dsh-plugin-pack 1.0.2 → 1.0.3

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.
Files changed (3) hide show
  1. package/client.js +32 -15
  2. package/lib/export.js +10 -2
  3. package/package.json +1 -1
package/client.js CHANGED
@@ -890,7 +890,11 @@ window.__ModuleLoader__.load({ id: 'dsh-plugin-pack', factory: (require) => {
890
890
  state.error ? h(Alert, { kind: 'err' }, state.error) : null,
891
891
  busy ? h('div', { className: 'pp-empty' }, h(Spinner, { label: translate('loading') })) : null,
892
892
  !busy &&
893
- state.items.map((item, index) =>
893
+ state.items
894
+ // 选目录模式下不列文件:用户是在挑"导出到哪儿",
895
+ // 列出 .tgz/.zip 只会让人以为能选压缩包(实际会被当成目录名)。
896
+ .filter((item) => !pickingDir || item.dir)
897
+ .map((item, index) =>
894
898
  h(
895
899
  'div',
896
900
  {
@@ -950,20 +954,28 @@ window.__ModuleLoader__.load({ id: 'dsh-plugin-pack', factory: (require) => {
950
954
  : h('span', { className: 'pp-side' }, `${(item.size / 1048576).toFixed(1)} MiB`),
951
955
  item.dir
952
956
  ? null
953
- : h(
954
- 'button',
955
- {
956
- className: 'pp-btn sm',
957
- onClick: (event) => {
958
- event.stopPropagation();
959
- onPick(item.path);
957
+ : pickingDir
958
+ ? null
959
+ : h(
960
+ 'button',
961
+ {
962
+ className: 'pp-btn sm',
963
+ onClick: (event) => {
964
+ event.stopPropagation();
965
+ onPick(item.path);
966
+ },
960
967
  },
961
- },
962
- '选它',
963
- ),
968
+ '选它',
969
+ ),
964
970
  ),
965
971
  ),
966
- !busy && !state.items.length && !state.error ? h('div', { className: 'pp-empty' }, '空目录(这里没有子目录,也没有 zip)') : null,
972
+ !busy && !state.items.length && !state.error
973
+ ? h(
974
+ 'div',
975
+ { className: 'pp-empty' },
976
+ pickingDir ? '空目录(这里没有子目录)' : '空目录(这里没有子目录,也没有 zip)',
977
+ )
978
+ : null,
967
979
  ),
968
980
  // 底部
969
981
  h(
@@ -2174,9 +2186,14 @@ window.__ModuleLoader__.load({ id: 'dsh-plugin-pack', factory: (require) => {
2174
2186
  .catch((err) => setImportResult({ error: String(err?.message ?? err) }));
2175
2187
  return;
2176
2188
  }
2177
- // 导出:选的是目录 → 补末尾分隔符,让后端按"目录 + 自动命名"处理,
2178
- // 而不是把目录名当成 zip 文件名再加 .zip
2179
- setOut(picked.endsWith('\\') || picked.endsWith('/') ? picked : `${picked}\\`);
2189
+ // 导出:只有选中的是「目录」才补末尾分隔符,让后端按"目录 + 自动命名"处理。
2190
+ //
2191
+ // 之前这里无条件补 `\`,导致选中 xxx.tgz 这种文件后变成 `xxx.tgz\`,
2192
+ // 后端按"末尾带分隔符 → 当目录"处理,又拼了一次默认文件名,
2193
+ // 结果在名为 xxx.tgz 的文件夹里塞了个新 zip —— 路径看着像文件其实是目录。
2194
+ // 所以带扩展名的就当文件,原样保留。
2195
+ const looksLikeFile = /\.[a-z0-9]{2,8}$/i.test(picked);
2196
+ setOut(looksLikeFile || picked.endsWith('\\') || picked.endsWith('/') ? picked : `${picked}\\`);
2180
2197
  },
2181
2198
  }),
2182
2199
  // 重名冲突弹窗:叠在最上层
package/lib/export.js CHANGED
@@ -373,8 +373,16 @@ export function resolveOutFile(raw, home, profileLabel, stampText, options = {})
373
373
  stat = null;
374
374
  }
375
375
  if (stat?.isDirectory()) return path.join(target, fallbackName);
376
- // 末尾带分隔符:用户明确指了"这个目录",即使它还不存在
377
- if (/[\\/]$/.test(text)) return path.join(target, fallbackName);
376
+ // 末尾带分隔符:用户明确指了"这个目录",即使它还不存在。
377
+ // 但 `xxx.tgz\` 这种是误操作(把文件当目录)——
378
+ // 去掉分隔符后如果像个带扩展名的文件名,就按文件处理,别再拼一层。
379
+ if (/[\\/]$/.test(text)) {
380
+ const trimmed = text.replace(/[\\/]+$/, '');
381
+ if (/\.[a-z0-9]{2,8}$/i.test(path.basename(trimmed))) {
382
+ return path.resolve(trimmed);
383
+ }
384
+ return path.join(target, fallbackName);
385
+ }
378
386
  if (stat?.isFile()) return target;
379
387
  // 已经带了本类型该有的扩展名就原样;否则补上
380
388
  if (target.toLowerCase().endsWith(ext)) return target;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-pack",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "DeepSeek Harness 插件整合包:一键把当前 profile 的第三方插件连依赖和配置导出成 zip(内部每个插件是标准 npm tgz),换机/换 profile 拖进去就能还原。",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",