dsh-free-search 0.4.37 → 0.4.38

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/lib/client.js CHANGED
@@ -116,6 +116,7 @@ window.__ModuleLoader__.load({
116
116
  cacheTtlHint: "0 关闭缓存,最长 5 分钟。缩短可加快时效,延长可防限流、省额度。",
117
117
  unavailable: "设置不可用 —— free-search 桥接未暴露。",
118
118
  saveFailed: "保存失败",
119
+ saveFailedDetail: (d) => `保存失败:${d}`,
119
120
  testing: "测试中…",
120
121
  testEngine: "测试引擎",
121
122
  useBing: "恢复 Bing 默认",
@@ -183,6 +184,7 @@ window.__ModuleLoader__.load({
183
184
  cacheTtlHint: "0 disables caching, max 5 minutes. Lower = fresher results, higher = less rate-limiting / fewer credits used.",
184
185
  unavailable: "Settings unavailable — the free-search bridge is not exposed.",
185
186
  saveFailed: "save failed",
187
+ saveFailedDetail: (d) => `save failed: ${d}`,
186
188
  testing: "Testing…",
187
189
  testEngine: "Test engine",
188
190
  useBing: "Use Bing default",
@@ -225,7 +227,7 @@ window.__ModuleLoader__.load({
225
227
  };
226
228
  const tt = (lang) => I18N[lang === "en" ? "en" : "zh"];
227
229
  // 当前插件版本(与 lib/index.js 的 PLUGIN_VERSION 保持一致)
228
- const PLUGIN_VERSION = "0.4.37";
230
+ const PLUGIN_VERSION = "0.4.38";
229
231
  const ENGINES = [
230
232
  { id: "ddg", label: "DuckDuckGo · HTML", badge: "FREE", link: "https://duckduckgo.com" },
231
233
  { id: "ddg-lite", label: "DuckDuckGo · Lite", badge: "FREE", link: "https://duckduckgo.com" },
@@ -361,6 +363,8 @@ window.__ModuleLoader__.load({
361
363
  const [dirty, setDirty] = react.useState(false);
362
364
  const [saving, setSaving] = react.useState(false);
363
365
  const [failed, setFailed] = react.useState(false);
366
+ // 保存失败明细(credentials-set / mutate 的 code+message),成功或改表单时清空
367
+ const [saveError, setSaveError] = react.useState("");
364
368
  const [testing, setTesting] = react.useState(false);
365
369
  const [testResult, setTestResult] = react.useState(null);
366
370
  const [checkingUpdate, setCheckingUpdate] = react.useState(false);
@@ -438,11 +442,14 @@ window.__ModuleLoader__.load({
438
442
  setProvider(value);
439
443
  setDirty(true);
440
444
  setFailed(false);
445
+ setSaveError("");
441
446
  };
442
447
 
443
448
  const save = async () => {
444
449
  setSaving(true);
445
450
  setFailed(false);
451
+ setSaveError("");
452
+ const errors = [];
446
453
  try {
447
454
  // key 存储分流:凭据中心(默认)走 credentials-set;设置页走 settings mutate(兼容)
448
455
  const keyFields = [
@@ -455,12 +462,15 @@ window.__ModuleLoader__.load({
455
462
  ["deepseekApiKey", deepseekKey],
456
463
  ["serpbaseApiKey", serpbaseKey],
457
464
  ];
458
- let credFailed = false;
459
465
  if (keyStorage === "credentials") {
460
466
  for (const [field, value] of keyFields) {
461
467
  if (!value.trim()) continue;
462
468
  const r = await bridgeCredentialsSet(field, value.trim());
463
- if (!r.ok) credFailed = true;
469
+ if (!r || !r.ok) {
470
+ const code = (r && r.code) || "error";
471
+ const msg = (r && r.message) || "";
472
+ errors.push(`credentials-set ${field}: ${code}${msg ? " — " + msg : ""}`);
473
+ }
464
474
  }
465
475
  }
466
476
  const ops = [{ op: "set", path: ["provider"], value: provider }];
@@ -477,16 +487,28 @@ window.__ModuleLoader__.load({
477
487
  ops.push({ op: "set", path: ["platforms"], value: platforms });
478
488
  ops.push({ op: "set", path: ["cacheTtl"], value: Math.min(Math.max(Number(cacheTtl) ?? 5, 0), 5) });
479
489
  const result = await bridgeMutate({ ns: NS, ops });
480
- if (result.ok && !credFailed) {
490
+ if (!result || !result.ok) {
491
+ const code = (result && result.code) || "error";
492
+ const msg = (result && result.message) || "";
493
+ errors.push(`mutate: ${code}${msg ? " — " + msg : ""}`);
494
+ }
495
+ if (errors.length === 0) {
481
496
  setDirty(false);
482
497
  setProvider(result.value.value.provider ?? provider);
483
498
  setFailed(false);
499
+ setSaveError("");
484
500
  load();
485
501
  } else {
502
+ const detail = errors.join("; ");
486
503
  setFailed(true);
504
+ setSaveError(detail);
505
+ console.error("[dsh-free-search] save failed:", detail);
487
506
  }
488
- } catch {
507
+ } catch (e) {
508
+ const msg = e && e.message ? e.message : String(e);
489
509
  setFailed(true);
510
+ setSaveError(`exception: ${msg}`);
511
+ console.error("[dsh-free-search] save exception:", e);
490
512
  } finally {
491
513
  setSaving(false);
492
514
  }
@@ -496,12 +518,14 @@ window.__ModuleLoader__.load({
496
518
  load();
497
519
  setDirty(false);
498
520
  setFailed(false);
521
+ setSaveError("");
499
522
  };
500
523
 
501
524
  const runTest = async () => {
502
525
  setTesting(true);
503
526
  setTestResult(null);
504
527
  setFailed(false);
528
+ setSaveError("");
505
529
  try {
506
530
  const result = await bridgeRawSearch({
507
531
  query: "DeepSeek Harness",
@@ -531,6 +555,7 @@ window.__ModuleLoader__.load({
531
555
  setCheckingUpdate(true);
532
556
  setUpdateInfo(null);
533
557
  setFailed(false);
558
+ setSaveError("");
534
559
  try {
535
560
  const result = await bridgeCheckUpdate();
536
561
  if (result.ok) {
@@ -549,6 +574,7 @@ window.__ModuleLoader__.load({
549
574
  setUpgrading(true);
550
575
  setUpdateInfo(null);
551
576
  setFailed(false);
577
+ setSaveError("");
552
578
  try {
553
579
  const response = await fetch(`${BRIDGE_PREFIX}/update`, {
554
580
  method: "POST",
@@ -581,6 +607,7 @@ window.__ModuleLoader__.load({
581
607
  setLang((prev) => (prev === "en" ? "zh" : "en"));
582
608
  setDirty(true);
583
609
  setFailed(false);
610
+ setSaveError("");
584
611
  };
585
612
 
586
613
  return react_jsx_runtime.jsx("li", {
@@ -729,6 +756,7 @@ react_jsx_runtime.jsx("div", {
729
756
  setExaKey(e.target.value);
730
757
  setDirty(true);
731
758
  setFailed(false);
759
+ setSaveError("");
732
760
  },
733
761
  }),
734
762
  react_jsx_runtime.jsx("input", {
@@ -741,6 +769,7 @@ react_jsx_runtime.jsx("div", {
741
769
  setTavilyKey(e.target.value);
742
770
  setDirty(true);
743
771
  setFailed(false);
772
+ setSaveError("");
744
773
  },
745
774
  }),
746
775
  react_jsx_runtime.jsx("input", {
@@ -753,6 +782,7 @@ react_jsx_runtime.jsx("div", {
753
782
  setKeenableKey(e.target.value);
754
783
  setDirty(true);
755
784
  setFailed(false);
785
+ setSaveError("");
756
786
  },
757
787
  }),
758
788
  react_jsx_runtime.jsx("input", {
@@ -765,6 +795,7 @@ react_jsx_runtime.jsx("div", {
765
795
  setFirecrawlKey(e.target.value);
766
796
  setDirty(true);
767
797
  setFailed(false);
798
+ setSaveError("");
768
799
  },
769
800
  }),
770
801
  react_jsx_runtime.jsx("input", {
@@ -777,6 +808,7 @@ react_jsx_runtime.jsx("div", {
777
808
  setParallelKey(e.target.value);
778
809
  setDirty(true);
779
810
  setFailed(false);
811
+ setSaveError("");
780
812
  },
781
813
  }),
782
814
  react_jsx_runtime.jsx("input", {
@@ -789,6 +821,7 @@ react_jsx_runtime.jsx("div", {
789
821
  setPerplexityKey(e.target.value);
790
822
  setDirty(true);
791
823
  setFailed(false);
824
+ setSaveError("");
792
825
  },
793
826
  }),
794
827
  react_jsx_runtime.jsx("input", {
@@ -801,6 +834,7 @@ react_jsx_runtime.jsx("div", {
801
834
  setSerpbaseKey(e.target.value);
802
835
  setDirty(true);
803
836
  setFailed(false);
837
+ setSaveError("");
804
838
  },
805
839
  }),
806
840
  react_jsx_runtime.jsx("input", {
@@ -813,6 +847,7 @@ react_jsx_runtime.jsx("div", {
813
847
  setDeepseekKey(e.target.value);
814
848
  setDirty(true);
815
849
  setFailed(false);
850
+ setSaveError("");
816
851
  },
817
852
  }),
818
853
  react_jsx_runtime.jsx("p", {
@@ -835,6 +870,7 @@ react_jsx_runtime.jsx("div", {
835
870
  setKeyStorage(e.target.value);
836
871
  setDirty(true);
837
872
  setFailed(false);
873
+ setSaveError("");
838
874
  },
839
875
  children: [
840
876
  react_jsx_runtime.jsx("option", { value: "credentials", children: t.keyStorageCred }),
@@ -875,6 +911,7 @@ react_jsx_runtime.jsx("div", {
875
911
  );
876
912
  setDirty(true);
877
913
  setFailed(false);
914
+ setSaveError("");
878
915
  },
879
916
  }),
880
917
  label,
@@ -907,6 +944,7 @@ react_jsx_runtime.jsx("div", {
907
944
  setCacheTtl(Number(e.target.value));
908
945
  setDirty(true);
909
946
  setFailed(false);
947
+ setSaveError("");
910
948
  },
911
949
  }),
912
950
  react_jsx_runtime.jsx("p", {
@@ -918,7 +956,12 @@ react_jsx_runtime.jsx("div", {
918
956
  react_jsx_runtime.jsx("div", {
919
957
  className: "dshfs-resultRow",
920
958
  children: [
921
- failed ? react_jsx_runtime.jsx("span", { className: "dshfs-failed", children: t.saveFailed }) : null,
959
+ failed
960
+ ? react_jsx_runtime.jsx("span", {
961
+ className: "dshfs-failed",
962
+ children: saveError ? t.saveFailedDetail(saveError) : t.saveFailed,
963
+ })
964
+ : null,
922
965
  testResult
923
966
  ? react_jsx_runtime.jsx("span", {
924
967
  className: testResult.ok ? "dshfs-testOk" : "dshfs-failed",
@@ -1041,6 +1084,7 @@ react_jsx_runtime.jsx("div", {
1041
1084
  setProvider("bing");
1042
1085
  setDirty(true);
1043
1086
  setFailed(false);
1087
+ setSaveError("");
1044
1088
  },
1045
1089
  disabled: saving || !ready || provider === "bing",
1046
1090
  children: t.useBing,
package/lib/index.js CHANGED
@@ -55,7 +55,7 @@ const FREE_ENGINES = ["ddg", "ddg-lite", "bing", "searxng", "anysearch"];
55
55
  const ALL_ENGINES = ["ddg", "ddg-lite", "bing", "searxng", "anysearch", "exa", "tavily", "keenable", "firecrawl", "parallel", "perplexity", "serpbase", "deepseek-official"];
56
56
 
57
57
  // 当前插件版本(发布时与 package.json 同步)
58
- const PLUGIN_VERSION = "0.4.37";
58
+ const PLUGIN_VERSION = "0.4.38";
59
59
  // 检查更新的 npm registry 元数据地址(dsh-free-search 是 npmjs 上的公开包)
60
60
  const NPM_REGISTRY_URL = "https://registry.npmjs.org/dsh-free-search/latest";
61
61
  const PLUGIN_NPM_URL = "https://www.npmjs.com/package/dsh-free-search";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-free-search",
3
- "version": "0.4.37",
3
+ "version": "0.4.38",
4
4
  "description": "Free web search for DeepSeek Harness: 13 engines (Bing/DuckDuckGo/AnySearch/SearXNG/Exa/Tavily/Keenable/Firecrawl/Parallel keyless; Perplexity/SerpBase/DeepSeek with key) + time filtering + platform search + web_fetch, with web settings UI.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",