dshmarket 1.27.0 → 1.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/client.js +61 -25
- package/client/client.js.map +1 -1
- package/lib/registry.js +25 -1
- package/lib/routes.js +5 -3
- package/lib/themes.js +2 -2
- package/lib/types/registry.d.ts +9 -1
- package/package.json +1 -1
- package/src/client/MarketSection.tsx +22 -13
- package/src/client/SettingsCard.tsx +16 -10
- package/src/client/locales.ts +2 -2
- package/src/client/market-data.ts +45 -4
- package/src/registry.ts +26 -2
- package/src/routes.ts +5 -3
- package/src/themes.ts +2 -2
package/client/client.js
CHANGED
|
@@ -35,7 +35,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
35
35
|
/** zh/en dictionaries for the Market settings section and install toast. */
|
|
36
36
|
const zh = {
|
|
37
37
|
nav: "插件市场",
|
|
38
|
-
setCardDesc: "
|
|
38
|
+
setCardDesc: "查看插件市场版本与设置。",
|
|
39
39
|
setSelfUpToDate: "已是最新版本",
|
|
40
40
|
setSelfUpdateReady: "有新版本",
|
|
41
41
|
setSelfUpdateHint: "更新会下载新版本,重启后生效。",
|
|
@@ -479,7 +479,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
479
479
|
};
|
|
480
480
|
const en = {
|
|
481
481
|
nav: "Plugin Market",
|
|
482
|
-
setCardDesc: "
|
|
482
|
+
setCardDesc: "View the plugin market version and settings.",
|
|
483
483
|
setSelfUpToDate: "Up to date",
|
|
484
484
|
setSelfUpdateReady: "New version available:",
|
|
485
485
|
setSelfUpdateHint: "Updating downloads the new version; it takes effect after a restart.",
|
|
@@ -923,6 +923,28 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
923
923
|
};
|
|
924
924
|
//#endregion
|
|
925
925
|
//#region src/client/market-data.ts
|
|
926
|
+
/** Category ids for one entry, de-duplicated in declaration order. */
|
|
927
|
+
function pluginCategories(plugin) {
|
|
928
|
+
const values = Array.isArray(plugin.category) ? plugin.category : [plugin.category];
|
|
929
|
+
const categories = [];
|
|
930
|
+
const seen = /* @__PURE__ */ new Set();
|
|
931
|
+
for (const value of values) {
|
|
932
|
+
if (typeof value !== "string" || value === "" || seen.has(value)) continue;
|
|
933
|
+
seen.add(value);
|
|
934
|
+
categories.push(value);
|
|
935
|
+
}
|
|
936
|
+
return categories;
|
|
937
|
+
}
|
|
938
|
+
/**
|
|
939
|
+
* Add active profile Bundles as presence-only catalog entries.
|
|
940
|
+
*
|
|
941
|
+
* The returned map is for catalog matching only. Update and uninstall flows
|
|
942
|
+
* must keep using the dependency-only map because a Bundle supplied by the
|
|
943
|
+
* dsh installation is not owned by the profile package manager.
|
|
944
|
+
*/
|
|
945
|
+
function installedForCatalog(installed, bundles) {
|
|
946
|
+
return Object.fromEntries([...bundles.map((name) => [name, "*"]), ...Object.entries(installed)]);
|
|
947
|
+
}
|
|
926
948
|
function groupSwitchState(members, disabled) {
|
|
927
949
|
const list = members ?? [];
|
|
928
950
|
if (list.length === 0) return "empty";
|
|
@@ -976,18 +998,24 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
976
998
|
}
|
|
977
999
|
/**
|
|
978
1000
|
* The discover list: category filter, then the published-within window, then
|
|
979
|
-
* search across name / owner / localized description
|
|
1001
|
+
* search across name / owner / localized description / category ids and
|
|
1002
|
+
* localized category labels, then the selected sort.
|
|
980
1003
|
* Pure — the section renders exactly this.
|
|
981
1004
|
*/
|
|
982
1005
|
function visiblePlugins(plugins, options) {
|
|
983
1006
|
const query = options.query.trim().toLowerCase();
|
|
984
1007
|
const list = plugins.filter((p) => {
|
|
985
1008
|
if (isMarketItself(p)) return false;
|
|
986
|
-
|
|
1009
|
+
const categories = pluginCategories(p);
|
|
1010
|
+
if (options.category !== "all" && !categories.includes(options.category)) return false;
|
|
987
1011
|
if (options.sinceDays !== void 0 && !withinDays(p.added, options.sinceDays)) return false;
|
|
988
1012
|
if (query === "") return true;
|
|
989
1013
|
const desc = p.description && (p.description[options.lang] || p.description.en) || "";
|
|
990
|
-
|
|
1014
|
+
const categoryMatches = categories.some((category) => {
|
|
1015
|
+
if (category.toLowerCase().includes(query)) return true;
|
|
1016
|
+
return Object.values(options.categories?.[category] ?? {}).some((label) => typeof label === "string" && label.toLowerCase().includes(query));
|
|
1017
|
+
});
|
|
1018
|
+
return p.name.toLowerCase().includes(query) || p.owner.toLowerCase().includes(query) || desc.toLowerCase().includes(query) || categoryMatches;
|
|
991
1019
|
});
|
|
992
1020
|
const hasDownloads = (p) => typeof p.downloads === "number";
|
|
993
1021
|
if (options.sort === "downloads-desc") return [...list].sort((a, b) => {
|
|
@@ -1010,7 +1038,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
1010
1038
|
}
|
|
1011
1039
|
/** The themes tab listing: theme category only, most-starred first. */
|
|
1012
1040
|
function themePlugins(plugins) {
|
|
1013
|
-
return plugins.filter((p) => p.
|
|
1041
|
+
return plugins.filter((p) => pluginCategories(p).includes("theme")).sort((a, b) => (b.stars || 0) - (a.stars || 0));
|
|
1014
1042
|
}
|
|
1015
1043
|
/**
|
|
1016
1044
|
* Category chip order: collapsed with an active non-'all' chip that would
|
|
@@ -5278,6 +5306,8 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
5278
5306
|
}).catch(() => {});
|
|
5279
5307
|
fetch("/dsh-market/updates" + (force === true ? "?force=1" : ""), { cache: "no-store" }).then((res) => res.json()).then((body) => setUpdates(body.updates || {})).catch(() => {});
|
|
5280
5308
|
}, []);
|
|
5309
|
+
/** Active Bundles count as installed in Discover without becoming package-manager targets. */
|
|
5310
|
+
const catalogInstalled = (0, react.useMemo)(() => installedForCatalog(installed, installedBundles), [installed, installedBundles]);
|
|
5281
5311
|
(0, react.useMemo)(() => new Set(disabledNames), [disabledNames]);
|
|
5282
5312
|
/** Effective switch state: market disable list ∪ user-patch-layer disables. */
|
|
5283
5313
|
const effectiveDisabledSet = (0, react.useMemo)(() => /* @__PURE__ */ new Set([...disabledNames, ...patchDisabledNames]), [disabledNames, patchDisabledNames]);
|
|
@@ -5468,6 +5498,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
5468
5498
|
category: cat,
|
|
5469
5499
|
query: q,
|
|
5470
5500
|
lang,
|
|
5501
|
+
categories: data.categories,
|
|
5471
5502
|
sort: `${sortField}-${sortDir}`,
|
|
5472
5503
|
sinceDays: timeRange === "all" ? void 0 : TIME_RANGE_DAYS[timeRange]
|
|
5473
5504
|
}), [
|
|
@@ -5491,6 +5522,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
5491
5522
|
category: "theme",
|
|
5492
5523
|
query: qThemes,
|
|
5493
5524
|
lang,
|
|
5525
|
+
categories: data.categories,
|
|
5494
5526
|
sort: `${themeSortField}-${themeSortDir}`,
|
|
5495
5527
|
sinceDays: themeTimeRange === "all" ? void 0 : TIME_RANGE_DAYS[themeTimeRange]
|
|
5496
5528
|
}), [
|
|
@@ -5582,7 +5614,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
5582
5614
|
}))).then(({ status, body }) => {
|
|
5583
5615
|
setBusyUrl(null);
|
|
5584
5616
|
sessionStorage.removeItem("dshm-pending");
|
|
5585
|
-
if (status === 200 && body.ok && body.hot && plugin.
|
|
5617
|
+
if (status === 200 && body.ok && body.hot && pluginCategories(plugin).includes("theme")) {
|
|
5586
5618
|
sessionStorage.setItem("dshm-toast", JSON.stringify([plugin.name]));
|
|
5587
5619
|
sessionStorage.setItem("dshm-tab", "themes");
|
|
5588
5620
|
location.reload();
|
|
@@ -6357,7 +6389,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
6357
6389
|
const pluginCard = (p) => {
|
|
6358
6390
|
const desc = p.description && (p.description[lang] || p.description.en) || "";
|
|
6359
6391
|
const done = doneUrls.includes(p.url) || hotUrls.includes(p.url);
|
|
6360
|
-
const already = isInstalled(p,
|
|
6392
|
+
const already = isInstalled(p, catalogInstalled, repoIdentities, data?.plugins, repoHints);
|
|
6361
6393
|
const busy = busyUrl === p.url;
|
|
6362
6394
|
const replacement = replacementOf(p);
|
|
6363
6395
|
const record = recordForUrl(records, p.url);
|
|
@@ -6473,10 +6505,10 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
6473
6505
|
}),
|
|
6474
6506
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6475
6507
|
className: Market_module_css_default.foot,
|
|
6476
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6508
|
+
children: [pluginCategories(p).map((category) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6477
6509
|
className: Market_module_css_default.tag,
|
|
6478
|
-
children: data.categories[
|
|
6479
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: Market_module_css_default.grow })]
|
|
6510
|
+
children: data.categories[category] && (data.categories[category][lang] || data.categories[category].en) || category
|
|
6511
|
+
}, category)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: Market_module_css_default.grow })]
|
|
6480
6512
|
}),
|
|
6481
6513
|
busy && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6482
6514
|
className: Market_module_css_default.progress,
|
|
@@ -6818,7 +6850,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
6818
6850
|
if (data === null) return names;
|
|
6819
6851
|
for (const [name, spec] of Object.entries(installed)) {
|
|
6820
6852
|
const entry = entryForDep(data.plugins, name, String(spec), repoIdentities[name], repoHints[name]);
|
|
6821
|
-
if (entry !== void 0 && entry.
|
|
6853
|
+
if (entry !== void 0 && pluginCategories(entry).includes("theme")) names.add(name);
|
|
6822
6854
|
}
|
|
6823
6855
|
return names;
|
|
6824
6856
|
}, [
|
|
@@ -8136,7 +8168,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
8136
8168
|
setTab("discover");
|
|
8137
8169
|
},
|
|
8138
8170
|
children: t("viewReplacement")
|
|
8139
|
-
}), !isInstalled(replacement,
|
|
8171
|
+
}), !isInstalled(replacement, catalogInstalled, repoIdentities, data?.plugins, repoHints) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
8140
8172
|
variant: "outline",
|
|
8141
8173
|
size: "sm",
|
|
8142
8174
|
onClick: () => setConfirming(replacement),
|
|
@@ -8269,10 +8301,10 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
8269
8301
|
})
|
|
8270
8302
|
}),
|
|
8271
8303
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: Market_module_css_default.grow }),
|
|
8272
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8304
|
+
pluginCategories(confirming).map((category) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8273
8305
|
className: Market_module_css_default.tag,
|
|
8274
|
-
children: data.categories[
|
|
8275
|
-
})
|
|
8306
|
+
children: data.categories[category] && (data.categories[category][lang] || data.categories[category].en) || category
|
|
8307
|
+
}, category))
|
|
8276
8308
|
]
|
|
8277
8309
|
}),
|
|
8278
8310
|
confirming.added && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -8484,8 +8516,10 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
8484
8516
|
/**
|
|
8485
8517
|
* The market's card on the plugin configuration page (dsh >= 0.1.0-rc.7).
|
|
8486
8518
|
*
|
|
8487
|
-
* It manages the market ITSELF — version, update, remove
|
|
8488
|
-
*
|
|
8519
|
+
* It manages the market ITSELF — version, update, remove — when the current
|
|
8520
|
+
* profile owns the dependency. A host-provided market keeps only its version
|
|
8521
|
+
* display and download-region controls. This page is where a user goes to deal
|
|
8522
|
+
* with a plugin,
|
|
8489
8523
|
* and "which version am I on / update it / get rid of it" is the part of
|
|
8490
8524
|
* that anybody can act on without knowing how DSH is put together.
|
|
8491
8525
|
*
|
|
@@ -8558,7 +8592,8 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
8558
8592
|
channels: offered.length > 0 ? offered : ["stable", "beta"],
|
|
8559
8593
|
region: asRegion(body.region) ?? "global",
|
|
8560
8594
|
regions: regions.length > 0 ? regions : REGIONS,
|
|
8561
|
-
regionAuto: body.regionAuto === true
|
|
8595
|
+
regionAuto: body.regionAuto === true,
|
|
8596
|
+
selfManaged: body.selfManaged !== false
|
|
8562
8597
|
};
|
|
8563
8598
|
}
|
|
8564
8599
|
function readUpdate(own) {
|
|
@@ -8614,7 +8649,8 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
8614
8649
|
channels: ["stable", "beta"],
|
|
8615
8650
|
region: "global",
|
|
8616
8651
|
regions: REGIONS,
|
|
8617
|
-
regionAuto: false
|
|
8652
|
+
regionAuto: false,
|
|
8653
|
+
selfManaged: true
|
|
8618
8654
|
});
|
|
8619
8655
|
}
|
|
8620
8656
|
try {
|
|
@@ -8757,7 +8793,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
8757
8793
|
}, [post, t]);
|
|
8758
8794
|
/** One label + hint block with an optional action, the host's row shape. */
|
|
8759
8795
|
const row = (label, hint, action) => (0, react.createElement)("div", { className: Market_module_css_default.setRow }, (0, react.createElement)("div", { className: Market_module_css_default.setLabelBox }, (0, react.createElement)("div", { className: Market_module_css_default.setLabel }, label), (0, react.createElement)("div", { className: Market_module_css_default.setHint }, hint)), action);
|
|
8760
|
-
const body = phase === "removed" ? row(t("setSelfRemoved"), t("setSelfRemovedHint"), null) : (0, react.createElement)(react.Fragment, null, row(update?.updateAvailable === true && update.latest !== null ? `${t("setSelfUpdateReady")} ${update.latest}` : update?.channelSwitch != null ? `${t("setChannelSwitch")} ${update.channelSwitch}` : t("setSelfUpToDate"), phase === "updated" ? t("setSelfUpdatedHint") : update?.channelSwitch != null ? t("setChannelSwitchHint") : update?.updateAvailable === true ? t("setSelfUpdateHint") : t("setSelfUpToDateHint"), phase === "updated" ? null : update?.updateAvailable === true ? (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
8796
|
+
const body = phase === "removed" ? row(t("setSelfRemoved"), t("setSelfRemovedHint"), null) : (0, react.createElement)(react.Fragment, null, status?.selfManaged === true ? row(update?.updateAvailable === true && update.latest !== null ? `${t("setSelfUpdateReady")} ${update.latest}` : update?.channelSwitch != null ? `${t("setChannelSwitch")} ${update.channelSwitch}` : t("setSelfUpToDate"), phase === "updated" ? t("setSelfUpdatedHint") : update?.channelSwitch != null ? t("setChannelSwitchHint") : update?.updateAvailable === true ? t("setSelfUpdateHint") : t("setSelfUpToDateHint"), phase === "updated" ? null : update?.updateAvailable === true ? (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
8761
8797
|
variant: "primary",
|
|
8762
8798
|
size: "sm",
|
|
8763
8799
|
disabled: busy,
|
|
@@ -8767,7 +8803,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
8767
8803
|
size: "sm",
|
|
8768
8804
|
disabled: busy,
|
|
8769
8805
|
onClick: () => onUpdate()
|
|
8770
|
-
}, t("setChannelSwitch")) : null), row(t("setChannel"), t(CHANNEL_HINT[status
|
|
8806
|
+
}, t("setChannelSwitch")) : null) : null, status?.selfManaged === true ? row(t("setChannel"), t(CHANNEL_HINT[status.channel]), (0, react.createElement)("div", { className: Market_module_css_default.setSeg }, (status?.channels ?? ["stable", "beta"]).map((id) => (0, react.createElement)("button", {
|
|
8771
8807
|
key: id,
|
|
8772
8808
|
type: "button",
|
|
8773
8809
|
className: status?.channel === id ? `${Market_module_css_default.setSegBtn} ${Market_module_css_default.setSegOn}` : Market_module_css_default.setSegBtn,
|
|
@@ -8776,7 +8812,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
8776
8812
|
onClick: () => {
|
|
8777
8813
|
onChannel(id);
|
|
8778
8814
|
}
|
|
8779
|
-
}, t(CHANNEL_LABEL[id]))))), row(t("setRegion"), status?.regionAuto === true ? `${t(REGION_HINT[status.region])} ${t("setRegionAuto")}` : t(REGION_HINT[status?.region ?? "global"]), (0, react.createElement)("div", { className: Market_module_css_default.setSeg }, (status?.regions ?? REGIONS).map((id) => (0, react.createElement)("button", {
|
|
8815
|
+
}, t(CHANNEL_LABEL[id]))))) : null, row(t("setRegion"), status?.regionAuto === true ? `${t(REGION_HINT[status.region])} ${t("setRegionAuto")}` : t(REGION_HINT[status?.region ?? "global"]), (0, react.createElement)("div", { className: Market_module_css_default.setSeg }, (status?.regions ?? REGIONS).map((id) => (0, react.createElement)("button", {
|
|
8780
8816
|
key: id,
|
|
8781
8817
|
type: "button",
|
|
8782
8818
|
className: status?.region === id ? `${Market_module_css_default.setSegBtn} ${Market_module_css_default.setSegOn}` : Market_module_css_default.setSegBtn,
|
|
@@ -8784,7 +8820,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
8784
8820
|
onClick: () => {
|
|
8785
8821
|
onRegion(id);
|
|
8786
8822
|
}
|
|
8787
|
-
}, t(REGION_LABEL[id]))))), row(t("setSelfRemove"), t("setSelfRemoveHint"), phase === "confirming" || busy ? null : (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
8823
|
+
}, t(REGION_LABEL[id]))))), status?.selfManaged === true ? row(t("setSelfRemove"), t("setSelfRemoveHint"), phase === "confirming" || busy ? null : (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
8788
8824
|
variant: "outline",
|
|
8789
8825
|
size: "sm",
|
|
8790
8826
|
className: Market_module_css_default.setDanger,
|
|
@@ -8792,7 +8828,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
8792
8828
|
onClick: () => {
|
|
8793
8829
|
setPhase("confirming");
|
|
8794
8830
|
}
|
|
8795
|
-
}, t("setSelfRemove"))), phase === "confirming" || busy ? (0, react.createElement)("div", { className: Market_module_css_default.setConfirm }, (0, react.createElement)("div", { className: Market_module_css_default.setHint }, t("setSelfConfirm")), (0, react.createElement)("label", { className: Market_module_css_default.setCheck }, (0, react.createElement)("input", {
|
|
8831
|
+
}, t("setSelfRemove"))) : null, status?.selfManaged === true && (phase === "confirming" || busy) ? (0, react.createElement)("div", { className: Market_module_css_default.setConfirm }, (0, react.createElement)("div", { className: Market_module_css_default.setHint }, t("setSelfConfirm")), (0, react.createElement)("label", { className: Market_module_css_default.setCheck }, (0, react.createElement)("input", {
|
|
8796
8832
|
type: "checkbox",
|
|
8797
8833
|
checked: purge,
|
|
8798
8834
|
onChange: () => {
|