dsh-life-pack 0.3.40 → 0.3.41
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/dist/client.js +329 -995
- package/dist/client.js.map +1 -1
- package/dist/seal-scroll.d.ts +3 -1
- package/dist/seal-scroll.d.ts.map +1 -1
- package/dist/seal-scroll.js +9 -2
- package/dist/seal-scroll.js.map +1 -1
- package/dist/seal-stamp.d.ts.map +1 -1
- package/dist/seal-stamp.js +4 -2
- package/dist/seal-stamp.js.map +1 -1
- package/dist/update-dialog.d.ts +7 -6
- package/dist/update-dialog.d.ts.map +1 -1
- package/dist/update-dialog.js +12 -26
- package/dist/update-dialog.js.map +1 -1
- package/package.json +2 -2
package/dist/client.js
CHANGED
|
@@ -153,27 +153,78 @@ window.__ModuleLoader__.load({
|
|
|
153
153
|
path: "/api/ilife-manager"
|
|
154
154
|
};
|
|
155
155
|
//#endregion
|
|
156
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-update@0.5.
|
|
157
|
-
const DEFAULT_PANEL_POLL_MS = 1e3;
|
|
156
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-update@0.5.4/node_modules/dsh-plugin-update/dist/config.js
|
|
158
157
|
function assertPrefix(value, role) {
|
|
159
158
|
if (typeof value !== "string" || value.length === 0) throw new Error("[dsh-plugin-update] " + role + " 非法:须为非空字符串(收到 " + JSON.stringify(value) + ")");
|
|
160
159
|
if (value.includes(".") || value.includes("/") || value.includes("\\") || /\s/.test(value)) throw new Error("[dsh-plugin-update] " + role + " 非法:不得含有点、路径分隔符或空白(收到 " + JSON.stringify(value) + ")");
|
|
161
160
|
return value;
|
|
162
161
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
162
|
+
//#endregion
|
|
163
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-update@0.5.4/node_modules/dsh-plugin-update/dist/redaction.js
|
|
164
|
+
const COPY_BUDGET_CHARS = 1500;
|
|
165
|
+
const REDACTED_PATH = "<路径>";
|
|
166
|
+
const REDACTED_SECRET = "<脱敏>";
|
|
167
|
+
const ABSOLUTE_PATH_RE = /[A-Za-z]:\\[^\s"']*|\\\\[^\s"'()\[\];]+|(^|[\s"'(\[=,])\/\/[^\s"'()\[\];]+|(^|[\s"'(\[=:,])\/(?!\/)[^\s"'()\[\];]+/g;
|
|
168
|
+
const URL_USERINFO_RE = /[A-Za-z][A-Za-z0-9+.-]*:\/\/[^\s/]*@/;
|
|
169
|
+
const NPM_TOKEN_RE = /\bnpm_[A-Za-z0-9_-]{8,}/g;
|
|
170
|
+
const GITHUB_TOKEN_RE = /\b(?:gh[pousr]_[A-Za-z0-9]{8,}|github_pat_[A-Za-z0-9_]{10,})/g;
|
|
171
|
+
const SK_TOKEN_RE = /\bsk-[A-Za-z0-9_-]{6,}/g;
|
|
172
|
+
const BEARER_TOKEN_RE = /(\bbearer\s+)[A-Za-z0-9._~+/-=]{6,}/gi;
|
|
173
|
+
const CRED_PAIR_RE = /(\b(?:token|password|passwd|pwd|api[_-]?key|access[_-]?key|auth[_-]?token|secret|cookie)\s*[:=]\s*)("[^"]+"|'[^']+'|[^\s'";,)\]]+)/gi;
|
|
174
|
+
const EMAIL_RE = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g;
|
|
175
|
+
function flattenWhitespace(text) {
|
|
176
|
+
return String(text ?? "").replace(/\s+/g, " ").trim();
|
|
177
|
+
}
|
|
178
|
+
function applyPathRule(text) {
|
|
179
|
+
ABSOLUTE_PATH_RE.lastIndex = 0;
|
|
180
|
+
return text.replace(ABSOLUTE_PATH_RE, (_whole, g1, g2) => {
|
|
181
|
+
return `${g1 ?? g2 ?? ""}${REDACTED_PATH}`;
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
function applyTokenRule(text) {
|
|
185
|
+
NPM_TOKEN_RE.lastIndex = 0;
|
|
186
|
+
GITHUB_TOKEN_RE.lastIndex = 0;
|
|
187
|
+
SK_TOKEN_RE.lastIndex = 0;
|
|
188
|
+
BEARER_TOKEN_RE.lastIndex = 0;
|
|
189
|
+
return text.replace(NPM_TOKEN_RE, REDACTED_SECRET).replace(GITHUB_TOKEN_RE, REDACTED_SECRET).replace(SK_TOKEN_RE, REDACTED_SECRET).replace(BEARER_TOKEN_RE, (_whole, prefix) => `${prefix}${REDACTED_SECRET}`);
|
|
190
|
+
}
|
|
191
|
+
function applyCredPairRule(text) {
|
|
192
|
+
CRED_PAIR_RE.lastIndex = 0;
|
|
193
|
+
return text.replace(CRED_PAIR_RE, (_whole, head) => `${head}${REDACTED_SECRET}`);
|
|
194
|
+
}
|
|
195
|
+
function applyEmailRule(text) {
|
|
196
|
+
EMAIL_RE.lastIndex = 0;
|
|
197
|
+
return text.replace(EMAIL_RE, REDACTED_SECRET);
|
|
198
|
+
}
|
|
199
|
+
function hasUserinfo(text) {
|
|
200
|
+
URL_USERINFO_RE.lastIndex = 0;
|
|
201
|
+
return URL_USERINFO_RE.test(text);
|
|
171
202
|
}
|
|
172
|
-
function
|
|
173
|
-
|
|
203
|
+
function truncateToWordBoundary(text, max) {
|
|
204
|
+
const input = String(text ?? "");
|
|
205
|
+
if (input.length <= max) return input;
|
|
206
|
+
const slice = input.slice(0, max);
|
|
207
|
+
const lastSpace = slice.lastIndexOf(" ");
|
|
208
|
+
let cut = lastSpace > 0 ? slice.slice(0, lastSpace) : slice;
|
|
209
|
+
const lastOpen = cut.lastIndexOf("<");
|
|
210
|
+
if (lastOpen > cut.lastIndexOf(">")) cut = cut.slice(0, lastOpen).trimEnd();
|
|
211
|
+
if (!cut) cut = slice;
|
|
212
|
+
return `${cut}\u2026`;
|
|
213
|
+
}
|
|
214
|
+
function truncateForCopy(text) {
|
|
215
|
+
return truncateToWordBoundary(text, COPY_BUDGET_CHARS);
|
|
216
|
+
}
|
|
217
|
+
function scrubWithoutBudget(text) {
|
|
218
|
+
return applyEmailRule(applyCredPairRule(applyTokenRule(applyPathRule(text))));
|
|
219
|
+
}
|
|
220
|
+
function sanitizeForCopy(text) {
|
|
221
|
+
const flat = flattenWhitespace(String(text ?? ""));
|
|
222
|
+
if (!flat) return "";
|
|
223
|
+
if (hasUserinfo(flat)) return "";
|
|
224
|
+
return truncateForCopy(scrubWithoutBudget(flat));
|
|
174
225
|
}
|
|
175
226
|
//#endregion
|
|
176
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-update@0.5.
|
|
227
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-update@0.5.4/node_modules/dsh-plugin-update/dist/service.js
|
|
177
228
|
function updateError(code) {
|
|
178
229
|
return Object.assign(new Error(code), { code });
|
|
179
230
|
}
|
|
@@ -260,7 +311,7 @@ window.__ModuleLoader__.load({
|
|
|
260
311
|
return 0;
|
|
261
312
|
}
|
|
262
313
|
//#endregion
|
|
263
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-update@0.5.
|
|
314
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-update@0.5.4/node_modules/dsh-plugin-update/dist/changelog.js
|
|
264
315
|
const CHANGELOG_NEUTRAL_LINE = "作者未提供更新说明,安装不受影响。";
|
|
265
316
|
const CHANGELOG_MAX_CHARS = 65536;
|
|
266
317
|
const CHANGELOG_ALL_CATEGORIES = [
|
|
@@ -708,151 +759,8 @@ ${blocks.join("\n")}
|
|
|
708
759
|
return renderChangelogNeutral();
|
|
709
760
|
}
|
|
710
761
|
}
|
|
711
|
-
function isTerminalPhase(phase) {
|
|
712
|
-
return phase === "done" || phase === "failed" || phase === "skipped" || phase === "current";
|
|
713
|
-
}
|
|
714
|
-
function asMillis(value, fallback) {
|
|
715
|
-
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : fallback;
|
|
716
|
-
}
|
|
717
|
-
function isNonEmptyString(value) {
|
|
718
|
-
return typeof value === "string" && value.length > 0;
|
|
719
|
-
}
|
|
720
|
-
const PHASES = [
|
|
721
|
-
"pending",
|
|
722
|
-
"checking",
|
|
723
|
-
"ready",
|
|
724
|
-
"installing",
|
|
725
|
-
"current",
|
|
726
|
-
"done",
|
|
727
|
-
"failed",
|
|
728
|
-
"skipped"
|
|
729
|
-
];
|
|
730
|
-
function asPhase(value) {
|
|
731
|
-
return typeof value === "string" && PHASES.includes(value) ? value : "pending";
|
|
732
|
-
}
|
|
733
|
-
function batchRequestId(sessionId, key) {
|
|
734
|
-
return "batch:" + sessionId + ":" + key;
|
|
735
|
-
}
|
|
736
|
-
function emptyBatchSession() {
|
|
737
|
-
return {
|
|
738
|
-
version: 1,
|
|
739
|
-
id: "",
|
|
740
|
-
selfKey: null,
|
|
741
|
-
stopOnFailure: false,
|
|
742
|
-
order: [],
|
|
743
|
-
entries: [],
|
|
744
|
-
createdAt: 0,
|
|
745
|
-
updatedAt: 0
|
|
746
|
-
};
|
|
747
|
-
}
|
|
748
|
-
function normalizeBatchSession(raw) {
|
|
749
|
-
try {
|
|
750
|
-
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return emptyBatchSession();
|
|
751
|
-
const input = raw;
|
|
752
|
-
if (input["version"] !== 1) return emptyBatchSession();
|
|
753
|
-
const id = isNonEmptyString(input["id"]) ? input["id"] : "";
|
|
754
|
-
const selfKey = isNonEmptyString(input["selfKey"]) ? input["selfKey"] : null;
|
|
755
|
-
const entries = [];
|
|
756
|
-
const seen = /* @__PURE__ */ new Set();
|
|
757
|
-
const rawEntries = input["entries"];
|
|
758
|
-
if (Array.isArray(rawEntries)) for (const item of rawEntries) {
|
|
759
|
-
if (!item || typeof item !== "object" || Array.isArray(item)) continue;
|
|
760
|
-
const e = item;
|
|
761
|
-
const key = e["key"];
|
|
762
|
-
if (!isNonEmptyString(key) || seen.has(key)) continue;
|
|
763
|
-
seen.add(key);
|
|
764
|
-
const requestId = isNonEmptyString(e["requestId"]) ? e["requestId"] : batchRequestId(id, key);
|
|
765
|
-
entries.push({
|
|
766
|
-
key,
|
|
767
|
-
phase: asPhase(e["phase"]),
|
|
768
|
-
requestId,
|
|
769
|
-
targetVersion: isNonEmptyString(e["targetVersion"]) ? e["targetVersion"] : null,
|
|
770
|
-
restartRequired: e["restartRequired"] === true,
|
|
771
|
-
error: isNonEmptyString(e["error"]) ? e["error"] : null,
|
|
772
|
-
updatedAt: asMillis(e["updatedAt"], 0)
|
|
773
|
-
});
|
|
774
|
-
}
|
|
775
|
-
const order = entries.map((e) => e.key);
|
|
776
|
-
return {
|
|
777
|
-
version: 1,
|
|
778
|
-
id,
|
|
779
|
-
selfKey: selfKey && seen.has(selfKey) ? selfKey : null,
|
|
780
|
-
stopOnFailure: input["stopOnFailure"] === true,
|
|
781
|
-
order,
|
|
782
|
-
entries,
|
|
783
|
-
createdAt: asMillis(input["createdAt"], 0),
|
|
784
|
-
updatedAt: asMillis(input["updatedAt"], 0)
|
|
785
|
-
};
|
|
786
|
-
} catch {
|
|
787
|
-
return emptyBatchSession();
|
|
788
|
-
}
|
|
789
|
-
}
|
|
790
762
|
//#endregion
|
|
791
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-update@0.5.
|
|
792
|
-
const COPY_BUDGET_CHARS = 1500;
|
|
793
|
-
const REDACTED_PATH = "<路径>";
|
|
794
|
-
const REDACTED_SECRET = "<脱敏>";
|
|
795
|
-
const ABSOLUTE_PATH_RE = /[A-Za-z]:\\[^\s"']*|\\\\[^\s"'()\[\];]+|(^|[\s"'(\[=,])\/\/[^\s"'()\[\];]+|(^|[\s"'(\[=:,])\/(?!\/)[^\s"'()\[\];]+/g;
|
|
796
|
-
const URL_USERINFO_RE = /[A-Za-z][A-Za-z0-9+.-]*:\/\/[^\s/]*@/;
|
|
797
|
-
const NPM_TOKEN_RE = /\bnpm_[A-Za-z0-9_-]{8,}/g;
|
|
798
|
-
const GITHUB_TOKEN_RE = /\b(?:gh[pousr]_[A-Za-z0-9]{8,}|github_pat_[A-Za-z0-9_]{10,})/g;
|
|
799
|
-
const SK_TOKEN_RE = /\bsk-[A-Za-z0-9_-]{6,}/g;
|
|
800
|
-
const BEARER_TOKEN_RE = /(\bbearer\s+)[A-Za-z0-9._~+/-=]{6,}/gi;
|
|
801
|
-
const CRED_PAIR_RE = /(\b(?:token|password|passwd|pwd|api[_-]?key|access[_-]?key|auth[_-]?token|secret|cookie)\s*[:=]\s*)("[^"]+"|'[^']+'|[^\s'";,)\]]+)/gi;
|
|
802
|
-
const EMAIL_RE = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g;
|
|
803
|
-
function flattenWhitespace(text) {
|
|
804
|
-
return String(text ?? "").replace(/\s+/g, " ").trim();
|
|
805
|
-
}
|
|
806
|
-
function applyPathRule(text) {
|
|
807
|
-
ABSOLUTE_PATH_RE.lastIndex = 0;
|
|
808
|
-
return text.replace(ABSOLUTE_PATH_RE, (_whole, g1, g2) => {
|
|
809
|
-
return `${g1 ?? g2 ?? ""}${REDACTED_PATH}`;
|
|
810
|
-
});
|
|
811
|
-
}
|
|
812
|
-
function applyTokenRule(text) {
|
|
813
|
-
NPM_TOKEN_RE.lastIndex = 0;
|
|
814
|
-
GITHUB_TOKEN_RE.lastIndex = 0;
|
|
815
|
-
SK_TOKEN_RE.lastIndex = 0;
|
|
816
|
-
BEARER_TOKEN_RE.lastIndex = 0;
|
|
817
|
-
return text.replace(NPM_TOKEN_RE, REDACTED_SECRET).replace(GITHUB_TOKEN_RE, REDACTED_SECRET).replace(SK_TOKEN_RE, REDACTED_SECRET).replace(BEARER_TOKEN_RE, (_whole, prefix) => `${prefix}${REDACTED_SECRET}`);
|
|
818
|
-
}
|
|
819
|
-
function applyCredPairRule(text) {
|
|
820
|
-
CRED_PAIR_RE.lastIndex = 0;
|
|
821
|
-
return text.replace(CRED_PAIR_RE, (_whole, head) => `${head}${REDACTED_SECRET}`);
|
|
822
|
-
}
|
|
823
|
-
function applyEmailRule(text) {
|
|
824
|
-
EMAIL_RE.lastIndex = 0;
|
|
825
|
-
return text.replace(EMAIL_RE, REDACTED_SECRET);
|
|
826
|
-
}
|
|
827
|
-
function hasUserinfo(text) {
|
|
828
|
-
URL_USERINFO_RE.lastIndex = 0;
|
|
829
|
-
return URL_USERINFO_RE.test(text);
|
|
830
|
-
}
|
|
831
|
-
function truncateToWordBoundary(text, max) {
|
|
832
|
-
const input = String(text ?? "");
|
|
833
|
-
if (input.length <= max) return input;
|
|
834
|
-
const slice = input.slice(0, max);
|
|
835
|
-
const lastSpace = slice.lastIndexOf(" ");
|
|
836
|
-
let cut = lastSpace > 0 ? slice.slice(0, lastSpace) : slice;
|
|
837
|
-
const lastOpen = cut.lastIndexOf("<");
|
|
838
|
-
if (lastOpen > cut.lastIndexOf(">")) cut = cut.slice(0, lastOpen).trimEnd();
|
|
839
|
-
if (!cut) cut = slice;
|
|
840
|
-
return `${cut}\u2026`;
|
|
841
|
-
}
|
|
842
|
-
function truncateForCopy(text) {
|
|
843
|
-
return truncateToWordBoundary(text, COPY_BUDGET_CHARS);
|
|
844
|
-
}
|
|
845
|
-
function scrubWithoutBudget(text) {
|
|
846
|
-
return applyEmailRule(applyCredPairRule(applyTokenRule(applyPathRule(text))));
|
|
847
|
-
}
|
|
848
|
-
function sanitizeForCopy(text) {
|
|
849
|
-
const flat = flattenWhitespace(String(text ?? ""));
|
|
850
|
-
if (!flat) return "";
|
|
851
|
-
if (hasUserinfo(flat)) return "";
|
|
852
|
-
return truncateForCopy(scrubWithoutBudget(flat));
|
|
853
|
-
}
|
|
854
|
-
//#endregion
|
|
855
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-update@0.5.1/node_modules/dsh-plugin-update/dist/panel.js
|
|
763
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-update@0.5.4/node_modules/dsh-plugin-update/dist/panel.js
|
|
856
764
|
function normalizePanelTheme(value) {
|
|
857
765
|
return value === "d5-paper" || value === "archive" ? "d5-paper" : "default";
|
|
858
766
|
}
|
|
@@ -974,109 +882,6 @@ ${blocks.join("\n")}
|
|
|
974
882
|
if (manual) lines.push(`\u624B\u5DE5\u547D\u4EE4\uFF1A${manual}`);
|
|
975
883
|
return redactForCopy(lines.join("\n"));
|
|
976
884
|
}
|
|
977
|
-
const DIAG_KNOWN_TYPES = {
|
|
978
|
-
v: "number",
|
|
979
|
-
stage: "string",
|
|
980
|
-
route: "string",
|
|
981
|
-
method: "string",
|
|
982
|
-
httpStatus: "number",
|
|
983
|
-
exitCode: "number",
|
|
984
|
-
latencyMs: "number",
|
|
985
|
-
detail: "string",
|
|
986
|
-
targetPackageName: "string",
|
|
987
|
-
runningVersion: "string",
|
|
988
|
-
latestVersion: "string",
|
|
989
|
-
environmentKind: "string",
|
|
990
|
-
requestId: "string",
|
|
991
|
-
checkId: "string",
|
|
992
|
-
registryHost: "string",
|
|
993
|
-
action: "string"
|
|
994
|
-
};
|
|
995
|
-
function readDiagTolerant(diag) {
|
|
996
|
-
const empty = {
|
|
997
|
-
stage: null,
|
|
998
|
-
route: null,
|
|
999
|
-
method: null,
|
|
1000
|
-
httpStatus: null,
|
|
1001
|
-
exitCode: null,
|
|
1002
|
-
latencyMs: null,
|
|
1003
|
-
detail: null,
|
|
1004
|
-
targetPackageName: null,
|
|
1005
|
-
runningVersion: null,
|
|
1006
|
-
latestVersion: null,
|
|
1007
|
-
environmentKind: null,
|
|
1008
|
-
requestId: null,
|
|
1009
|
-
checkId: null,
|
|
1010
|
-
registryHost: null,
|
|
1011
|
-
action: null,
|
|
1012
|
-
unknownKeys: []
|
|
1013
|
-
};
|
|
1014
|
-
if (!diag || typeof diag !== "object" || Array.isArray(diag)) return empty;
|
|
1015
|
-
const raw = diag;
|
|
1016
|
-
const out = {
|
|
1017
|
-
...empty,
|
|
1018
|
-
unknownKeys: []
|
|
1019
|
-
};
|
|
1020
|
-
for (const key of Object.keys(DIAG_KNOWN_TYPES)) {
|
|
1021
|
-
if (!Object.prototype.hasOwnProperty.call(raw, key)) continue;
|
|
1022
|
-
const v = raw[key];
|
|
1023
|
-
if (v === void 0 || v === null) continue;
|
|
1024
|
-
if (typeof v !== DIAG_KNOWN_TYPES[key]) continue;
|
|
1025
|
-
out[key] = v;
|
|
1026
|
-
}
|
|
1027
|
-
for (const key of Object.keys(raw)) if (!Object.prototype.hasOwnProperty.call(DIAG_KNOWN_TYPES, key)) out.unknownKeys.push(key);
|
|
1028
|
-
return out;
|
|
1029
|
-
}
|
|
1030
|
-
function pickText(value, fallback) {
|
|
1031
|
-
if (typeof value === "string" && value.trim()) return value.trim();
|
|
1032
|
-
return fallback;
|
|
1033
|
-
}
|
|
1034
|
-
function queueTextOf(queuePosition, _diagQueuePos) {
|
|
1035
|
-
const pos = typeof queuePosition === "number" ? queuePosition : null;
|
|
1036
|
-
if (pos === 0) return "正在安装";
|
|
1037
|
-
if (typeof pos === "number") return `\u6392\u961F\u7B2C ${pos} \u4F4D`;
|
|
1038
|
-
return "不在队列里";
|
|
1039
|
-
}
|
|
1040
|
-
function buildUpdateDiagCopy(input) {
|
|
1041
|
-
const rawCode = String(input.code ?? "").trim() || "internal";
|
|
1042
|
-
const copy = failureCopy(rawCode) ?? UNKNOWN_FAILURE_COPY;
|
|
1043
|
-
const diag = readDiagTolerant(input.diag);
|
|
1044
|
-
const detail = redactForCopy(diag.detail ?? input.detail ?? "") || "(本回包没有带诊断摘要,等电话侧 diag 落定后补齐)";
|
|
1045
|
-
const pluginName = pickText(diag.targetPackageName ?? input.pluginId, "(未知包)");
|
|
1046
|
-
const runVer = pickText(diag.runningVersion ?? input.runningVersion, "?");
|
|
1047
|
-
const instVer = pickText(input.installedVersion ?? diag.latestVersion, "?");
|
|
1048
|
-
const host = pickText(diag.environmentKind ?? input.hostKind, "未知");
|
|
1049
|
-
const routeRaw = diag.route ?? input.route;
|
|
1050
|
-
const requestRaw = diag.requestId ?? input.requestId;
|
|
1051
|
-
const checkRaw = diag.checkId ?? input.checkId;
|
|
1052
|
-
const queue = queueTextOf(input.queuePosition ?? null);
|
|
1053
|
-
const prov = [
|
|
1054
|
-
`\u63D2\u4EF6=${pluginName}`,
|
|
1055
|
-
`\u7248\u672C=${runVer}\u2192${instVer}`,
|
|
1056
|
-
`\u5BBF\u4E3B=${host}`
|
|
1057
|
-
];
|
|
1058
|
-
if (typeof routeRaw === "string" && routeRaw.trim()) prov.push(`\u8DEF\u7531=${routeRaw.trim()}`);
|
|
1059
|
-
if (diag.stage) prov.push(`\u9636\u6BB5=${diag.stage}`);
|
|
1060
|
-
if (diag.method) prov.push(`\u65B9\u6CD5=${diag.method}`);
|
|
1061
|
-
if (typeof diag.httpStatus === "number") prov.push(`HTTP=${diag.httpStatus}`);
|
|
1062
|
-
if (typeof diag.exitCode === "number") prov.push(`exit=${diag.exitCode}`);
|
|
1063
|
-
if (typeof diag.latencyMs === "number") prov.push(`\u8017\u65F6=${diag.latencyMs}ms`);
|
|
1064
|
-
if (diag.registryHost) prov.push(`\u6E90=${diag.registryHost}`);
|
|
1065
|
-
else prov.push("源=未知(非官方源时省略本身即信息)");
|
|
1066
|
-
if (diag.action) prov.push(`\u5EFA\u8BAE=${diag.action}`);
|
|
1067
|
-
if (typeof requestRaw === "string" && requestRaw.trim()) prov.push(`\u8BF7\u6C42=${requestRaw.trim()}`);
|
|
1068
|
-
if (typeof checkRaw === "string" && checkRaw.trim()) prov.push(`\u68C0\u67E5=${checkRaw.trim()}`);
|
|
1069
|
-
prov.push(`\u961F\u5217=${queue}`);
|
|
1070
|
-
const format = input.format === "line" ? "line" : "block";
|
|
1071
|
-
const provLine = redactForCopy(prov.join(" · "));
|
|
1072
|
-
if (format === "line") return redactForCopy(`[update-diag] code=${rawCode} \xB7 ${copy.zh} \xB7 \u6458\u8981=${detail} \xB7 ${provLine} \xB7 \u600E\u4E48\u529E=${copy.act}`);
|
|
1073
|
-
return [
|
|
1074
|
-
`[update-diag] ${rawCode} \u2014 ${copy.zh}`,
|
|
1075
|
-
` \u6458\u8981\uFF1A${detail}`,
|
|
1076
|
-
` \u6765\u6E90\uFF1A${provLine}`,
|
|
1077
|
-
` \u600E\u4E48\u529E\uFF1A${copy.act}`
|
|
1078
|
-
].join("\n");
|
|
1079
|
-
}
|
|
1080
885
|
const PANEL_SKIPPED_MAX = 50;
|
|
1081
886
|
function panelSkipKey(pluginId) {
|
|
1082
887
|
return `dsh-upd-skipped/${String(pluginId)}`;
|
|
@@ -1417,6 +1222,9 @@ ${blocks.join("\n")}
|
|
|
1417
1222
|
".dsh-upd-strip-k{display:block;font-size:11px;letter-spacing:.14em;opacity:.7}",
|
|
1418
1223
|
".dsh-upd-strip-v{font-family:Consolas,Menlo,monospace;font-size:12.5px}",
|
|
1419
1224
|
".dsh-upd-chapter{margin-top:14px;padding-top:10px;border-top:1px solid var(--dsh-upd-line,#e5e7eb)}",
|
|
1225
|
+
".dsh-upd-footer{display:flex;align-items:center;justify-content:flex-end;gap:10px;margin-top:14px;padding-top:10px;border-top:1px solid var(--dsh-upd-line,#e5e7eb)}",
|
|
1226
|
+
".dsh-upd-foot-note{margin-right:auto;font-size:12px;opacity:.7}",
|
|
1227
|
+
".dsh-upd-footer button{margin:0}",
|
|
1420
1228
|
".dsh-upd-chap-head{display:flex;align-items:baseline;gap:10px;margin-bottom:6px}",
|
|
1421
1229
|
".dsh-upd-chap-no{font-size:13px;font-style:italic;opacity:.6}",
|
|
1422
1230
|
".dsh-upd-chap-title{font-size:14px;margin:0}",
|
|
@@ -1523,6 +1331,8 @@ ${blocks.join("\n")}
|
|
|
1523
1331
|
"background:url(\"data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%2720%27 height=%2720%27 viewBox=%270 0 24 24%27 fill=%27none%27 stroke=%27%238a5a00%27 stroke-width=%272%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27%3E%3Cpath d=%27M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z%27/%3E%3Cline x1=%2712%27 y1=%279%27 x2=%2712%27 y2=%2713%27/%3E%3Cline x1=%2712%27 y1=%2717%27 x2=%2712.01%27 y2=%2717%27/%3E%3C/svg%3E\") no-repeat center/20px 20px}",
|
|
1524
1332
|
".dsh-upd[data-theme=\"d5-paper\"] .dsh-upd-banner>div:first-child{overflow:hidden;text-overflow:ellipsis}",
|
|
1525
1333
|
".dsh-upd[data-theme=\"d5-paper\"] .dsh-upd-actions{flex-wrap:wrap}",
|
|
1334
|
+
".dsh-upd[data-theme=\"d5-paper\"] .dsh-upd-footer{margin-top:26px;padding-top:16px;border-top:1px solid var(--d5-line)}",
|
|
1335
|
+
".dsh-upd[data-theme=\"d5-paper\"] .dsh-upd-foot-note{color:var(--d5-muted)}",
|
|
1526
1336
|
".dsh-upd[data-theme=\"d5-paper\"] .dsh-upd-head{display:flex;gap:16px;align-items:baseline;flex-wrap:wrap;padding-right:120px}",
|
|
1527
1337
|
".dsh-upd[data-theme=\"d5-paper\"] .dsh-upd-name{font-family:var(--d5-serif);font-size:22px;font-weight:700}",
|
|
1528
1338
|
".dsh-upd[data-theme=\"d5-paper\"] .dsh-upd-meta{width:100%;font-size:12.5px;color:var(--d5-muted)}",
|
|
@@ -1617,7 +1427,6 @@ ${blocks.join("\n")}
|
|
|
1617
1427
|
if (view.showManual && manual) actions.push(`<button type="button" data-action="copy-manual" title="\u590D\u5236\u624B\u5DE5\u547D\u4EE4\uFF0C\u7C98\u5230\u7EC8\u7AEF\u6574\u884C\u6267\u884C">\u590D\u5236\u624B\u5DE5\u547D\u4EE4</button>`);
|
|
1618
1428
|
if (b.kind === "restart") actions.push(`<button type="button" data-action="restart-hint" data-primary="1" title="\u5BBF\u4E3B\u6CA1\u6709\u81EA\u91CD\u542F\u7535\u8BDD\uFF1A\u8BF7\u624B\u52A8\u91CD\u542F\u5BBF\u4E3B">\u91CD\u542F\u5BBF\u4E3B</button>`);
|
|
1619
1429
|
if (snapshot) actions.push(`<button type="button" data-action="copy-diag" title="\u590D\u5236\u5DF2\u8131\u654F\u8BCA\u65AD\uFF0C\u76F4\u63A5\u7C98\u7ED9\u63D2\u4EF6\u4F5C\u8005">\u590D\u5236\u8BCA\u65AD</button>`);
|
|
1620
|
-
if (mode === "dialog") actions.push(`<button type="button" data-action="close-view" title="\u5173\u95ED\u9762\u677F\uFF08\u5B89\u88C5\u5728\u5BBF\u4E3B\u4FA7\u7EE7\u7EED\u8DD1\uFF0C\u53EF\u91CD\u5F00\u6062\u590D\u663E\u793A\uFF09">\u5173\u95ED</button>`);
|
|
1621
1430
|
actions.push("</div>");
|
|
1622
1431
|
}
|
|
1623
1432
|
actions.push(progressBar(snapshot));
|
|
@@ -1674,495 +1483,144 @@ ${changelogHTML}
|
|
|
1674
1483
|
parts.push(chapterOf(3, `<div class="dsh-upd-queue">${rows.join("")}</div>`, note));
|
|
1675
1484
|
} else parts.push(chapterOf(3, `<div class="dsh-upd-queue"><div class="dsh-upd-changelog-neutral">${escapeHtml$2(view.queueNote ?? "当前没有排队任务,同一使用范围一次只装一个。")}</div></div>`));
|
|
1676
1485
|
{
|
|
1677
|
-
const errLines = [];
|
|
1678
|
-
if (b.kind === "failed" || b.kind === "blocked") errLines.push(`<div class="dsh-upd-err">\u7A33\u5B9A\u7801 <code>${escapeHtml$2(String(b.kind === "blocked" ? snapshot?.blockedReason ?? b.kind : "install-failed"))}</code>\uFF1A\u4E0A\u4E00\u6761\u4E2D\u6587\u8BF4\u660E\u5C31\u662F\u8981\u7528\u6237\u505A\u7684\u4E8B\uFF1B\u8981\u5F80\u4E0A\u6E38\u62A5\uFF0C\u7528\u300C\u590D\u5236\u8BCA\u65AD\u300D\u6574\u6BB5\u7C98\uFF08\u5DF2\u8131\u654F\uFF09\u3002</div>`);
|
|
1679
|
-
errLines.push(`<div class="dsh-upd-log">\u6DF1\u6316\u770B\u65E5\u5FD7\uFF1A\u6309\u63D2\u4EF6\u6807\u8BC6 <code>${escapeHtml$2(pluginId)}</code> \u8FC7\u6EE4 <code>host.call</code>\u3001<code>host.call.fail</code>\u3001<code>update.install.exec</code> \u4E09\u4E2A\u4E8B\u4EF6\u3002</div>`);
|
|
1680
|
-
if (copyNotice) errLines.push(`<div class="dsh-upd-copy" role="status">${escapeHtml$2(copyNotice)}</div>`);
|
|
1681
|
-
parts.push(chapterOf(4, errLines.join("")));
|
|
1682
|
-
}
|
|
1683
|
-
parts.push(chapterOf(5, view.showManual && manual ? `<div class="dsh-upd-manual"><div>\u624B\u5DE5\u515C\u5E95\u547D\u4EE4\uFF08\u590D\u5236\u6574\u884C\u6267\u884C\uFF09\uFF1A</div><code>${escapeHtml$2(manual)}</code></div>` : `<div class="dsh-upd-manual"><div class="dsh-upd-changelog-neutral">\u5F53\u524D\u6CA1\u6709\u53EF\u7528\u7684\u624B\u5DE5\u547D\u4EE4\uFF08\u8BA4\u4E0D\u51FA\u4F7F\u7528\u8303\u56F4\u6216\u5C5E\u6E90\u7801\u5B89\u88C5\u65F6\u4E0D\u7ED9\uFF09\u3002</div></div>`));
|
|
1684
|
-
return parts.join("\n");
|
|
1685
|
-
}
|
|
1686
|
-
function renderUpdatePanelHTML(input) {
|
|
1687
|
-
const view = panelViewModel(input);
|
|
1688
|
-
const kernel = renderUpdatePanelKernel(input, view);
|
|
1689
|
-
const d5 = normalizePanelTheme(input.theme) === "d5-paper";
|
|
1690
|
-
const attr = d5 ? " data-theme=\"d5-paper\"" : "";
|
|
1691
|
-
const sealAttr = ` data-seal="${escapeHtml$2(view.seal.text)}" data-seal-tone="${view.seal.tone}"`;
|
|
1692
|
-
const body = input.mode === "dialog" ? `<div class="dsh-upd-overlay" data-mode="dialog"><div class="dsh-upd" data-mode="dialog" data-plugin="${escapeHtml$2(input.pluginId)}"${sealAttr}${attr}>
|
|
1693
|
-
${kernel}
|
|
1694
|
-
</div></div>` : `<div class="dsh-upd" data-mode="embedded" data-plugin="${escapeHtml$2(input.pluginId)}"${sealAttr}${attr}>
|
|
1695
|
-
${kernel}
|
|
1696
|
-
</div>`;
|
|
1697
|
-
return `<style>${d5 ? `${UPDATE_PANEL_CSS}
|
|
1698
|
-
${UPDATE_PANEL_D5_CSS}` : UPDATE_PANEL_CSS}</style>
|
|
1699
|
-
${body}`;
|
|
1700
|
-
}
|
|
1701
|
-
function isObject$2(value) {
|
|
1702
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
1703
|
-
}
|
|
1704
|
-
function asSnapshot$1(value) {
|
|
1705
|
-
if (!isObject$2(value)) return null;
|
|
1706
|
-
const s = value;
|
|
1707
|
-
if (typeof s["runningVersion"] !== "string") return null;
|
|
1708
|
-
if (typeof s["canInstall"] !== "boolean") return null;
|
|
1709
|
-
return value;
|
|
1710
|
-
}
|
|
1711
|
-
function asQueue(value) {
|
|
1712
|
-
if (!isObject$2(value) || typeof value["busy"] !== "boolean") return null;
|
|
1713
|
-
return value;
|
|
1714
|
-
}
|
|
1715
|
-
function randomRequestId() {
|
|
1716
|
-
try {
|
|
1717
|
-
const rand = Math.floor(Math.random() * 16777215).toString(36);
|
|
1718
|
-
return `r${Date.now().toString(36)}${rand}`.slice(0, 64);
|
|
1719
|
-
} catch {
|
|
1720
|
-
return `r${Date.now()}`;
|
|
1721
|
-
}
|
|
1722
|
-
}
|
|
1723
|
-
function getTimer$1() {
|
|
1724
|
-
const g = globalThis;
|
|
1725
|
-
const set = g["setInterval"];
|
|
1726
|
-
const clear = g["clearInterval"];
|
|
1727
|
-
if (typeof set === "function" && typeof clear === "function") return {
|
|
1728
|
-
set: (fn, ms) => set(fn, ms),
|
|
1729
|
-
clear: (h) => clear(h)
|
|
1730
|
-
};
|
|
1731
|
-
const setT = g["setTimeout"];
|
|
1732
|
-
const clearT = g["clearTimeout"];
|
|
1733
|
-
return {
|
|
1734
|
-
set: (fn, ms) => setT(fn, ms),
|
|
1735
|
-
clear: (h) => clearT(h)
|
|
1736
|
-
};
|
|
1737
|
-
}
|
|
1738
|
-
async function defaultCopyText$1(text) {
|
|
1739
|
-
try {
|
|
1740
|
-
const clip = globalThis["navigator"]?.clipboard;
|
|
1741
|
-
const write = clip?.writeText;
|
|
1742
|
-
if (clip && typeof write === "function") {
|
|
1743
|
-
await write.call(clip, text);
|
|
1744
|
-
return;
|
|
1745
|
-
}
|
|
1746
|
-
} catch {}
|
|
1747
|
-
}
|
|
1748
|
-
function mountUpdatePanel(container, options) {
|
|
1749
|
-
if (!container || typeof container.innerHTML !== "string") throw new Error("[dsh-plugin-update] 挂载面板需要一个有 innerHTML 的容器");
|
|
1750
|
-
if (!options || typeof options !== "object") throw new Error("[dsh-plugin-update] 挂载面板缺少配置:插件标识 pluginId 必填");
|
|
1751
|
-
const pluginId = options.pluginId;
|
|
1752
|
-
if (typeof pluginId !== "string" || !pluginId) throw new Error(`[dsh-plugin-update] \u63D2\u4EF6\u6807\u8BC6 pluginId \u5FC5\u586B\uFF1A\u987B\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32\uFF08\u6536\u5230 ${JSON.stringify(pluginId)}\uFF09`);
|
|
1753
|
-
if (typeof options.call !== "function") throw new Error("[dsh-plugin-update] 挂载面板需要传输函数 call(面板调宿主电话的唯一接触面)");
|
|
1754
|
-
const prefix = options.prefix === void 0 ? "wf" : options.prefix;
|
|
1755
|
-
const phoneNames = buildPhoneNames(prefix);
|
|
1756
|
-
const changelogPhone = buildChangelogPhoneName(prefix);
|
|
1757
|
-
const autoChangelogEnabled = typeof options.changelogMarkdown !== "string" && options.autoChangelog !== false;
|
|
1758
|
-
let manualChangelogOverride = typeof options.changelogMarkdown === "string";
|
|
1759
|
-
const changelogCache = /* @__PURE__ */ new Map();
|
|
1760
|
-
const changelogInflight = /* @__PURE__ */ new Set();
|
|
1761
|
-
const changelogFailedAt = /* @__PURE__ */ new Map();
|
|
1762
|
-
let autoSeq = 0;
|
|
1763
|
-
const pollMs = options.pollMs === void 0 ? DEFAULT_PANEL_POLL_MS : options.pollMs;
|
|
1764
|
-
if (typeof pollMs !== "number" || !Number.isFinite(pollMs) || pollMs < 250) throw new Error(`[dsh-plugin-update] \u9762\u677F\u8F6E\u8BE2\u95F4\u9694\u975E\u6CD5\uFF1A\u4E0D\u5F97\u5C0F\u4E8E 250 \u6BEB\u79D2\uFF08\u6536\u5230 ${JSON.stringify(options.pollMs)}\uFF09`);
|
|
1765
|
-
let mode = options.mode ?? "embedded";
|
|
1766
|
-
if (mode !== "embedded" && mode !== "dialog") throw new Error(`[dsh-plugin-update] \u6446\u653E\u5F62\u6001\u975E\u6CD5\uFF1A\u53EA\u6536 embedded \u6216 dialog\uFF08\u6536\u5230 ${JSON.stringify(options.mode)}\uFF09`);
|
|
1767
|
-
if (options.theme !== void 0 && options.theme !== "default" && options.theme !== "archive" && options.theme !== "d5-paper") throw new Error(`[dsh-plugin-update] \u4E3B\u9898\u975E\u6CD5\uFF1A\u53EA\u6536 default \u6216 archive\uFF08d5-paper \u4E3A\u65E7\u522B\u540D\u4ECD\u53EF\u7528\uFF09\uFF08\u6536\u5230 ${JSON.stringify(options.theme)}\uFF09`);
|
|
1768
|
-
let theme = normalizePanelTheme(options.theme ?? "default");
|
|
1769
|
-
let showOthers = options.showOthers === true;
|
|
1770
|
-
const call = options.call;
|
|
1771
|
-
const onRestartRequested = options.onRestartRequested;
|
|
1772
|
-
const onCloseRequested = typeof options.onCloseRequested === "function" ? options.onCloseRequested : null;
|
|
1773
|
-
let lastHTML = "";
|
|
1774
|
-
const copyText = options.copyText ?? defaultCopyText$1;
|
|
1775
|
-
const skipStore = options.skipStore ?? createBrowserSkipStore(pluginId);
|
|
1776
|
-
const hostKind = typeof options.hostKind === "string" && options.hostKind ? options.hostKind : null;
|
|
1777
|
-
const profileNameOption = typeof options.profileName === "string" && options.profileName ? options.profileName : null;
|
|
1778
|
-
const diagCopyFormat = options.diagCopyFormat === "line" ? "line" : "block";
|
|
1779
|
-
let changelogMarkdown = typeof options.changelogMarkdown === "string" ? options.changelogMarkdown : null;
|
|
1780
|
-
let snapshot = null;
|
|
1781
|
-
let manual = null;
|
|
1782
|
-
let queue = null;
|
|
1783
|
-
let receipt = null;
|
|
1784
|
-
let requestId = null;
|
|
1785
|
-
let lastError = null;
|
|
1786
|
-
let lastErrorKind = null;
|
|
1787
|
-
let lastDiag = null;
|
|
1788
|
-
let copyNotice = null;
|
|
1789
|
-
let noticeExpiresAt = 0;
|
|
1790
|
-
let busyAct = null;
|
|
1791
|
-
let mounted = true;
|
|
1792
|
-
let envProfileName = null;
|
|
1793
|
-
let envHostKind = null;
|
|
1794
|
-
function sayCopy(text) {
|
|
1795
|
-
copyNotice = text;
|
|
1796
|
-
try {
|
|
1797
|
-
noticeExpiresAt = Date.now() + 5e3;
|
|
1798
|
-
} catch {
|
|
1799
|
-
noticeExpiresAt = 0;
|
|
1800
|
-
}
|
|
1801
|
-
}
|
|
1802
|
-
function queueArgs() {
|
|
1803
|
-
return {
|
|
1804
|
-
includeQueue: true,
|
|
1805
|
-
includeEnv: true,
|
|
1806
|
-
showOthers,
|
|
1807
|
-
...requestId ? { requestId } : {}
|
|
1808
|
-
};
|
|
1809
|
-
}
|
|
1810
|
-
function render() {
|
|
1811
|
-
if (!mounted) return;
|
|
1812
|
-
if (!copyNotice) noticeExpiresAt = 0;
|
|
1813
|
-
else if (noticeExpiresAt && Date.now() > noticeExpiresAt) {
|
|
1814
|
-
copyNotice = null;
|
|
1815
|
-
noticeExpiresAt = 0;
|
|
1816
|
-
}
|
|
1817
|
-
const latest = snapshot?.latestVersion ?? null;
|
|
1818
|
-
const skippedLatest = !!latest && validReleaseVersion(latest) && skipStore.has(latest);
|
|
1819
|
-
const nextHTML = renderUpdatePanelHTML({
|
|
1820
|
-
snapshot,
|
|
1821
|
-
manual,
|
|
1822
|
-
queue,
|
|
1823
|
-
busyAct,
|
|
1824
|
-
skippedLatest,
|
|
1825
|
-
lastError,
|
|
1826
|
-
errorKind: lastErrorKind,
|
|
1827
|
-
changelogMarkdown,
|
|
1828
|
-
mode,
|
|
1829
|
-
showOthers,
|
|
1830
|
-
pluginId,
|
|
1831
|
-
copyNotice,
|
|
1832
|
-
theme,
|
|
1833
|
-
profileName: profileNameOption ?? envProfileName,
|
|
1834
|
-
hostKind: hostKind ?? envHostKind
|
|
1835
|
-
});
|
|
1836
|
-
if (nextHTML !== lastHTML) {
|
|
1837
|
-
lastHTML = nextHTML;
|
|
1838
|
-
container.innerHTML = nextHTML;
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
|
-
function applyStatusReply(reply) {
|
|
1842
|
-
if (!isObject$2(reply)) return;
|
|
1843
|
-
if (reply["ok"] === true) {
|
|
1844
|
-
const s = asSnapshot$1(reply["snapshot"]);
|
|
1845
|
-
if (s) snapshot = s;
|
|
1846
|
-
manual = typeof reply["manual"] === "string" ? reply["manual"] : null;
|
|
1847
|
-
if (reply["receipt"] && isObject$2(reply["receipt"]) && typeof reply["receipt"]["checkId"] === "string") receipt = { checkId: reply["receipt"]["checkId"] };
|
|
1848
|
-
const q = asQueue(reply["queue"]);
|
|
1849
|
-
if (q) queue = q;
|
|
1850
|
-
const env = reply["env"];
|
|
1851
|
-
if (isObject$2(env)) {
|
|
1852
|
-
const pn = env["profileName"];
|
|
1853
|
-
const hk = env["environmentKind"];
|
|
1854
|
-
if (typeof pn === "string" && pn) envProfileName = pn;
|
|
1855
|
-
if (typeof hk === "string" && hk) envHostKind = hk;
|
|
1856
|
-
}
|
|
1857
|
-
lastError = null;
|
|
1858
|
-
lastErrorKind = null;
|
|
1859
|
-
lastDiag = Object.prototype.hasOwnProperty.call(reply, "diag") ? reply["diag"] : null;
|
|
1860
|
-
} else {
|
|
1861
|
-
lastError = typeof reply["error"] === "string" ? reply["error"] : "check-failed";
|
|
1862
|
-
lastErrorKind = typeof reply["errorKind"] === "string" && reply["errorKind"].trim() ? reply["errorKind"].trim() : null;
|
|
1863
|
-
lastDiag = Object.prototype.hasOwnProperty.call(reply, "diag") ? reply["diag"] : null;
|
|
1864
|
-
}
|
|
1865
|
-
}
|
|
1866
|
-
function pendingAutoChangelogVersion() {
|
|
1867
|
-
if (!autoChangelogEnabled || manualChangelogOverride || !mounted) return null;
|
|
1868
|
-
const v = snapshot?.latestVersion ?? null;
|
|
1869
|
-
if (typeof v !== "string" || !validReleaseVersion(v)) return null;
|
|
1870
|
-
if (!snapshot || snapshot.canInstall !== true) return null;
|
|
1871
|
-
try {
|
|
1872
|
-
if (skipStore.has(v)) return null;
|
|
1873
|
-
} catch {}
|
|
1874
|
-
if (changelogInflight.has(v)) return null;
|
|
1875
|
-
const hasCache = changelogCache.has(v);
|
|
1876
|
-
const failedAt = changelogFailedAt.has(v) ? changelogFailedAt.get(v) : null;
|
|
1877
|
-
let nowMs = 0;
|
|
1878
|
-
try {
|
|
1879
|
-
nowMs = Date.now();
|
|
1880
|
-
} catch {
|
|
1881
|
-
nowMs = 0;
|
|
1882
|
-
}
|
|
1883
|
-
if (!shouldFetchChangelog({
|
|
1884
|
-
hasCache,
|
|
1885
|
-
failedAt,
|
|
1886
|
-
now: nowMs,
|
|
1887
|
-
isManual: false
|
|
1888
|
-
})) return null;
|
|
1889
|
-
return v;
|
|
1890
|
-
}
|
|
1891
|
-
function maybeAutoChangelog() {
|
|
1892
|
-
const v = pendingAutoChangelogVersion();
|
|
1893
|
-
if (v === null) return;
|
|
1894
|
-
changelogInflight.add(v);
|
|
1895
|
-
const seq = autoSeq;
|
|
1896
|
-
Promise.resolve().then(() => call(changelogPhone, { version: v })).then((reply) => {
|
|
1897
|
-
changelogInflight.delete(v);
|
|
1898
|
-
if (!mounted || seq !== autoSeq) return;
|
|
1899
|
-
if (!reply || typeof reply !== "object" || reply["ok"] !== true) {
|
|
1900
|
-
try {
|
|
1901
|
-
changelogFailedAt.set(v, Date.now());
|
|
1902
|
-
} catch {
|
|
1903
|
-
try {
|
|
1904
|
-
changelogFailedAt.set(v, 0);
|
|
1905
|
-
} catch {}
|
|
1906
|
-
}
|
|
1907
|
-
return;
|
|
1908
|
-
}
|
|
1909
|
-
const md = reply["markdown"];
|
|
1910
|
-
changelogCache.set(v, typeof md === "string" ? md : null);
|
|
1911
|
-
if (typeof md === "string") {
|
|
1912
|
-
changelogMarkdown = md;
|
|
1913
|
-
render();
|
|
1914
|
-
}
|
|
1915
|
-
}, () => {
|
|
1916
|
-
changelogInflight.delete(v);
|
|
1917
|
-
if (mounted && seq === autoSeq) try {
|
|
1918
|
-
changelogFailedAt.set(v, Date.now());
|
|
1919
|
-
} catch {
|
|
1920
|
-
try {
|
|
1921
|
-
changelogFailedAt.set(v, 0);
|
|
1922
|
-
} catch {}
|
|
1923
|
-
}
|
|
1924
|
-
});
|
|
1925
|
-
}
|
|
1926
|
-
async function refresh() {
|
|
1927
|
-
if (!mounted) return;
|
|
1928
|
-
try {
|
|
1929
|
-
const reply = await call(phoneNames.updateStatus, queueArgs());
|
|
1930
|
-
if (!mounted) return;
|
|
1931
|
-
applyStatusReply(reply);
|
|
1932
|
-
} catch {
|
|
1933
|
-
if (!mounted) return;
|
|
1934
|
-
lastError = "check-failed";
|
|
1935
|
-
lastErrorKind = null;
|
|
1936
|
-
lastDiag = null;
|
|
1937
|
-
}
|
|
1938
|
-
render();
|
|
1939
|
-
maybeAutoChangelog();
|
|
1940
|
-
}
|
|
1941
|
-
async function act(kind, arg) {
|
|
1942
|
-
if (!mounted) return;
|
|
1943
|
-
copyNotice = null;
|
|
1944
|
-
switch (kind) {
|
|
1945
|
-
case "check":
|
|
1946
|
-
if (busyAct) return;
|
|
1947
|
-
busyAct = "check";
|
|
1948
|
-
copyNotice = "正在查新版…";
|
|
1949
|
-
render();
|
|
1950
|
-
try {
|
|
1951
|
-
const reply = await call(phoneNames.updateCheck, queueArgs());
|
|
1952
|
-
if (!mounted) return;
|
|
1953
|
-
applyStatusReply(reply);
|
|
1954
|
-
changelogFailedAt.clear();
|
|
1955
|
-
} catch {
|
|
1956
|
-
if (!mounted) return;
|
|
1957
|
-
lastError = "check-failed";
|
|
1958
|
-
lastErrorKind = null;
|
|
1959
|
-
lastDiag = null;
|
|
1960
|
-
} finally {
|
|
1961
|
-
busyAct = null;
|
|
1962
|
-
if (copyNotice === "正在查新版…") copyNotice = null;
|
|
1963
|
-
}
|
|
1964
|
-
render();
|
|
1965
|
-
maybeAutoChangelog();
|
|
1966
|
-
return;
|
|
1967
|
-
case "install":
|
|
1968
|
-
if (busyAct) return;
|
|
1969
|
-
busyAct = "install";
|
|
1970
|
-
copyNotice = "正在安装…";
|
|
1971
|
-
render();
|
|
1972
|
-
try {
|
|
1973
|
-
if (!receipt) {
|
|
1974
|
-
const checked = await call(phoneNames.updateCheck, queueArgs());
|
|
1975
|
-
if (!mounted) return;
|
|
1976
|
-
applyStatusReply(checked);
|
|
1977
|
-
}
|
|
1978
|
-
if (!mounted) return;
|
|
1979
|
-
if (!receipt) {
|
|
1980
|
-
lastError = "check-expired";
|
|
1981
|
-
lastErrorKind = "check-expired";
|
|
1982
|
-
lastDiag = null;
|
|
1983
|
-
render();
|
|
1984
|
-
return;
|
|
1985
|
-
}
|
|
1986
|
-
requestId = randomRequestId();
|
|
1987
|
-
const reply = await call(phoneNames.updateInstall, {
|
|
1988
|
-
checkId: receipt.checkId,
|
|
1989
|
-
requestId,
|
|
1990
|
-
...queueArgs()
|
|
1991
|
-
});
|
|
1992
|
-
if (!mounted) return;
|
|
1993
|
-
applyStatusReply(reply);
|
|
1994
|
-
} catch {
|
|
1995
|
-
if (!mounted) return;
|
|
1996
|
-
lastError = "check-failed";
|
|
1997
|
-
lastErrorKind = null;
|
|
1998
|
-
lastDiag = null;
|
|
1999
|
-
} finally {
|
|
2000
|
-
busyAct = null;
|
|
2001
|
-
if (copyNotice === "正在安装…") copyNotice = null;
|
|
2002
|
-
}
|
|
2003
|
-
render();
|
|
2004
|
-
maybeAutoChangelog();
|
|
2005
|
-
return;
|
|
2006
|
-
case "skip": {
|
|
2007
|
-
const v = snapshot?.latestVersion ?? null;
|
|
2008
|
-
if (v && validReleaseVersion(v)) try {
|
|
2009
|
-
skipStore.skip(v);
|
|
2010
|
-
} catch {}
|
|
2011
|
-
render();
|
|
2012
|
-
return;
|
|
2013
|
-
}
|
|
2014
|
-
case "reset-skip":
|
|
2015
|
-
try {
|
|
2016
|
-
skipStore.reset(arg ?? snapshot?.latestVersion ?? void 0);
|
|
2017
|
-
} catch {}
|
|
2018
|
-
await refresh();
|
|
2019
|
-
return;
|
|
2020
|
-
case "copy-manual":
|
|
2021
|
-
if (manual) try {
|
|
2022
|
-
await copyText(manual);
|
|
2023
|
-
sayCopy("手工命令已复制,粘到终端整行执行即可。");
|
|
2024
|
-
} catch {
|
|
2025
|
-
sayCopy("复制失败,请手动选中上面的命令。");
|
|
2026
|
-
}
|
|
2027
|
-
render();
|
|
2028
|
-
return;
|
|
2029
|
-
case "copy-diag": {
|
|
2030
|
-
const jobCode = snapshot?.job?.state === "failed" ? messageCodeOf(snapshot.job.message) || "install-failed" : "";
|
|
2031
|
-
const code = failureCodeOf({
|
|
2032
|
-
error: lastError,
|
|
2033
|
-
errorKind: lastErrorKind
|
|
2034
|
-
}, jobCode || snapshot?.blockedReason || "check-failed");
|
|
2035
|
-
const detail = snapshot?.job?.message && snapshot.job.message.includes(":") ? snapshot.job.message.slice(snapshot.job.message.indexOf(":") + 1) : snapshot?.job?.message;
|
|
2036
|
-
const text = buildUpdateDiagCopy({
|
|
2037
|
-
pluginId,
|
|
2038
|
-
code,
|
|
2039
|
-
detail,
|
|
2040
|
-
runningVersion: snapshot?.runningVersion ?? null,
|
|
2041
|
-
installedVersion: snapshot?.installedVersion ?? null,
|
|
2042
|
-
latestVersion: snapshot?.latestVersion ?? null,
|
|
2043
|
-
hostKind,
|
|
2044
|
-
queuePosition: queue?.position ?? null,
|
|
2045
|
-
requestId,
|
|
2046
|
-
checkId: receipt?.checkId ?? null,
|
|
2047
|
-
route: null,
|
|
2048
|
-
diag: lastDiag,
|
|
2049
|
-
manual,
|
|
2050
|
-
format: diagCopyFormat
|
|
2051
|
-
});
|
|
2052
|
-
try {
|
|
2053
|
-
await copyText(text);
|
|
2054
|
-
sayCopy("诊断已复制,直接粘给插件作者即可(已脱敏)。");
|
|
2055
|
-
} catch {
|
|
2056
|
-
sayCopy("复制失败,请手动选中上面的信息。");
|
|
2057
|
-
}
|
|
2058
|
-
render();
|
|
2059
|
-
return;
|
|
2060
|
-
}
|
|
2061
|
-
case "toggle-queue":
|
|
2062
|
-
showOthers = !showOthers;
|
|
2063
|
-
await refresh();
|
|
2064
|
-
return;
|
|
2065
|
-
case "restart-hint":
|
|
2066
|
-
try {
|
|
2067
|
-
if (typeof onRestartRequested === "function") {
|
|
2068
|
-
await onRestartRequested();
|
|
2069
|
-
sayCopy("已按调用方的重启流程处理;重启后新版生效。");
|
|
2070
|
-
} else sayCopy("本宿主未提供重启入口:请手动重启宿主,重启后新版生效。");
|
|
2071
|
-
} catch {
|
|
2072
|
-
sayCopy("重启入口调用失败:请手动重启宿主,重启后新版生效。");
|
|
2073
|
-
}
|
|
2074
|
-
render();
|
|
2075
|
-
return;
|
|
2076
|
-
case "close-view":
|
|
2077
|
-
await requestDialogClose();
|
|
2078
|
-
return;
|
|
2079
|
-
}
|
|
2080
|
-
}
|
|
2081
|
-
async function setMode(next) {
|
|
2082
|
-
if (next !== "embedded" && next !== "dialog") throw new Error(`[dsh-plugin-update] \u6446\u653E\u5F62\u6001\u975E\u6CD5\uFF1A\u53EA\u6536 embedded \u6216 dialog\uFF08\u6536\u5230 ${JSON.stringify(next)}\uFF09`);
|
|
2083
|
-
mode = next;
|
|
2084
|
-
render();
|
|
2085
|
-
}
|
|
2086
|
-
async function setTheme(next) {
|
|
2087
|
-
if (next !== "default" && next !== "archive" && next !== "d5-paper") throw new Error(`[dsh-plugin-update] \u4E3B\u9898\u975E\u6CD5\uFF1A\u53EA\u6536 default \u6216 archive\uFF08d5-paper \u4E3A\u65E7\u522B\u540D\u4ECD\u53EF\u7528\uFF09\uFF08\u6536\u5230 ${JSON.stringify(next)}\uFF09`);
|
|
2088
|
-
theme = normalizePanelTheme(next);
|
|
2089
|
-
render();
|
|
2090
|
-
}
|
|
2091
|
-
async function setShowOthers(show) {
|
|
2092
|
-
showOthers = show === true;
|
|
2093
|
-
await refresh();
|
|
2094
|
-
}
|
|
2095
|
-
function onClick(ev) {
|
|
2096
|
-
try {
|
|
2097
|
-
const t = ev;
|
|
2098
|
-
const btn = t?.target && typeof t.target.closest === "function" ? t.target.closest("[data-action]") : null;
|
|
2099
|
-
const kind = btn?.getAttribute ? btn.getAttribute("data-action") : null;
|
|
2100
|
-
if (!kind) return;
|
|
2101
|
-
act(kind);
|
|
2102
|
-
} catch {}
|
|
2103
|
-
}
|
|
2104
|
-
async function requestDialogClose() {
|
|
2105
|
-
if (!mounted || mode !== "dialog") return;
|
|
2106
|
-
if (onCloseRequested) try {
|
|
2107
|
-
await onCloseRequested();
|
|
2108
|
-
} catch {}
|
|
2109
|
-
unmount();
|
|
2110
|
-
}
|
|
2111
|
-
function onKeyDown(ev) {
|
|
2112
|
-
try {
|
|
2113
|
-
const e = ev;
|
|
2114
|
-
if (!mounted || mode !== "dialog" || !e || e.key !== "Escape") return;
|
|
2115
|
-
requestDialogClose();
|
|
2116
|
-
} catch {}
|
|
2117
|
-
}
|
|
2118
|
-
function setChangelogMarkdown(markdown) {
|
|
2119
|
-
changelogMarkdown = typeof markdown === "string" ? markdown : null;
|
|
2120
|
-
if (typeof markdown === "string") manualChangelogOverride = true;
|
|
2121
|
-
render();
|
|
2122
|
-
}
|
|
2123
|
-
function unmount() {
|
|
2124
|
-
if (!mounted) return;
|
|
2125
|
-
mounted = false;
|
|
2126
|
-
autoSeq++;
|
|
2127
|
-
changelogInflight.clear();
|
|
2128
|
-
try {
|
|
2129
|
-
timer.clear(handle);
|
|
2130
|
-
} catch {}
|
|
2131
|
-
try {
|
|
2132
|
-
container.removeEventListener?.("click", onClick);
|
|
2133
|
-
} catch {}
|
|
2134
|
-
try {
|
|
2135
|
-
container.removeEventListener?.("keydown", onKeyDown);
|
|
2136
|
-
} catch {}
|
|
1486
|
+
const errLines = [];
|
|
1487
|
+
if (b.kind === "failed" || b.kind === "blocked") errLines.push(`<div class="dsh-upd-err">\u7A33\u5B9A\u7801 <code>${escapeHtml$2(String(b.kind === "blocked" ? snapshot?.blockedReason ?? b.kind : "install-failed"))}</code>\uFF1A\u4E0A\u4E00\u6761\u4E2D\u6587\u8BF4\u660E\u5C31\u662F\u8981\u7528\u6237\u505A\u7684\u4E8B\uFF1B\u8981\u5F80\u4E0A\u6E38\u62A5\uFF0C\u7528\u300C\u590D\u5236\u8BCA\u65AD\u300D\u6574\u6BB5\u7C98\uFF08\u5DF2\u8131\u654F\uFF09\u3002</div>`);
|
|
1488
|
+
errLines.push(`<div class="dsh-upd-log">\u6DF1\u6316\u770B\u65E5\u5FD7\uFF1A\u6309\u63D2\u4EF6\u6807\u8BC6 <code>${escapeHtml$2(pluginId)}</code> \u8FC7\u6EE4 <code>host.call</code>\u3001<code>host.call.fail</code>\u3001<code>update.install.exec</code> \u4E09\u4E2A\u4E8B\u4EF6\u3002</div>`);
|
|
1489
|
+
if (copyNotice) errLines.push(`<div class="dsh-upd-copy" role="status">${escapeHtml$2(copyNotice)}</div>`);
|
|
1490
|
+
parts.push(chapterOf(4, errLines.join("")));
|
|
2137
1491
|
}
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
const
|
|
2146
|
-
const
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
1492
|
+
parts.push(chapterOf(5, view.showManual && manual ? `<div class="dsh-upd-manual"><div>\u624B\u5DE5\u515C\u5E95\u547D\u4EE4\uFF08\u590D\u5236\u6574\u884C\u6267\u884C\uFF09\uFF1A</div><code>${escapeHtml$2(manual)}</code></div>` : `<div class="dsh-upd-manual"><div class="dsh-upd-changelog-neutral">\u5F53\u524D\u6CA1\u6709\u53EF\u7528\u7684\u624B\u5DE5\u547D\u4EE4\uFF08\u8BA4\u4E0D\u51FA\u4F7F\u7528\u8303\u56F4\u6216\u5C5E\u6E90\u7801\u5B89\u88C5\u65F6\u4E0D\u7ED9\uFF09\u3002</div></div>`));
|
|
1493
|
+
if (showActions && mode === "dialog") parts.push(`<div class="dsh-upd-footer"><span class="dsh-upd-foot-note">\u5B89\u88C5\u5728\u5BBF\u4E3B\u4FA7\u7EE7\u7EED\u8DD1\uFF0C\u91CD\u5F00\u6062\u590D\u663E\u793A</span><button type="button" data-action="close-view" title="\u5173\u95ED\u9762\u677F\uFF08\u5B89\u88C5\u5728\u5BBF\u4E3B\u4FA7\u7EE7\u7EED\u8DD1\uFF0C\u53EF\u91CD\u5F00\u6062\u590D\u663E\u793A\uFF09">\u5173\u95ED</button></div>`);
|
|
1494
|
+
return parts.join("\n");
|
|
1495
|
+
}
|
|
1496
|
+
function renderUpdatePanelHTML(input) {
|
|
1497
|
+
const view = panelViewModel(input);
|
|
1498
|
+
const kernel = renderUpdatePanelKernel(input, view);
|
|
1499
|
+
const d5 = normalizePanelTheme(input.theme) === "d5-paper";
|
|
1500
|
+
const attr = d5 ? " data-theme=\"d5-paper\"" : "";
|
|
1501
|
+
const sealAttr = ` data-seal="${escapeHtml$2(view.seal.text)}" data-seal-tone="${view.seal.tone}"`;
|
|
1502
|
+
const body = input.mode === "dialog" ? `<div class="dsh-upd-overlay" data-mode="dialog"><div class="dsh-upd" data-mode="dialog" data-plugin="${escapeHtml$2(input.pluginId)}"${sealAttr}${attr}>
|
|
1503
|
+
${kernel}
|
|
1504
|
+
</div></div>` : `<div class="dsh-upd" data-mode="embedded" data-plugin="${escapeHtml$2(input.pluginId)}"${sealAttr}${attr}>
|
|
1505
|
+
${kernel}
|
|
1506
|
+
</div>`;
|
|
1507
|
+
return `<style>${d5 ? `${UPDATE_PANEL_CSS}
|
|
1508
|
+
${UPDATE_PANEL_D5_CSS}` : UPDATE_PANEL_CSS}</style>
|
|
1509
|
+
${body}`;
|
|
1510
|
+
}
|
|
1511
|
+
//#endregion
|
|
1512
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-update@0.5.4/node_modules/dsh-plugin-update/dist/entry.js
|
|
1513
|
+
const UPDATE_ENTRY_CSS = [
|
|
1514
|
+
".dsh-upd-entry{display:inline-flex;align-items:center;gap:8px;font:13px/1.6 system-ui,\"Microsoft YaHei\",sans-serif;color:var(--dsh-upd-fg,#1f2937)}",
|
|
1515
|
+
".dsh-upd-entry-btn{font:inherit;border:1px solid var(--dsh-upd-line,#d1d5db);border-radius:6px;",
|
|
1516
|
+
"background:var(--dsh-upd-btn,#f9fafb);color:inherit;padding:4px 12px;cursor:pointer}",
|
|
1517
|
+
".dsh-upd-entry-btn:hover{border-color:var(--dsh-upd-primary,#2563eb)}",
|
|
1518
|
+
".dsh-upd-entry-btn,.dsh-upd-entry-dot{transition:background-color .15s ease,border-color .15s ease,color .15s ease,transform .06s ease}",
|
|
1519
|
+
".dsh-upd-entry-btn:active:not(:disabled){transform:translateY(1px)}",
|
|
1520
|
+
".dsh-upd-entry-btn:disabled,.dsh-upd-entry-dot:disabled{opacity:.55;cursor:wait}",
|
|
1521
|
+
".dsh-upd-entry-btn[aria-busy=\"true\"]::after{content:\"\";display:inline-block;width:10px;height:10px;margin-left:7px;vertical-align:-1px;",
|
|
1522
|
+
"border:2px solid currentColor;border-top-color:transparent;border-radius:50%;animation:dsh-upd-entry-spin .8s linear infinite}",
|
|
1523
|
+
"@keyframes dsh-upd-entry-spin{to{transform:rotate(360deg)}}",
|
|
1524
|
+
"@media (prefers-reduced-motion: reduce){.dsh-upd-entry-btn,.dsh-upd-entry-dot{transition:none}.dsh-upd-entry-btn[aria-busy=\"true\"]::after{animation:none}}",
|
|
1525
|
+
".dsh-upd-entry-btn:focus-visible,.dsh-upd-entry-dot:focus-visible{outline:2px solid var(--dsh-upd-focus,#2563eb);outline-offset:1px}",
|
|
1526
|
+
".dsh-upd-entry[data-state=\"update\"] .dsh-upd-entry-btn{border-color:var(--dsh-upd-ok-line,#059669);color:var(--dsh-upd-ok-line,#059669)}",
|
|
1527
|
+
".dsh-upd-entry[data-state=\"restart\"] .dsh-upd-entry-btn{border-color:var(--dsh-upd-warn-line,#d97706);color:var(--dsh-upd-warn-line,#d97706)}",
|
|
1528
|
+
".dsh-upd-entry[data-state=\"failed\"] .dsh-upd-entry-btn{border-color:var(--dsh-upd-bad-line,#dc2626);color:var(--dsh-upd-bad-line,#dc2626)}",
|
|
1529
|
+
".dsh-upd-entry-dot{width:10px;height:10px;padding:0;border:0;border-radius:50%;background:var(--dsh-upd-line,#9ca3af);cursor:pointer}",
|
|
1530
|
+
".dsh-upd-entry[data-state=\"update\"] .dsh-upd-entry-dot{background:var(--dsh-upd-ok-line,#059669)}",
|
|
1531
|
+
".dsh-upd-entry[data-state=\"busy\"] .dsh-upd-entry-dot,.dsh-upd-entry[data-state=\"restart\"] .dsh-upd-entry-dot{background:var(--dsh-upd-warn-line,#d97706)}",
|
|
1532
|
+
".dsh-upd-entry[data-state=\"failed\"] .dsh-upd-entry-dot{background:var(--dsh-upd-bad-line,#dc2626)}",
|
|
1533
|
+
".dsh-upd-entry-note{font-size:12.5px;opacity:.9;background:var(--dsh-upd-bg,#ffffff);border:1px solid var(--dsh-upd-line,#e5e7eb);border-radius:4px;padding:1px 8px}",
|
|
1534
|
+
".dsh-upd-entry[data-theme=\"d5-paper\"] .dsh-upd-entry-note{background:var(--d5-card);border-color:var(--d5-line-strong);color:var(--d5-ink)}",
|
|
1535
|
+
".dsh-upd-entry[data-theme=\"d5-paper\"]{--d5-ink:#1a1a1a;--d5-muted:#6f675a;--d5-line-strong:#c4b896;--d5-accent:#c8402a;--d5-card:#fffdf6;",
|
|
1536
|
+
"font-family:Georgia,\"Songti SC\",\"STSong\",\"SimSun\",serif;color:var(--d5-ink)}",
|
|
1537
|
+
".dsh-upd-entry[data-theme=\"d5-paper\"] .dsh-upd-entry-btn{border-color:var(--d5-line-strong);background:var(--d5-card);color:var(--d5-ink);border-radius:3px}",
|
|
1538
|
+
".dsh-upd-entry[data-theme=\"d5-paper\"] .dsh-upd-entry-btn:hover{border-color:var(--d5-accent);color:var(--d5-accent)}",
|
|
1539
|
+
"@media (prefers-color-scheme: dark){.dsh-upd-entry[data-theme=\"d5-paper\"]{--d5-ink:#ece5d3;--d5-muted:#a89c83;--d5-line-strong:#5c4e3b;--d5-accent:#e0684e;--d5-card:#1e1a15}}",
|
|
1540
|
+
"@media (prefers-color-scheme: dark){.dsh-upd-entry{color:#e5e7eb}",
|
|
1541
|
+
".dsh-upd-entry-btn{--dsh-upd-btn:#1f2937;--dsh-upd-line:#374151}}"
|
|
1542
|
+
].join("\n");
|
|
1543
|
+
function isTerminalPhase(phase) {
|
|
1544
|
+
return phase === "done" || phase === "failed" || phase === "skipped" || phase === "current";
|
|
1545
|
+
}
|
|
1546
|
+
function asMillis(value, fallback) {
|
|
1547
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : fallback;
|
|
1548
|
+
}
|
|
1549
|
+
function isNonEmptyString(value) {
|
|
1550
|
+
return typeof value === "string" && value.length > 0;
|
|
1551
|
+
}
|
|
1552
|
+
const PHASES = [
|
|
1553
|
+
"pending",
|
|
1554
|
+
"checking",
|
|
1555
|
+
"ready",
|
|
1556
|
+
"installing",
|
|
1557
|
+
"current",
|
|
1558
|
+
"done",
|
|
1559
|
+
"failed",
|
|
1560
|
+
"skipped"
|
|
1561
|
+
];
|
|
1562
|
+
function asPhase(value) {
|
|
1563
|
+
return typeof value === "string" && PHASES.includes(value) ? value : "pending";
|
|
1564
|
+
}
|
|
1565
|
+
function batchRequestId(sessionId, key) {
|
|
1566
|
+
return "batch:" + sessionId + ":" + key;
|
|
1567
|
+
}
|
|
1568
|
+
function emptyBatchSession() {
|
|
2154
1569
|
return {
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
1570
|
+
version: 1,
|
|
1571
|
+
id: "",
|
|
1572
|
+
selfKey: null,
|
|
1573
|
+
stopOnFailure: false,
|
|
1574
|
+
order: [],
|
|
1575
|
+
entries: [],
|
|
1576
|
+
createdAt: 0,
|
|
1577
|
+
updatedAt: 0
|
|
2162
1578
|
};
|
|
2163
1579
|
}
|
|
1580
|
+
function normalizeBatchSession(raw) {
|
|
1581
|
+
try {
|
|
1582
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return emptyBatchSession();
|
|
1583
|
+
const input = raw;
|
|
1584
|
+
if (input["version"] !== 1) return emptyBatchSession();
|
|
1585
|
+
const id = isNonEmptyString(input["id"]) ? input["id"] : "";
|
|
1586
|
+
const selfKey = isNonEmptyString(input["selfKey"]) ? input["selfKey"] : null;
|
|
1587
|
+
const entries = [];
|
|
1588
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1589
|
+
const rawEntries = input["entries"];
|
|
1590
|
+
if (Array.isArray(rawEntries)) for (const item of rawEntries) {
|
|
1591
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) continue;
|
|
1592
|
+
const e = item;
|
|
1593
|
+
const key = e["key"];
|
|
1594
|
+
if (!isNonEmptyString(key) || seen.has(key)) continue;
|
|
1595
|
+
seen.add(key);
|
|
1596
|
+
const requestId = isNonEmptyString(e["requestId"]) ? e["requestId"] : batchRequestId(id, key);
|
|
1597
|
+
entries.push({
|
|
1598
|
+
key,
|
|
1599
|
+
phase: asPhase(e["phase"]),
|
|
1600
|
+
requestId,
|
|
1601
|
+
targetVersion: isNonEmptyString(e["targetVersion"]) ? e["targetVersion"] : null,
|
|
1602
|
+
restartRequired: e["restartRequired"] === true,
|
|
1603
|
+
error: isNonEmptyString(e["error"]) ? e["error"] : null,
|
|
1604
|
+
updatedAt: asMillis(e["updatedAt"], 0)
|
|
1605
|
+
});
|
|
1606
|
+
}
|
|
1607
|
+
const order = entries.map((e) => e.key);
|
|
1608
|
+
return {
|
|
1609
|
+
version: 1,
|
|
1610
|
+
id,
|
|
1611
|
+
selfKey: selfKey && seen.has(selfKey) ? selfKey : null,
|
|
1612
|
+
stopOnFailure: input["stopOnFailure"] === true,
|
|
1613
|
+
order,
|
|
1614
|
+
entries,
|
|
1615
|
+
createdAt: asMillis(input["createdAt"], 0),
|
|
1616
|
+
updatedAt: asMillis(input["updatedAt"], 0)
|
|
1617
|
+
};
|
|
1618
|
+
} catch {
|
|
1619
|
+
return emptyBatchSession();
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
2164
1622
|
//#endregion
|
|
2165
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-update@0.5.
|
|
1623
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-update@0.5.4/node_modules/dsh-plugin-update/dist/panel-batch.js
|
|
2166
1624
|
const BATCH_PANEL_POLL = {
|
|
2167
1625
|
defaultMs: 1500,
|
|
2168
1626
|
minMs: 250
|
|
@@ -2701,6 +2159,7 @@ ${body}`;
|
|
|
2701
2159
|
const call = options.call;
|
|
2702
2160
|
const titles = options.titles && typeof options.titles === "object" ? options.titles : {};
|
|
2703
2161
|
const onRestartRequested = options.onRestartRequested;
|
|
2162
|
+
const onCloseRequested = typeof options.onCloseRequested === "function" ? options.onCloseRequested : null;
|
|
2704
2163
|
const copyText = options.copyText ?? defaultCopyText;
|
|
2705
2164
|
const skipStores = /* @__PURE__ */ new Map();
|
|
2706
2165
|
const autoChangelogEnabled = options.autoChangelog !== false;
|
|
@@ -3025,16 +2484,23 @@ ${body}`;
|
|
|
3025
2484
|
render();
|
|
3026
2485
|
return;
|
|
3027
2486
|
case "close":
|
|
3028
|
-
|
|
2487
|
+
await requestDialogClose();
|
|
3029
2488
|
return;
|
|
3030
2489
|
default: return;
|
|
3031
2490
|
}
|
|
3032
2491
|
}
|
|
2492
|
+
async function requestDialogClose() {
|
|
2493
|
+
if (!mounted || mode !== "dialog") return;
|
|
2494
|
+
if (onCloseRequested) try {
|
|
2495
|
+
await onCloseRequested();
|
|
2496
|
+
} catch {}
|
|
2497
|
+
unmount();
|
|
2498
|
+
}
|
|
3033
2499
|
function onKeyDown(ev) {
|
|
3034
2500
|
try {
|
|
3035
2501
|
const e = ev;
|
|
3036
2502
|
if (!mounted || mode !== "dialog" || !e || e.key !== "Escape") return;
|
|
3037
|
-
|
|
2503
|
+
requestDialogClose();
|
|
3038
2504
|
} catch {}
|
|
3039
2505
|
}
|
|
3040
2506
|
function setTheme(next) {
|
|
@@ -3104,108 +2570,89 @@ ${body}`;
|
|
|
3104
2570
|
};
|
|
3105
2571
|
}
|
|
3106
2572
|
//#endregion
|
|
3107
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-update@0.5.
|
|
2573
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-update@0.5.4/node_modules/dsh-plugin-update/dist/entry-batch.js
|
|
3108
2574
|
const LABEL_IDLE = "检查更新";
|
|
3109
|
-
const LABEL_FAILED = "更新失败,点此查看";
|
|
3110
2575
|
const LABEL_BUSY = "正在安装…";
|
|
3111
|
-
const LABEL_RESTART = "待重启";
|
|
3112
|
-
function hasUpdateOf(snapshot) {
|
|
3113
|
-
if (!snapshot) return false;
|
|
3114
|
-
const latest = snapshot.latestVersion;
|
|
3115
|
-
if (typeof latest !== "string" || !latest.trim()) return false;
|
|
3116
|
-
return latest.trim() !== snapshot.runningVersion;
|
|
3117
|
-
}
|
|
3118
|
-
function entryStateKind(state) {
|
|
3119
|
-
const snapshot = state?.snapshot ?? null;
|
|
3120
|
-
const job = snapshot?.job ?? null;
|
|
3121
|
-
if (job && (job.state === "installing" || job.state === "verifying")) return "busy";
|
|
3122
|
-
if (snapshot && (snapshot.blockedReason === "pending-restart" || job?.state === "restart-required")) return "restart";
|
|
3123
|
-
if (state && state.error || job && (job.state === "failed" || job.state === "interrupted")) return "failed";
|
|
3124
|
-
if (hasUpdateOf(snapshot)) return "update";
|
|
3125
|
-
return "idle";
|
|
3126
|
-
}
|
|
3127
|
-
function entryLabelFor(state) {
|
|
3128
|
-
switch (entryStateKind(state)) {
|
|
3129
|
-
case "busy": return LABEL_BUSY;
|
|
3130
|
-
case "restart": return LABEL_RESTART;
|
|
3131
|
-
case "failed": return LABEL_FAILED;
|
|
3132
|
-
case "update": {
|
|
3133
|
-
const latest = state?.snapshot?.latestVersion;
|
|
3134
|
-
return typeof latest === "string" && latest.trim() ? `\u6709\u65B0\u7248 ${latest.trim()}` : LABEL_IDLE;
|
|
3135
|
-
}
|
|
3136
|
-
default: return LABEL_IDLE;
|
|
3137
|
-
}
|
|
3138
|
-
}
|
|
3139
|
-
const UPDATE_ENTRY_CSS = [
|
|
3140
|
-
".dsh-upd-entry{display:inline-flex;align-items:center;gap:8px;font:13px/1.6 system-ui,\"Microsoft YaHei\",sans-serif;color:var(--dsh-upd-fg,#1f2937)}",
|
|
3141
|
-
".dsh-upd-entry-btn{font:inherit;border:1px solid var(--dsh-upd-line,#d1d5db);border-radius:6px;",
|
|
3142
|
-
"background:var(--dsh-upd-btn,#f9fafb);color:inherit;padding:4px 12px;cursor:pointer}",
|
|
3143
|
-
".dsh-upd-entry-btn:hover{border-color:var(--dsh-upd-primary,#2563eb)}",
|
|
3144
|
-
".dsh-upd-entry-btn,.dsh-upd-entry-dot{transition:background-color .15s ease,border-color .15s ease,color .15s ease,transform .06s ease}",
|
|
3145
|
-
".dsh-upd-entry-btn:active:not(:disabled){transform:translateY(1px)}",
|
|
3146
|
-
".dsh-upd-entry-btn:disabled,.dsh-upd-entry-dot:disabled{opacity:.55;cursor:wait}",
|
|
3147
|
-
".dsh-upd-entry-btn[aria-busy=\"true\"]::after{content:\"\";display:inline-block;width:10px;height:10px;margin-left:7px;vertical-align:-1px;",
|
|
3148
|
-
"border:2px solid currentColor;border-top-color:transparent;border-radius:50%;animation:dsh-upd-entry-spin .8s linear infinite}",
|
|
3149
|
-
"@keyframes dsh-upd-entry-spin{to{transform:rotate(360deg)}}",
|
|
3150
|
-
"@media (prefers-reduced-motion: reduce){.dsh-upd-entry-btn,.dsh-upd-entry-dot{transition:none}.dsh-upd-entry-btn[aria-busy=\"true\"]::after{animation:none}}",
|
|
3151
|
-
".dsh-upd-entry-btn:focus-visible,.dsh-upd-entry-dot:focus-visible{outline:2px solid var(--dsh-upd-focus,#2563eb);outline-offset:1px}",
|
|
3152
|
-
".dsh-upd-entry[data-state=\"update\"] .dsh-upd-entry-btn{border-color:var(--dsh-upd-ok-line,#059669);color:var(--dsh-upd-ok-line,#059669)}",
|
|
3153
|
-
".dsh-upd-entry[data-state=\"restart\"] .dsh-upd-entry-btn{border-color:var(--dsh-upd-warn-line,#d97706);color:var(--dsh-upd-warn-line,#d97706)}",
|
|
3154
|
-
".dsh-upd-entry[data-state=\"failed\"] .dsh-upd-entry-btn{border-color:var(--dsh-upd-bad-line,#dc2626);color:var(--dsh-upd-bad-line,#dc2626)}",
|
|
3155
|
-
".dsh-upd-entry-dot{width:10px;height:10px;padding:0;border:0;border-radius:50%;background:var(--dsh-upd-line,#9ca3af);cursor:pointer}",
|
|
3156
|
-
".dsh-upd-entry[data-state=\"update\"] .dsh-upd-entry-dot{background:var(--dsh-upd-ok-line,#059669)}",
|
|
3157
|
-
".dsh-upd-entry[data-state=\"busy\"] .dsh-upd-entry-dot,.dsh-upd-entry[data-state=\"restart\"] .dsh-upd-entry-dot{background:var(--dsh-upd-warn-line,#d97706)}",
|
|
3158
|
-
".dsh-upd-entry[data-state=\"failed\"] .dsh-upd-entry-dot{background:var(--dsh-upd-bad-line,#dc2626)}",
|
|
3159
|
-
".dsh-upd-entry-note{font-size:12.5px;opacity:.9;background:var(--dsh-upd-bg,#ffffff);border:1px solid var(--dsh-upd-line,#e5e7eb);border-radius:4px;padding:1px 8px}",
|
|
3160
|
-
".dsh-upd-entry[data-theme=\"d5-paper\"] .dsh-upd-entry-note{background:var(--d5-card);border-color:var(--d5-line-strong);color:var(--d5-ink)}",
|
|
3161
|
-
".dsh-upd-entry[data-theme=\"d5-paper\"]{--d5-ink:#1a1a1a;--d5-muted:#6f675a;--d5-line-strong:#c4b896;--d5-accent:#c8402a;--d5-card:#fffdf6;",
|
|
3162
|
-
"font-family:Georgia,\"Songti SC\",\"STSong\",\"SimSun\",serif;color:var(--d5-ink)}",
|
|
3163
|
-
".dsh-upd-entry[data-theme=\"d5-paper\"] .dsh-upd-entry-btn{border-color:var(--d5-line-strong);background:var(--d5-card);color:var(--d5-ink);border-radius:3px}",
|
|
3164
|
-
".dsh-upd-entry[data-theme=\"d5-paper\"] .dsh-upd-entry-btn:hover{border-color:var(--d5-accent);color:var(--d5-accent)}",
|
|
3165
|
-
"@media (prefers-color-scheme: dark){.dsh-upd-entry[data-theme=\"d5-paper\"]{--d5-ink:#ece5d3;--d5-muted:#a89c83;--d5-line-strong:#5c4e3b;--d5-accent:#e0684e;--d5-card:#1e1a15}}",
|
|
3166
|
-
"@media (prefers-color-scheme: dark){.dsh-upd-entry{color:#e5e7eb}",
|
|
3167
|
-
".dsh-upd-entry-btn{--dsh-upd-btn:#1f2937;--dsh-upd-line:#374151}}"
|
|
3168
|
-
].join("\n");
|
|
3169
|
-
const ENTRY_ATTR = "data-dsh-upd-entry";
|
|
3170
|
-
const ENTRY_SELECTOR = "[data-dsh-upd-entry]";
|
|
3171
2576
|
function isObject(value) {
|
|
3172
2577
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
3173
2578
|
}
|
|
3174
|
-
function
|
|
3175
|
-
if (!
|
|
3176
|
-
if (typeof value["runningVersion"] !== "string") return null;
|
|
3177
|
-
if (typeof value["canInstall"] !== "boolean") return null;
|
|
2579
|
+
function asRows(value) {
|
|
2580
|
+
if (!Array.isArray(value)) return null;
|
|
3178
2581
|
return value;
|
|
3179
2582
|
}
|
|
3180
2583
|
function escapeHtml(value) {
|
|
3181
2584
|
return String(value).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
3182
2585
|
}
|
|
3183
|
-
function
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
const
|
|
3187
|
-
|
|
3188
|
-
if (
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
2586
|
+
function batchEntrySummary(state) {
|
|
2587
|
+
const rows = state?.rows ?? null;
|
|
2588
|
+
const counts = batchLedgerCounts(Array.isArray(rows) ? rows : []);
|
|
2589
|
+
const total = Array.isArray(rows) ? rows.length : 0;
|
|
2590
|
+
let kind;
|
|
2591
|
+
if (!Array.isArray(rows) || rows.length === 0) kind = state?.error ? "failed" : "idle";
|
|
2592
|
+
else if (counts.installing > 0) kind = "busy";
|
|
2593
|
+
else if (counts.failed > 0) kind = "failed";
|
|
2594
|
+
else if (counts.restart > 0) kind = "restart";
|
|
2595
|
+
else if (counts.updatable > 0) kind = "update";
|
|
2596
|
+
else kind = "idle";
|
|
2597
|
+
if (kind !== "busy" && state?.error) {
|
|
2598
|
+
if (Array.isArray(rows) && rows.length > 0 && counts.failed === 0 && counts.installing === 0) kind = "failed";
|
|
2599
|
+
}
|
|
2600
|
+
const hasUpdate = counts.installing > 0 || counts.failed > 0 || counts.restart > 0 || counts.updatable > 0;
|
|
2601
|
+
let label;
|
|
2602
|
+
switch (kind) {
|
|
2603
|
+
case "busy":
|
|
2604
|
+
label = LABEL_BUSY;
|
|
2605
|
+
break;
|
|
2606
|
+
case "failed":
|
|
2607
|
+
label = counts.failed > 0 ? counts.failed + " 家失败,点此查看" : "更新失败,点此查看";
|
|
2608
|
+
break;
|
|
2609
|
+
case "restart":
|
|
2610
|
+
label = counts.restart + " 家待重启";
|
|
2611
|
+
break;
|
|
2612
|
+
case "update":
|
|
2613
|
+
label = counts.updatable + " 家可更新";
|
|
2614
|
+
break;
|
|
2615
|
+
default: label = LABEL_IDLE;
|
|
2616
|
+
}
|
|
2617
|
+
return {
|
|
2618
|
+
kind,
|
|
2619
|
+
label,
|
|
2620
|
+
updatable: counts.updatable,
|
|
2621
|
+
installing: counts.installing,
|
|
2622
|
+
pending: counts.pending,
|
|
2623
|
+
restart: counts.restart,
|
|
2624
|
+
failed: counts.failed,
|
|
2625
|
+
skipped: counts.skipped,
|
|
2626
|
+
settled: counts.settled,
|
|
2627
|
+
total,
|
|
2628
|
+
hasUpdate
|
|
2629
|
+
};
|
|
2630
|
+
}
|
|
2631
|
+
function mountUpdateBatchEntry(container, options) {
|
|
2632
|
+
if (!container || typeof container.innerHTML !== "string") throw new Error("[dsh-plugin-update] 挂批量入口件需要一个有 innerHTML 的容器");
|
|
2633
|
+
if (!options || typeof options !== "object") throw new Error("[dsh-plugin-update] 挂批量入口件缺少配置:批量电话前缀 prefix 必填");
|
|
2634
|
+
if (typeof options.call !== "function") throw new Error("[dsh-plugin-update] 挂批量入口件需要传输函数 call(入口件调宿主电话的唯一接触面)");
|
|
2635
|
+
const phones = buildBatchPhoneNames(options.prefix);
|
|
3192
2636
|
const variant = options.variant ?? "button";
|
|
3193
|
-
if (variant !== "button" && variant !== "badge" && variant !== "inline") throw new Error(
|
|
2637
|
+
if (variant !== "button" && variant !== "badge" && variant !== "inline") throw new Error("[dsh-plugin-update] 入口件形态非法:只收 button / badge / inline(收到 " + JSON.stringify(options.variant) + ")");
|
|
3194
2638
|
const autoCheck = options.autoCheck ?? "mount";
|
|
3195
|
-
if (autoCheck !== "mount" && autoCheck !== "never") throw new Error(
|
|
3196
|
-
const openOn = options.openOn ?? "
|
|
3197
|
-
if (openOn !== "has-update" && openOn !== "always" && openOn !== "manual" && openOn !== "direct") throw new Error(
|
|
3198
|
-
if (options.theme !== void 0 && options.theme !== "default" && options.theme !== "archive" && options.theme !== "d5-paper") throw new Error(
|
|
2639
|
+
if (autoCheck !== "mount" && autoCheck !== "never") throw new Error("[dsh-plugin-update] 自动检查时机非法:只收 mount 或 never(收到 " + JSON.stringify(options.autoCheck) + ")");
|
|
2640
|
+
const openOn = options.openOn ?? "always";
|
|
2641
|
+
if (openOn !== "has-update" && openOn !== "always" && openOn !== "manual" && openOn !== "direct") throw new Error("[dsh-plugin-update] 点击去向非法:只收 has-update / always / manual / direct(收到 " + JSON.stringify(options.openOn) + ")");
|
|
2642
|
+
if (options.theme !== void 0 && options.theme !== "default" && options.theme !== "archive" && options.theme !== "d5-paper") throw new Error("[dsh-plugin-update] 主题非法:只收 default 或 archive(d5-paper 为旧别名仍可用)(收到 " + JSON.stringify(options.theme) + ")");
|
|
3199
2643
|
let theme = normalizePanelTheme(options.theme ?? "default");
|
|
3200
2644
|
const pollMs = options.pollMs;
|
|
3201
|
-
if (pollMs !== void 0 && (typeof pollMs !== "number" || !Number.isFinite(pollMs) || pollMs < 250)) throw new Error(
|
|
2645
|
+
if (pollMs !== void 0 && (typeof pollMs !== "number" || !Number.isFinite(pollMs) || pollMs < 250)) throw new Error("[dsh-plugin-update] 面板轮询间隔非法:不得小于 250 毫秒(收到 " + JSON.stringify(options.pollMs) + ")");
|
|
3202
2646
|
const labelOverride = typeof options.label === "string" && options.label ? options.label : null;
|
|
3203
|
-
const
|
|
2647
|
+
const titles = options.titles && typeof options.titles === "object" ? options.titles : {};
|
|
3204
2648
|
const onActivate = typeof options.onActivate === "function" ? options.onActivate : null;
|
|
3205
2649
|
const call = options.call;
|
|
3206
|
-
|
|
2650
|
+
const ENTRY_ATTR = "data-dsh-upd-entry";
|
|
2651
|
+
const ENTRY_SELECTOR = "[data-dsh-upd-entry]";
|
|
2652
|
+
let rows = null;
|
|
3207
2653
|
let error = null;
|
|
3208
2654
|
let note = null;
|
|
2655
|
+
let loaded = false;
|
|
3209
2656
|
let activating = false;
|
|
3210
2657
|
let mounted = true;
|
|
3211
2658
|
let panel = null;
|
|
@@ -3230,28 +2677,27 @@ ${body}`;
|
|
|
3230
2677
|
}
|
|
3231
2678
|
function stateOf() {
|
|
3232
2679
|
return {
|
|
3233
|
-
|
|
2680
|
+
rows,
|
|
3234
2681
|
error
|
|
3235
2682
|
};
|
|
3236
2683
|
}
|
|
3237
|
-
function
|
|
3238
|
-
return
|
|
2684
|
+
function summaryOf() {
|
|
2685
|
+
return batchEntrySummary(stateOf());
|
|
3239
2686
|
}
|
|
3240
|
-
function
|
|
3241
|
-
return
|
|
2687
|
+
function currentLabel() {
|
|
2688
|
+
return labelOverride ?? summaryOf().label;
|
|
3242
2689
|
}
|
|
3243
2690
|
function phoneArgs() {
|
|
3244
2691
|
return {};
|
|
3245
2692
|
}
|
|
3246
2693
|
function entryHTML() {
|
|
3247
|
-
const
|
|
2694
|
+
const summary = summaryOf();
|
|
3248
2695
|
const text = activating ? "正在查新版…" : currentLabel();
|
|
3249
2696
|
const busyAttr = activating ? " disabled aria-busy=\"true\"" : "";
|
|
3250
2697
|
const themeAttr = theme === "d5-paper" ? " data-theme=\"d5-paper\"" : "";
|
|
3251
|
-
const control = variant === "badge" ?
|
|
3252
|
-
const noteHTML = note ?
|
|
3253
|
-
return
|
|
3254
|
-
<span class="dsh-upd-entry" data-variant="${variant}" data-state="${kind}"${themeAttr}>${control}${noteHTML}</span>`;
|
|
2698
|
+
const control = variant === "badge" ? "<button type=\"button\" class=\"dsh-upd-entry-dot\" " + ENTRY_ATTR + "=\"activate\" title=\"" + escapeHtml(text) + "\" aria-label=\"" + escapeHtml(text) + "\"" + busyAttr + "></button>" : "<button type=\"button\" class=\"dsh-upd-entry-btn\" " + ENTRY_ATTR + "=\"activate\"" + busyAttr + ">" + escapeHtml(text) + "</button>";
|
|
2699
|
+
const noteHTML = note ? "<span class=\"dsh-upd-entry-note\" data-dsh-upd-note=\"1\">" + escapeHtml(note) + "</span>" : "";
|
|
2700
|
+
return "<style>" + UPDATE_ENTRY_CSS + "</style>\n<span class=\"dsh-upd-entry\" data-variant=\"" + variant + "\" data-state=\"" + summary.kind + "\"" + themeAttr + ">" + control + noteHTML + "</span>";
|
|
3255
2701
|
}
|
|
3256
2702
|
function render() {
|
|
3257
2703
|
if (!mounted) return;
|
|
@@ -3263,14 +2709,15 @@ ${body}`;
|
|
|
3263
2709
|
error = failureCodeOf(isObject(reply) ? reply : null, "check-failed");
|
|
3264
2710
|
return;
|
|
3265
2711
|
}
|
|
3266
|
-
const next =
|
|
3267
|
-
if (next)
|
|
2712
|
+
const next = asRows(reply["rows"]);
|
|
2713
|
+
if (next) rows = next;
|
|
3268
2714
|
error = null;
|
|
2715
|
+
loaded = true;
|
|
3269
2716
|
}
|
|
3270
2717
|
async function refresh() {
|
|
3271
2718
|
if (!mounted) return;
|
|
3272
2719
|
try {
|
|
3273
|
-
const reply = await call(
|
|
2720
|
+
const reply = await call(phones.status, phoneArgs());
|
|
3274
2721
|
if (!mounted) return;
|
|
3275
2722
|
applyReply(reply);
|
|
3276
2723
|
} catch {
|
|
@@ -3281,7 +2728,7 @@ ${body}`;
|
|
|
3281
2728
|
}
|
|
3282
2729
|
async function checkNow() {
|
|
3283
2730
|
try {
|
|
3284
|
-
const reply = await call(
|
|
2731
|
+
const reply = await call(phones.check, phoneArgs());
|
|
3285
2732
|
if (!mounted) return;
|
|
3286
2733
|
applyReply(reply);
|
|
3287
2734
|
} catch {
|
|
@@ -3291,15 +2738,15 @@ ${body}`;
|
|
|
3291
2738
|
}
|
|
3292
2739
|
function mountPanel(mode) {
|
|
3293
2740
|
if (!mounted || panelMode !== null) return;
|
|
3294
|
-
panel =
|
|
3295
|
-
|
|
3296
|
-
prefix,
|
|
2741
|
+
panel = mountUpdateBatchPanel(panelHost, {
|
|
2742
|
+
prefix: options.prefix,
|
|
3297
2743
|
mode,
|
|
3298
2744
|
theme,
|
|
3299
2745
|
pollMs,
|
|
3300
|
-
|
|
2746
|
+
titles,
|
|
2747
|
+
onRestartRequested: options.onRestartRequested,
|
|
2748
|
+
copyText: options.copyText,
|
|
3301
2749
|
autoChangelog: options.autoChangelog,
|
|
3302
|
-
changelogMarkdown: options.changelogMarkdown ?? null,
|
|
3303
2750
|
onCloseRequested: () => close(),
|
|
3304
2751
|
call: panelCall
|
|
3305
2752
|
});
|
|
@@ -3340,23 +2787,29 @@ ${body}`;
|
|
|
3340
2787
|
}
|
|
3341
2788
|
if (!mounted) return;
|
|
3342
2789
|
if (variant === "badge" || openOn === "manual") {
|
|
3343
|
-
if (onActivate) onActivate(
|
|
3344
|
-
hasUpdate: hasUpdate(),
|
|
3345
|
-
latestVersion: snapshot?.latestVersion ?? null
|
|
3346
|
-
});
|
|
2790
|
+
if (onActivate) onActivate(summaryOf());
|
|
3347
2791
|
else openDialog();
|
|
3348
2792
|
render();
|
|
3349
2793
|
return;
|
|
3350
2794
|
}
|
|
3351
|
-
|
|
2795
|
+
const summary = summaryOf();
|
|
2796
|
+
if (openOn === "always" || summary.hasUpdate || !loaded || error) {
|
|
3352
2797
|
openDialog();
|
|
3353
2798
|
return;
|
|
3354
2799
|
}
|
|
3355
|
-
note =
|
|
2800
|
+
note = batchLedgerText({
|
|
2801
|
+
updatable: summary.updatable,
|
|
2802
|
+
installing: summary.installing,
|
|
2803
|
+
pending: summary.pending,
|
|
2804
|
+
restart: summary.restart,
|
|
2805
|
+
failed: summary.failed,
|
|
2806
|
+
skipped: summary.skipped,
|
|
2807
|
+
settled: summary.settled
|
|
2808
|
+
});
|
|
3356
2809
|
render();
|
|
3357
2810
|
}
|
|
3358
2811
|
function setTheme(next) {
|
|
3359
|
-
if (next !== "default" && next !== "archive" && next !== "d5-paper") throw new Error(
|
|
2812
|
+
if (next !== "default" && next !== "archive" && next !== "d5-paper") throw new Error("[dsh-plugin-update] 主题非法:只收 default 或 archive(d5-paper 为旧别名仍可用)(收到 " + JSON.stringify(next) + ")");
|
|
3360
2813
|
theme = normalizePanelTheme(next);
|
|
3361
2814
|
if (panel) panel.setTheme(theme);
|
|
3362
2815
|
else render();
|
|
@@ -3410,42 +2863,14 @@ ${body}`;
|
|
|
3410
2863
|
open,
|
|
3411
2864
|
close,
|
|
3412
2865
|
label: currentLabel,
|
|
2866
|
+
summary: summaryOf,
|
|
3413
2867
|
setTheme,
|
|
3414
2868
|
unmount
|
|
3415
2869
|
};
|
|
3416
2870
|
}
|
|
3417
|
-
//#endregion
|
|
3418
|
-
//#region src/install.ts
|
|
3419
|
-
/** dsh-life-pack 安装口径(P10 脚手架,P1 #2 定案单命令双包)。
|
|
3420
|
-
*
|
|
3421
|
-
* 真相(#2 真机结论):dsh plugin 是 pnpm 薄转发,add 单品等价 pnpm add,
|
|
3422
|
-
* 传递依赖落盘是;激活否:reconcile 只扫直接 dependencies,传递的 manager
|
|
3423
|
-
* 不进 bundles;pnpm 隔离布局下从 profile 解析不到它。
|
|
3424
|
-
*
|
|
3425
|
-
* 口径:任何单品落地时总管必须已在位导航。实现为单命令双包:
|
|
3426
|
-
* dsh plugin add dsh-life-pack dsh-calorie
|
|
3427
|
-
* 两者皆直接依赖,由 reconcile 按序激活。单品 package 内保留对总管的
|
|
3428
|
-
* dependencies 只作本地开发兜底,不作为单 add 即激活的依据。
|
|
3429
|
-
* 不许单卸总管:缺席时总管对应 tab 显示推荐安装并提示补装(见 nav.ts)。
|
|
3430
|
-
* 安装验收以 bundles 双含为准,另加单 add 单品后 bundles 无总管的负向断言。
|
|
3431
|
-
*/
|
|
3432
|
-
const MANAGER_PACKAGE = "dsh-life-pack";
|
|
3433
|
-
//#endregion
|
|
3434
|
-
//#region src/update-targets.ts
|
|
3435
|
-
/** 七个更新目标(总管自己 + 六个单品),薄接线唯一定义地(票 1170)。
|
|
3436
|
-
*
|
|
3437
|
-
* 包名不新开第二源:六单品取自 nav.ts 的 MANAGER_TABS,总管自己取自 install.ts。
|
|
3438
|
-
* 七个 phonePrefix 必须互不相同,否则串台。
|
|
3439
|
-
*/
|
|
3440
|
-
const MANAGER_TARGET_KEY = "life-pack";
|
|
3441
2871
|
/** 批量电话前缀:宿主与面板共用,唯一定义地(面板 mount 参数与宿主登记同源)。 */
|
|
3442
2872
|
const BATCH_PREFIX = "life";
|
|
3443
|
-
|
|
3444
|
-
key: MANAGER_TARGET_KEY,
|
|
3445
|
-
title: "爱生活",
|
|
3446
|
-
packageName: MANAGER_PACKAGE,
|
|
3447
|
-
phonePrefix: "ilife-life-pack"
|
|
3448
|
-
}, ...MANAGER_TABS.map((tab) => ({
|
|
2873
|
+
[...MANAGER_TABS.map((tab) => ({
|
|
3449
2874
|
key: tab.skill,
|
|
3450
2875
|
title: tab.title,
|
|
3451
2876
|
packageName: tab.plugin,
|
|
@@ -3453,21 +2878,12 @@ ${body}`;
|
|
|
3453
2878
|
}))];
|
|
3454
2879
|
//#endregion
|
|
3455
2880
|
//#region src/update-dialog.ts
|
|
3456
|
-
/** 面板薄包装(票 1170
|
|
2881
|
+
/** 面板薄包装(票 1170 起,浏览器侧:无 node 内建,可进 client 束;完全上游 UI,本包零自家样式)。
|
|
3457
2882
|
*
|
|
3458
|
-
*
|
|
3459
|
-
|
|
2883
|
+
* 只定死三组参数,不自建文案与样式:批量入口形态 button、皮肤 archive、打开策略沿上游缺省 always
|
|
2884
|
+
*(查完总是开批量面板;0.5.4 #49 到达,manual 桥接已删);弹窗 dialog 由入口件内置(含关闭落地);
|
|
3460
2885
|
* 轮询与更新日志沿上游缺省,中文标题沿目标表(不传 titles 覆盖)。
|
|
3461
2886
|
*/
|
|
3462
|
-
/** 总管自己那一行的电话名前缀(入口件状态源,取自目标表,不手写字面量)。 */
|
|
3463
|
-
function managerPrefix() {
|
|
3464
|
-
const row = UPDATE_TARGETS.find((target) => target.key === MANAGER_TARGET_KEY);
|
|
3465
|
-
return row !== void 0 ? row.phonePrefix : "ilife-life-pack";
|
|
3466
|
-
}
|
|
3467
|
-
/** 总管自己在批量内的插件标识(与宿主侧上游缺省 batchPrefix-key 同口径)。 */
|
|
3468
|
-
function managerPluginId() {
|
|
3469
|
-
return "life-life-pack";
|
|
3470
|
-
}
|
|
3471
2887
|
/** 把 RpcCallFace 收成面板要的一参形状:上游回包原样透传(含失败回包的 errorKind 与 diag)。
|
|
3472
2888
|
*
|
|
3473
2889
|
* 宿主电话表把上游回包整体装进回执 value(成功失败皆如此,只有宿主级故障才走外层失败信封),
|
|
@@ -3514,29 +2930,18 @@ ${body}`;
|
|
|
3514
2930
|
};
|
|
3515
2931
|
};
|
|
3516
2932
|
}
|
|
3517
|
-
/**
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
2933
|
+
/** 挂批量入口(一颗按钮看七家聚合,弹窗 dialog 由入口件内置,关闭落地自带)。
|
|
2934
|
+
*
|
|
2935
|
+
* 0.5.4 #49 到达:`prefix: life` 直调批量五电话,徽标与面板总账同一份数法;manual 桥接与容器事件同步已整段删除。
|
|
2936
|
+
*/
|
|
2937
|
+
function mountLifeBatchEntry(container, call, overrides) {
|
|
2938
|
+
return mountUpdateBatchEntry(container, {
|
|
2939
|
+
prefix: BATCH_PREFIX,
|
|
3522
2940
|
call,
|
|
3523
2941
|
variant: "button",
|
|
3524
|
-
openOn: "manual",
|
|
3525
2942
|
theme: "archive",
|
|
3526
2943
|
autoCheck: overrides?.autoCheck ?? "mount",
|
|
3527
|
-
label: overrides?.label
|
|
3528
|
-
onActivate: () => {
|
|
3529
|
-
onOpen();
|
|
3530
|
-
}
|
|
3531
|
-
});
|
|
3532
|
-
}
|
|
3533
|
-
/** 挂批量面板(内嵌形态进自家弹窗壳,离开时 unmount 只停轮询)。 */
|
|
3534
|
-
function mountLifeBatchPanel(container, call) {
|
|
3535
|
-
return mountUpdateBatchPanel(container, {
|
|
3536
|
-
prefix: BATCH_PREFIX,
|
|
3537
|
-
call,
|
|
3538
|
-
theme: "archive",
|
|
3539
|
-
mode: "embedded"
|
|
2944
|
+
label: overrides?.label
|
|
3540
2945
|
});
|
|
3541
2946
|
}
|
|
3542
2947
|
//#endregion
|
|
@@ -5327,48 +4732,13 @@ ${body}`;
|
|
|
5327
4732
|
display: "inline-flex",
|
|
5328
4733
|
color: "var(--dsw-alias-label-secondary, #9a9a9a)"
|
|
5329
4734
|
},
|
|
5330
|
-
/** 更新入口挂点:只占位,按钮本体由上游入口件渲染(票 1170
|
|
4735
|
+
/** 更新入口挂点:只占位,按钮本体由上游入口件渲染(票 1170);批量弹窗壳亦由上游提供,本包零自家样式。 */
|
|
5331
4736
|
updateEntrySlot: {
|
|
5332
4737
|
display: "inline-flex",
|
|
5333
4738
|
alignItems: "center"
|
|
5334
|
-
},
|
|
5335
|
-
/** 批量弹窗遮罩(自家壳:颜色走主题变量,按钮复用 interactionCss 同一缝)。 */
|
|
5336
|
-
updateBackdrop: {
|
|
5337
|
-
position: "fixed",
|
|
5338
|
-
inset: 0,
|
|
5339
|
-
display: "flex",
|
|
5340
|
-
alignItems: "center",
|
|
5341
|
-
justifyContent: "center",
|
|
5342
|
-
padding: 16,
|
|
5343
|
-
background: "rgba(0, 0, 0, 0.45)",
|
|
5344
|
-
zIndex: 1e3
|
|
5345
|
-
},
|
|
5346
|
-
updateBox: {
|
|
5347
|
-
position: "relative",
|
|
5348
|
-
width: "min(720px, 92vw)",
|
|
5349
|
-
maxHeight: "84vh",
|
|
5350
|
-
overflow: "auto",
|
|
5351
|
-
borderRadius: 12,
|
|
5352
|
-
border: "1px solid var(--dsw-alias-border-l1, rgba(128,128,128,.35))",
|
|
5353
|
-
background: "var(--dsw-alias-bg-layer-1, #232324)",
|
|
5354
|
-
color: "var(--dsw-alias-label-primary, inherit)",
|
|
5355
|
-
padding: "12px 12px 16px"
|
|
5356
|
-
},
|
|
5357
|
-
updateClose: {
|
|
5358
|
-
position: "sticky",
|
|
5359
|
-
top: 0,
|
|
5360
|
-
float: "right",
|
|
5361
|
-
marginLeft: 8,
|
|
5362
|
-
border: "1px solid var(--dsw-alias-border-l1, rgba(128,128,128,.35))",
|
|
5363
|
-
background: "transparent",
|
|
5364
|
-
color: "var(--dsw-alias-label-primary, inherit)",
|
|
5365
|
-
borderRadius: 999,
|
|
5366
|
-
padding: "4px 12px",
|
|
5367
|
-
fontSize: 13,
|
|
5368
|
-
cursor: "pointer"
|
|
5369
4739
|
}
|
|
5370
4740
|
};
|
|
5371
|
-
/** 更新区(票 1170
|
|
4741
|
+
/** 更新区(票 1170 薄接线,完全上游 UI):标题行挂上游入口按钮,点开即上游 dialog 七目标批量面板;缺席页签仍显示静态推荐,不进批量 targets。 */
|
|
5372
4742
|
/** 标签解析(resolveSlotLabel 同形:thunk 跟活,无则空字串;见 slots lib:27-29)。 */
|
|
5373
4743
|
function resolveLabel(label) {
|
|
5374
4744
|
if (typeof label === "function") return label();
|
|
@@ -5421,7 +4791,7 @@ ${body}`;
|
|
|
5421
4791
|
}, react.createElement("span", { style: S.morePkg }, row.pkg), react.createElement("span", { style: S.moreDesc }, row.desc), react.createElement("span", { style: S.moreIcon }, react.createElement(ExternalIcon, null)))));
|
|
5422
4792
|
}
|
|
5423
4793
|
/** 版本胶囊那一行字:只在这里拼一次,屏上与用例读的是同一串。 */
|
|
5424
|
-
const MANAGER_VERSION_TEXT = "dsh-life-pack · 0.3.
|
|
4794
|
+
const MANAGER_VERSION_TEXT = "dsh-life-pack · 0.3.41";
|
|
5425
4795
|
/** 爱生活面板:总设置区 + 检查更新(七家)+ 爱生活页签条(slot 驱动)+ 技能设置页投影/缺席卡。 */
|
|
5426
4796
|
function LifePackSection(props) {
|
|
5427
4797
|
const tabsId = react.useId();
|
|
@@ -5440,40 +4810,18 @@ ${body}`;
|
|
|
5440
4810
|
})), Object.fromEntries(Object.entries(health.rows).map(([id, row]) => [id, row.report ?? void 0]))), [rows, health.rows]);
|
|
5441
4811
|
const lightOf = (id) => lights.find((light) => light.id === id);
|
|
5442
4812
|
const [activeId, setActiveId] = react.useState(void 0);
|
|
5443
|
-
/**
|
|
5444
|
-
const [batchOpen, setBatchOpen] = react.useState(false);
|
|
4813
|
+
/** 批量入口挂载位(一颗按钮看七家聚合;0.5.4 #49 到达,弹窗 dialog 由入口件内置,开关态亦归上游)。 */
|
|
5445
4814
|
const entryRef = react.useRef(null);
|
|
5446
|
-
const dialogRef = react.useRef(null);
|
|
5447
4815
|
const callReady = props.getCall() !== null;
|
|
5448
4816
|
/** 入口件挂载:连接后到才挂(取用器现取),卸载即 unmount(只停入口轮询)。 */
|
|
5449
4817
|
react.useEffect(() => {
|
|
5450
4818
|
const mount = entryRef.current;
|
|
5451
4819
|
if (mount === null || !callReady) return;
|
|
5452
|
-
const entry =
|
|
5453
|
-
setBatchOpen(true);
|
|
5454
|
-
});
|
|
4820
|
+
const entry = mountLifeBatchEntry(mount, managerCallAdapter(props.getCall()));
|
|
5455
4821
|
return () => {
|
|
5456
4822
|
entry.unmount();
|
|
5457
4823
|
};
|
|
5458
4824
|
}, [callReady]);
|
|
5459
|
-
/** 批量面板挂载:弹窗开才挂,关即 unmount(只停轮询,宿主侧安装继续跑)。 */
|
|
5460
|
-
react.useEffect(() => {
|
|
5461
|
-
const mount = dialogRef.current;
|
|
5462
|
-
if (mount === null || !batchOpen || !callReady) return;
|
|
5463
|
-
const panel = mountLifeBatchPanel(mount, managerCallAdapter(props.getCall()));
|
|
5464
|
-
return () => {
|
|
5465
|
-
panel.unmount();
|
|
5466
|
-
};
|
|
5467
|
-
}, [batchOpen, callReady]);
|
|
5468
|
-
function closeBatch() {
|
|
5469
|
-
setBatchOpen(false);
|
|
5470
|
-
}
|
|
5471
|
-
function onDialogKeyDown(event) {
|
|
5472
|
-
if (event.key === "Escape") {
|
|
5473
|
-
event.stopPropagation();
|
|
5474
|
-
setBatchOpen(false);
|
|
5475
|
-
}
|
|
5476
|
-
}
|
|
5477
4825
|
const [visitedIds, setVisitedIds] = react.useState(() => /* @__PURE__ */ new Set());
|
|
5478
4826
|
const active = MANAGER_TABS.some((t) => t.plugin === activeId) ? activeId : MANAGER_TABS[0].plugin;
|
|
5479
4827
|
react.useEffect(() => {
|
|
@@ -5707,21 +5055,7 @@ ${body}`;
|
|
|
5707
5055
|
const reco = recoFor(tab);
|
|
5708
5056
|
return react.createElement("div", { style: S.reco }, reco.hint, react.createElement("span", { style: S.cmd }, reco.installCmd));
|
|
5709
5057
|
})());
|
|
5710
|
-
}),
|
|
5711
|
-
role: "dialog",
|
|
5712
|
-
"aria-modal": "true",
|
|
5713
|
-
"aria-label": "批量更新",
|
|
5714
|
-
style: S.updateBackdrop,
|
|
5715
|
-
onKeyDown: onDialogKeyDown
|
|
5716
|
-
}, react.createElement("style", { "data-ilife-interaction": "t1" }, interactionCss()), react.createElement("div", { style: S.updateBox }, react.createElement("button", {
|
|
5717
|
-
type: "button",
|
|
5718
|
-
"data-ilife-press": "",
|
|
5719
|
-
style: S.updateClose,
|
|
5720
|
-
"aria-label": "关闭更新面板(批量推进在宿主侧继续跑)",
|
|
5721
|
-
onClick: closeBatch
|
|
5722
|
-
}, "关闭"), react.createElement("div", { ref: (element) => {
|
|
5723
|
-
dialogRef.current = element;
|
|
5724
|
-
} }))) : null, react.createElement(MorePluginsCard, null));
|
|
5058
|
+
}), react.createElement(MorePluginsCard, null));
|
|
5725
5059
|
}
|
|
5726
5060
|
function apply(ctx) {
|
|
5727
5061
|
const getCall = () => ctx.connection?.rpc?.call ?? null;
|