@huyooo/file-explorer-bridge-electron 0.4.29 → 0.4.30

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.
@@ -6,14 +6,29 @@ import { ClipboardAdapter } from '@huyooo/file-explorer-core';
6
6
  * 只负责 IPC 通信,具体实现在 @huyooo/file-explorer-core 中
7
7
  */
8
8
 
9
+ /** 媒体文件应用打开请求参数 */
10
+ interface MediaFileAppRequest {
11
+ filePath: string;
12
+ mediaType: 'image' | 'video' | 'audio';
13
+ fileUrl: string;
14
+ fileName: string;
15
+ }
9
16
  /** 文件管理器配置选项 */
10
17
  interface FileExplorerOptions {
11
18
  /** 在新窗口中打开文件夹的回调 */
12
19
  onOpenInNewWindow?: (folderPath: string) => void;
20
+ /**
21
+ * 宿主自定义媒体文件应用打开
22
+ * 设置后,bridge 不再处理专用预览宿主,而是委托宿主打开对应媒体扩展 app
23
+ */
24
+ onOpenMediaFileApp?: (request: MediaFileAppRequest) => void;
25
+ /**
26
+ * 宿主关闭指定文件对应的媒体扩展 app
27
+ * 设置后,closeMediaFileApp IPC 会调用此回调
28
+ */
29
+ onCloseMediaFileApp?: (filePath: string, mediaType: 'image' | 'video' | 'audio') => void;
13
30
  /** IPC 通道名称前缀(允许宿主自定义,避免冲突) */
14
31
  channelPrefix?: string;
15
- /** 预览窗口 IPC 通道前缀(一般不需要改) */
16
- previewChannelPrefix?: string;
17
32
  }
18
33
  interface RegisterFileExplorerOptions extends FileExplorerOptions {
19
34
  /** 注入剪贴板适配器(例如 clipboard-files) */
@@ -27,4 +42,4 @@ interface RegisterFileExplorerOptions extends FileExplorerOptions {
27
42
  */
28
43
  declare function registerFileExplorer(options?: RegisterFileExplorerOptions): void;
29
44
 
30
- export { type FileExplorerOptions, type RegisterFileExplorerOptions, registerFileExplorer };
45
+ export { type FileExplorerOptions, type MediaFileAppRequest, type RegisterFileExplorerOptions, registerFileExplorer };
@@ -1 +1 @@
1
- import{ipcMain as e,shell as n,BrowserWindow as r}from"electron";import t from"path";import{fileURLToPath as a}from"url";import s from"fs";import{readDirectory as c,readFileContent as o,readImageAsBase64 as i,writeFileContent as l,createFolder as d,createFile as u,deleteFiles as h,renameFile as m,copyFiles as w,moveFiles as y,getFileInfo as p,getSystemPath as f,getThumbnailService as g,getApplicationIcon as b,copyFilesToClipboard as P,getClipboardFiles as x,pasteFiles as v,searchFiles as F,searchFilesStream as S,compressFiles as C,extractArchive as I,isArchiveFile as T,getWatchManager as z,showFileInfo as U,openInTerminal as W,openInEditor as M,getFileType as D,formatFileSize as A,formatDateTime as $,encodeFileUrl as R,getMediaService as j}from"@huyooo/file-explorer-core";import{promises as E}from"fs";import{getPreviewHtmlPath as N}from"@huyooo/file-explorer-preview/path";var B=t.dirname(a(import.meta.url)),G=null;var L=R,O={},k=new Map;function q(a={}){O=a;const R=a.channelPrefix||"file-explorer",q=a.previewChannelPrefix||"file-explorer-preview",H=e=>`${R}:${e}`,J=e=>`${q}:${e}`,K={trashItem:async e=>{await n.trashItem(e)},openPath:async e=>{await n.openPath(e)}};e.handle(H("readDirectory"),async(e,n)=>{const r=g();return await c(n,{urlEncoder:L,getThumbnailUrl:r?e=>r.getThumbnailUrl(e):void 0})}),e.handle(H("readSystemPath"),async(e,n)=>{const r=f(n);if(!r)return[];const t=g();return await c(r,{urlEncoder:L,getThumbnailUrl:t?e=>t.getThumbnailUrl(e):void 0})}),e.handle(H("getSystemPath"),async(e,n)=>f(n)),e.handle(H("readFileContent"),async(e,n)=>await o(n)),e.handle(H("writeFileContent"),async(e,n,r)=>await l(n,r)),e.handle(H("createFolder"),async(e,n,r)=>{const a=t.join(n,r);return await d(a)}),e.handle(H("createFile"),async(e,n,r,a)=>{const s=t.join(n,r);return await u(s,a)}),e.handle(H("deleteFiles"),async(e,n)=>{const r=g();return await h(n,{adapter:K,useTrash:!0,onDeleted:e=>r?.deleteThumbnail(e)})}),e.handle(H("renameFile"),async(e,n,r)=>{const t=g();return await m(n,r,{onRenamed:e=>t?.deleteThumbnail(e)})}),e.handle(H("copyFiles"),async(e,n,r)=>await w(n,r)),e.handle(H("moveFiles"),async(e,n,r)=>await y(n,r)),e.handle(H("getFileInfo"),async(e,n)=>await p(n)),e.handle(H("readImageAsBase64"),async(e,n)=>await i(n)),e.handle(H("openPath"),async(e,r)=>{try{return await n.openPath(r),{success:!0}}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("getApplicationIcon"),async(e,n)=>await b(n)),e.handle(H("getThumbnailUrl"),async(e,n)=>{const r=g();return r?await r.getThumbnailUrl(n):null}),e.handle(H("copyFilesToClipboard"),async(e,n)=>G?await P(n,G):{success:!1,error:"剪贴板适配器未初始化"}),e.handle(H("getClipboardFiles"),async()=>G?x(G):{success:!1,error:"剪贴板适配器未初始化"}),e.handle(H("pasteFiles"),async(e,n,r)=>await v(n,r)),e.handle(H("searchFiles"),async(e,n,r,a)=>{try{const e=await F(n,r,a),s=g(),c=100,o=[];for(const n of e.slice(0,c))try{const e=await E.stat(n),r=D(n,e),a={id:n,name:t.basename(n),type:r,size:e.isDirectory()?void 0:A(e.size),dateModified:$(e.mtime),url:L(n)};if(s){const e=await s.getThumbnailUrl(n);e&&(a.thumbnailUrl=e)}o.push(a)}catch{}return{success:!0,data:{items:o,total:e.length}}}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("searchFilesStream"),async(e,n,r,a)=>{const s=g(),c=async e=>{try{const n=await E.stat(e),r=D(e,n),a={id:e,name:t.basename(e),type:r,size:n.isDirectory()?void 0:A(n.size),dateModified:$(n.mtime),url:L(e)};if(s){const n=await s.getThumbnailUrl(e);n&&(a.thumbnailUrl=n)}return a}catch{return null}};return S(n,r,async(n,r)=>{const t=[];for(const e of n){const n=await c(e);n&&t.push(n)}e.sender.send(H("searchResults"),{searchId:a,items:t,done:r})},100),{success:!0}}),e.handle(H("compressFiles"),async(e,n,r)=>{try{return await C(n,r,n=>{e.sender.send(H("compressProgress"),n)})}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("extractArchive"),async(e,n,r)=>{try{return await I(n,r,n=>{e.sender.send(H("extractProgress"),n)})}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("isArchiveFile"),async(e,n)=>T(n));const Q=new Map;e.handle(H("watchDirectory"),async(e,n,r)=>{try{const t=Q.get(r);t&&(t(),Q.delete(r));const a=z().watch(n,n=>{e.sender.send(H("watchEvent"),{watchId:r,event:n})});return Q.set(r,a),{success:!0}}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("unwatchDirectory"),async(e,n)=>{const r=Q.get(n);return r&&(r(),Q.delete(n)),{success:!0}}),e.handle(H("showFileInfo"),async(e,n)=>await U(n)),e.handle(H("openInTerminal"),async(e,n)=>await W(n)),e.handle(H("openInEditor"),async(e,n)=>await M(n)),e.handle(H("openInNewWindow"),async(e,r)=>{try{return O.onOpenInNewWindow?O.onOpenInNewWindow(r):await n.openPath(r),{success:!0}}catch(e){return{success:!1,error:String(e)}}}),e.on(H("requestWindowFocus"),e=>{const n=r.fromWebContents(e.sender);n&&!n.isFocused()&&n.focus()}),e.handle(H("mediaNeedsTranscode"),async(e,n)=>{const r=j();if(!r)return{success:!1,error:"媒体服务未初始化"};try{return{success:!0,data:await r.needsTranscode(n)}}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("mediaGetPlayableUrl"),async(e,n)=>{const r=j();if(!r)return{success:!1,error:"媒体服务未初始化"};try{return{success:!0,url:await r.getPlayableUrl(n,r=>{e.sender.send(H("mediaTranscodeProgress"),{filePath:n,progress:r})})}}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("mediaGetMetadata"),async(e,n)=>{const r=j();if(!r)return{success:!1,error:"媒体服务未初始化"};try{return{success:!0,data:await r.getMetadata(n)}}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("mediaCleanupFile"),async(e,n)=>{const r=j();if(!r)return{success:!1,error:"媒体服务未初始化"};try{return await r.cleanupFile(n),{success:!0}}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("openMediaPreviewWindow"),async(e,n,a)=>{try{const c=t.basename(n),o=j();let i;if("image"===a)i=L(n);else if(o){i=await o.getPlayableUrl(n,r=>{e.sender.send(H("mediaTranscodeProgress"),{filePath:n,progress:r})})||L(n)}else i=L(n);const l=k.get(n);if(l&&!l.isDestroyed())return l.focus(),{success:!0};const d="darwin"===process.platform,u="win32"===process.platform,h=d?38:32;let m=720,w=405,y=720,p=405;"audio"===a?(m=720,w=405,y=720,p=405):"image"===a&&(m=1e3,w=700,y=600,p=400);const f=m,g=w+h,b=y,P=p+h,x=t.join(B,"../preload/preview.cjs"),v=N();if(!s.existsSync(x))return{success:!1,error:`Preview preload not found: ${x}`};if(!s.existsSync(v))return{success:!1,error:`Preview html not found: ${v}`};const F=new r({width:f,height:g,minWidth:b,minHeight:P,title:c,modal:!1,show:!1,backgroundColor:"#27292c",resizable:!0,maximizable:!0,fullscreenable:!0,frame:!!d,titleBarStyle:d?"hiddenInset":void 0,trafficLightPosition:d?{x:12,y:12}:void 0,webPreferences:{preload:x,nodeIntegration:!1,contextIsolation:!0,sandbox:!1,webSecurity:!1}}),S=new URLSearchParams({type:a,url:encodeURIComponent(i),name:encodeURIComponent(c),platform:d?"darwin":u?"win32":"linux"});return F.loadFile(v,{search:S.toString()}),F.once("ready-to-show",()=>{F.show()}),F.on("maximize",()=>{F.webContents.send(J("maximizeChange"),!0)}),F.on("unmaximize",()=>{F.webContents.send(J("maximizeChange"),!1)}),F.on("closed",()=>{k.delete(n)}),k.set(n,F),{success:!0}}catch(e){return{success:!1,error:String(e)}}}),e.handle(H("closeMediaPreviewWindow"),async(e,n)=>{const r=k.get(n);return r&&!r.isDestroyed()&&(r.close(),k.delete(n)),{success:!0}}),e.on(J("minimize"),e=>{const n=r.fromWebContents(e.sender);n&&n.minimize()}),e.on(J("toggleMaximize"),e=>{const n=r.fromWebContents(e.sender);n&&(n.isMaximized()?n.unmaximize():n.maximize())}),e.on(J("close"),e=>{const n=r.fromWebContents(e.sender);n&&n.close()}),e.on(J("hide"),e=>{const n=r.fromWebContents(e.sender);n&&n.hide()}),e.on(J("show"),e=>{const n=r.fromWebContents(e.sender);n&&n.show()})}function H(e={}){var n;e.clipboardAdapter&&(n=e.clipboardAdapter,G=n),q(e)}export{H as registerFileExplorer};
1
+ import{ipcMain as e,shell as a,BrowserWindow as r}from"electron";import n from"path";import{fileURLToPath as t}from"url";import{readDirectory as s,readFileContent as c,readImageAsBase64 as i,writeFileContent as l,createFolder as o,createFile as d,deleteFiles as u,renameFile as h,copyFiles as y,moveFiles as p,getFileInfo as m,getSystemPath as w,getThumbnailService as g,getApplicationIcon as f,copyFilesToClipboard as b,getClipboardFiles as F,pasteFiles as P,searchFiles as T,searchFilesStream as S,compressFiles as A,extractArchive as M,isArchiveFile as U,getWatchManager as I,showFileInfo as v,openInTerminal as C,openInEditor as z,getFileType as x,formatFileSize as D,formatDateTime as N,encodeFileUrl as O,getMediaService as W}from"@huyooo/file-explorer-core";import{promises as E}from"fs";n.dirname(t(import.meta.url));var H=new Map,j=null;var G=O,R={};function $(t={}){R=t;const O=t.channelPrefix||"file-explorer",$=e=>`${O}:${e}`,q={trashItem:async e=>{await a.trashItem(e)},openPath:async e=>{await a.openPath(e)}};e.handle($("readDirectory"),async(e,a,r)=>{const n=g();return await s(a,{urlEncoder:G,includeHidden:r?.includeHidden??!0,getThumbnailUrl:n?e=>n.getThumbnailUrl(e):void 0})}),e.handle($("readSystemPath"),async(e,a)=>{const r=w(a);if(!r)return[];const n=g();return await s(r,{urlEncoder:G,includeHidden:!0,getThumbnailUrl:n?e=>n.getThumbnailUrl(e):void 0})}),e.handle($("getSystemPath"),async(e,a)=>w(a)),e.handle($("readFileContent"),async(e,a)=>await c(a)),e.handle($("writeFileContent"),async(e,a,r)=>await l(a,r)),e.handle($("createFolder"),async(e,a,r)=>{const t=n.join(a,r);return await o(t)}),e.handle($("createFile"),async(e,a,r,t)=>{const s=n.join(a,r);return await d(s,t)}),e.handle($("deleteFiles"),async(e,a)=>{const r=g();return await u(a,{adapter:q,useTrash:!0,onDeleted:e=>r?.deleteThumbnail(e)})}),e.handle($("renameFile"),async(e,a,r)=>{const n=g();return await h(a,r,{onRenamed:e=>n?.deleteThumbnail(e)})}),e.handle($("copyFiles"),async(e,a,r)=>await y(a,r)),e.handle($("moveFiles"),async(e,a,r)=>await p(a,r)),e.handle($("getFileInfo"),async(e,a)=>await m(a)),e.handle($("readImageAsBase64"),async(e,a)=>await i(a)),e.handle($("openPath"),async(e,r)=>{try{return await a.openPath(r),{success:!0}}catch(e){return{success:!1,error:String(e)}}}),e.handle($("getApplicationIcon"),async(e,a)=>await f(a)),e.handle($("getThumbnailUrl"),async(e,a)=>{const r=g();return r?await r.getThumbnailUrl(a):null}),e.handle($("copyFilesToClipboard"),async(e,a)=>j?await b(a,j):{success:!1,error:"剪贴板适配器未初始化"}),e.handle($("getClipboardFiles"),async()=>j?F(j):{success:!1,error:"剪贴板适配器未初始化"}),e.handle($("pasteFiles"),async(e,a,r)=>await P(a,r)),e.handle($("searchFiles"),async(e,a,r,t)=>{try{const e=await T(a,r,t),s=g(),c=100,i=[];for(const a of e.slice(0,c))try{const e=await E.stat(a),r=x(a,e),t={id:a,name:n.basename(a),type:r,size:e.isDirectory()?void 0:D(e.size),dateModified:N(e.mtime),url:G(a)};if(s){const e=await s.getThumbnailUrl(a);e&&(t.thumbnailUrl=e)}i.push(t)}catch{}return{success:!0,data:{items:i,total:e.length}}}catch(e){return{success:!1,error:String(e)}}}),e.handle($("searchFilesStream"),async(e,a,r,t)=>{const s=g(),c=H.get(e.sender.id)??new Map;H.set(e.sender.id,c);const i=new AbortController;c.set(t,{controller:i});const l=async e=>{try{const a=await E.stat(e),r=x(e,a),t={id:e,name:n.basename(e),type:r,size:a.isDirectory()?void 0:D(a.size),dateModified:N(a.mtime),url:G(e)};if(s){const a=await s.getThumbnailUrl(e);a&&(t.thumbnailUrl=a)}return t}catch{return null}};return S(a,r,async(a,r)=>{if(i.signal.aborted)return;const n=[];for(const e of a){if(i.signal.aborted)return;const a=await l(e);a&&n.push(a)}i.signal.aborted||(e.sender.send($("searchResults"),{searchId:t,items:n,done:r}),r&&(c.delete(t),0===c.size&&H.delete(e.sender.id)))},100,{signal:i.signal}).catch(()=>{c.delete(t),0===c.size&&H.delete(e.sender.id)}),{success:!0}}),e.handle($("cancelSearch"),async(e,a)=>{const r=H.get(e.sender.id),n=r?.get(a);return n?(n.controller.abort(),r?.delete(a),r&&0===r.size&&H.delete(e.sender.id),{success:!0}):{success:!0}}),e.handle($("compressFiles"),async(e,a,r)=>{try{return await A(a,r,a=>{e.sender.send($("compressProgress"),a)})}catch(e){return{success:!1,error:String(e)}}}),e.handle($("extractArchive"),async(e,a,r)=>{try{return await M(a,r,a=>{e.sender.send($("extractProgress"),a)})}catch(e){return{success:!1,error:String(e)}}}),e.handle($("isArchiveFile"),async(e,a)=>U(a));const B=new Map;e.handle($("watchDirectory"),async(e,a,r)=>{try{const n=B.get(r);n&&(n(),B.delete(r));const t=I().watch(a,a=>{e.sender.send($("watchEvent"),{watchId:r,event:a})});return B.set(r,t),{success:!0}}catch(e){return{success:!1,error:String(e)}}}),e.handle($("unwatchDirectory"),async(e,a)=>{const r=B.get(a);return r&&(r(),B.delete(a)),{success:!0}}),e.handle($("showFileInfo"),async(e,a)=>await v(a)),e.handle($("openInTerminal"),async(e,a)=>await C(a)),e.handle($("openInEditor"),async(e,a)=>await z(a)),e.handle($("openInNewWindow"),async(e,r)=>{try{return R.onOpenInNewWindow?R.onOpenInNewWindow(r):await a.openPath(r),{success:!0}}catch(e){return{success:!1,error:String(e)}}}),e.on($("requestWindowFocus"),e=>{const a=r.fromWebContents(e.sender);a&&!a.isFocused()&&a.focus()}),e.handle($("mediaNeedsTranscode"),async(e,a)=>{const r=W();if(!r)return{success:!1,error:"媒体服务未初始化"};try{return{success:!0,data:await r.needsTranscode(a)}}catch(e){return{success:!1,error:String(e)}}}),e.handle($("mediaGetPlayableUrl"),async(e,a)=>{const r=W();if(!r)return{success:!1,error:"媒体服务未初始化"};try{return{success:!0,url:await r.getPlayableUrl(a,r=>{e.sender.send($("mediaTranscodeProgress"),{filePath:a,progress:r})})}}catch(e){return{success:!1,error:String(e)}}}),e.handle($("mediaGetMetadata"),async(e,a)=>{const r=W();if(!r)return{success:!1,error:"媒体服务未初始化"};try{return{success:!0,data:await r.getMetadata(a)}}catch(e){return{success:!1,error:String(e)}}}),e.handle($("mediaCleanupFile"),async(e,a)=>{const r=W();if(!r)return{success:!1,error:"媒体服务未初始化"};try{return await r.cleanupFile(a),{success:!0}}catch(e){return{success:!1,error:String(e)}}}),e.handle($("openMediaFileApp"),async(e,a,r)=>{try{const t=n.basename(a),s=W();let c;if("image"===r)c=G(a);else if(s){c=await s.getPlayableUrl(a,r=>{e.sender.send($("mediaTranscodeProgress"),{filePath:a,progress:r})})||G(a)}else c=G(a);return R.onOpenMediaFileApp?(R.onOpenMediaFileApp({filePath:a,mediaType:r,fileUrl:c,fileName:t}),{success:!0}):{success:!1,error:"请实现 onOpenMediaFileApp 以支持媒体文件应用"}}catch(e){return{success:!1,error:String(e)}}}),e.handle($("closeMediaFileApp"),async(e,a,r)=>(R.onCloseMediaFileApp&&R.onCloseMediaFileApp(a,r),{success:!0}))}function q(e={}){var a;e.clipboardAdapter&&(a=e.clipboardAdapter,j=a),$(e)}export{q as registerFileExplorer};
@@ -6,9 +6,12 @@
6
6
  /**
7
7
  * 文件操作 API 类型
8
8
  */
9
+ interface ReadDirectoryOptions {
10
+ includeHidden?: boolean;
11
+ }
9
12
  interface FileExplorerAPI {
10
13
  /** 读取目录 */
11
- readDirectory: (dirPath: string) => Promise<unknown[]>;
14
+ readDirectory: (dirPath: string, options?: ReadDirectoryOptions) => Promise<unknown[]>;
12
15
  /** 读取系统路径目录 */
13
16
  readSystemPath: (pathId: string) => Promise<unknown[]>;
14
17
  /** 获取系统路径 */
@@ -120,6 +123,11 @@ interface FileExplorerAPI {
120
123
  success: boolean;
121
124
  error?: string;
122
125
  }>;
126
+ /** 取消指定搜索 */
127
+ cancelSearch: (searchId: string) => Promise<{
128
+ success: boolean;
129
+ error?: string;
130
+ }>;
123
131
  /** 监听搜索结果 */
124
132
  onSearchResults: (callback: (data: {
125
133
  searchId: string;
@@ -249,13 +257,13 @@ interface FileExplorerAPI {
249
257
  success: boolean;
250
258
  error?: string;
251
259
  }>;
252
- /** 打开媒体预览窗口 */
253
- openMediaPreviewWindow: (filePath: string, mediaType: 'image' | 'video' | 'audio') => Promise<{
260
+ /** 打开媒体文件应用 */
261
+ openMediaFileApp: (filePath: string, mediaType: 'image' | 'video' | 'audio') => Promise<{
254
262
  success: boolean;
255
263
  error?: string;
256
264
  }>;
257
- /** 关闭媒体预览窗口 */
258
- closeMediaPreviewWindow: (filePath: string) => Promise<{
265
+ /** 关闭媒体文件应用 */
266
+ closeMediaFileApp: (filePath: string, mediaType: 'image' | 'video' | 'audio') => Promise<{
259
267
  success: boolean;
260
268
  error?: string;
261
269
  }>;
@@ -275,4 +283,4 @@ interface ExposeFileExplorerAPIOptions {
275
283
  }
276
284
  declare function exposeFileExplorerAPI(options?: ExposeFileExplorerAPIOptions): void;
277
285
 
278
- export { type ExposeFileExplorerAPIOptions, type FileExplorerAPI, exposeFileExplorerAPI };
286
+ export { type ExposeFileExplorerAPIOptions, type FileExplorerAPI, type ReadDirectoryOptions, exposeFileExplorerAPI };
@@ -1 +1 @@
1
- import{contextBridge as e,ipcRenderer as o}from"electron";function i(i={}){const n=i.apiName||"fileExplorerAPI",r=function(e={}){const i=e.channelPrefix||"file-explorer",n=e=>`${i}:${e}`;return{readDirectory:e=>o.invoke(n("readDirectory"),e),readSystemPath:e=>o.invoke(n("readSystemPath"),e),getSystemPath:e=>o.invoke(n("getSystemPath"),e),readFileContent:e=>o.invoke(n("readFileContent"),e),writeFileContent:(e,i)=>o.invoke(n("writeFileContent"),e,i),createFolder:(e,i)=>o.invoke(n("createFolder"),e,i),createFile:(e,i,r)=>o.invoke(n("createFile"),e,i,r),deleteFiles:e=>o.invoke(n("deleteFiles"),e),renameFile:(e,i)=>o.invoke(n("renameFile"),e,i),copyFiles:(e,i)=>o.invoke(n("copyFiles"),e,i),moveFiles:(e,i)=>o.invoke(n("moveFiles"),e,i),getFileInfo:e=>o.invoke(n("getFileInfo"),e),readImageAsBase64:e=>o.invoke(n("readImageAsBase64"),e),openPath:e=>o.invoke(n("openPath"),e),getApplicationIcon:e=>o.invoke(n("getApplicationIcon"),e),getThumbnailUrl:e=>o.invoke(n("getThumbnailUrl"),e),copyFilesToClipboard:e=>o.invoke(n("copyFilesToClipboard"),e),getClipboardFiles:()=>o.invoke(n("getClipboardFiles")),pasteFiles:(e,i)=>o.invoke(n("pasteFiles"),e,i),searchFiles:(e,i,r)=>o.invoke(n("searchFiles"),e,i,r),searchFilesStream:(e,i,r)=>o.invoke(n("searchFilesStream"),e,i,r),onSearchResults:e=>{const i=(o,i)=>{e(i)};return o.on(n("searchResults"),i),()=>o.removeListener(n("searchResults"),i)},compressFiles:(e,i)=>o.invoke(n("compressFiles"),e,i),extractArchive:(e,i)=>o.invoke(n("extractArchive"),e,i),isArchiveFile:e=>o.invoke(n("isArchiveFile"),e),onCompressProgress:e=>{const i=(o,i)=>{e(i)};return o.on(n("compressProgress"),i),()=>o.removeListener(n("compressProgress"),i)},onExtractProgress:e=>{const i=(o,i)=>{e(i)};return o.on(n("extractProgress"),i),()=>o.removeListener(n("extractProgress"),i)},watchDirectory:(e,i)=>o.invoke(n("watchDirectory"),e,i),unwatchDirectory:e=>o.invoke(n("unwatchDirectory"),e),onWatchEvent:e=>{const i=(o,i)=>{e(i)};return o.on(n("watchEvent"),i),()=>o.removeListener(n("watchEvent"),i)},showFileInfo:e=>o.invoke(n("showFileInfo"),e),openInTerminal:e=>o.invoke(n("openInTerminal"),e),openInEditor:e=>o.invoke(n("openInEditor"),e),openInNewWindow:e=>o.invoke(n("openInNewWindow"),e),requestWindowFocus:()=>o.send(n("requestWindowFocus")),mediaNeedsTranscode:e=>o.invoke(n("mediaNeedsTranscode"),e),mediaGetPlayableUrl:e=>o.invoke(n("mediaGetPlayableUrl"),e),mediaGetMetadata:e=>o.invoke(n("mediaGetMetadata"),e),onMediaTranscodeProgress:e=>{const i=(o,i)=>{e(i)};return o.on(n("mediaTranscodeProgress"),i),()=>o.removeListener(n("mediaTranscodeProgress"),i)},mediaCleanupFile:e=>o.invoke(n("mediaCleanupFile"),e),openMediaPreviewWindow:(e,i)=>o.invoke(n("openMediaPreviewWindow"),e,i),closeMediaPreviewWindow:e=>o.invoke(n("closeMediaPreviewWindow"),e)}}({channelPrefix:i.channelPrefix});e.exposeInMainWorld(n,r)}export{i as exposeFileExplorerAPI};
1
+ import{contextBridge as e,ipcRenderer as o}from"electron";function i(i={}){const n=i.apiName||"fileExplorerAPI",r=function(e={}){const i=e.channelPrefix||"file-explorer",n=e=>`${i}:${e}`;return{readDirectory:(e,i)=>o.invoke(n("readDirectory"),e,i),readSystemPath:e=>o.invoke(n("readSystemPath"),e),getSystemPath:e=>o.invoke(n("getSystemPath"),e),readFileContent:e=>o.invoke(n("readFileContent"),e),writeFileContent:(e,i)=>o.invoke(n("writeFileContent"),e,i),createFolder:(e,i)=>o.invoke(n("createFolder"),e,i),createFile:(e,i,r)=>o.invoke(n("createFile"),e,i,r),deleteFiles:e=>o.invoke(n("deleteFiles"),e),renameFile:(e,i)=>o.invoke(n("renameFile"),e,i),copyFiles:(e,i)=>o.invoke(n("copyFiles"),e,i),moveFiles:(e,i)=>o.invoke(n("moveFiles"),e,i),getFileInfo:e=>o.invoke(n("getFileInfo"),e),readImageAsBase64:e=>o.invoke(n("readImageAsBase64"),e),openPath:e=>o.invoke(n("openPath"),e),getApplicationIcon:e=>o.invoke(n("getApplicationIcon"),e),getThumbnailUrl:e=>o.invoke(n("getThumbnailUrl"),e),copyFilesToClipboard:e=>o.invoke(n("copyFilesToClipboard"),e),getClipboardFiles:()=>o.invoke(n("getClipboardFiles")),pasteFiles:(e,i)=>o.invoke(n("pasteFiles"),e,i),searchFiles:(e,i,r)=>o.invoke(n("searchFiles"),e,i,r),searchFilesStream:(e,i,r)=>o.invoke(n("searchFilesStream"),e,i,r),cancelSearch:e=>o.invoke(n("cancelSearch"),e),onSearchResults:e=>{const i=(o,i)=>{e(i)};return o.on(n("searchResults"),i),()=>o.removeListener(n("searchResults"),i)},compressFiles:(e,i)=>o.invoke(n("compressFiles"),e,i),extractArchive:(e,i)=>o.invoke(n("extractArchive"),e,i),isArchiveFile:e=>o.invoke(n("isArchiveFile"),e),onCompressProgress:e=>{const i=(o,i)=>{e(i)};return o.on(n("compressProgress"),i),()=>o.removeListener(n("compressProgress"),i)},onExtractProgress:e=>{const i=(o,i)=>{e(i)};return o.on(n("extractProgress"),i),()=>o.removeListener(n("extractProgress"),i)},watchDirectory:(e,i)=>o.invoke(n("watchDirectory"),e,i),unwatchDirectory:e=>o.invoke(n("unwatchDirectory"),e),onWatchEvent:e=>{const i=(o,i)=>{e(i)};return o.on(n("watchEvent"),i),()=>o.removeListener(n("watchEvent"),i)},showFileInfo:e=>o.invoke(n("showFileInfo"),e),openInTerminal:e=>o.invoke(n("openInTerminal"),e),openInEditor:e=>o.invoke(n("openInEditor"),e),openInNewWindow:e=>o.invoke(n("openInNewWindow"),e),requestWindowFocus:()=>o.send(n("requestWindowFocus")),mediaNeedsTranscode:e=>o.invoke(n("mediaNeedsTranscode"),e),mediaGetPlayableUrl:e=>o.invoke(n("mediaGetPlayableUrl"),e),mediaGetMetadata:e=>o.invoke(n("mediaGetMetadata"),e),onMediaTranscodeProgress:e=>{const i=(o,i)=>{e(i)};return o.on(n("mediaTranscodeProgress"),i),()=>o.removeListener(n("mediaTranscodeProgress"),i)},mediaCleanupFile:e=>o.invoke(n("mediaCleanupFile"),e),openMediaFileApp:(e,i)=>o.invoke(n("openMediaFileApp"),e,i),closeMediaFileApp:(e,i)=>o.invoke(n("closeMediaFileApp"),e,i)}}({channelPrefix:i.channelPrefix});e.exposeInMainWorld(n,r)}export{i as exposeFileExplorerAPI};
@@ -1 +1 @@
1
- "use strict";var e,r=Object.defineProperty,n=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,t={};((e,n)=>{for(var i in n)r(e,i,{get:n[i],enumerable:!0})})(t,{exposePreviewWindowAPI:()=>p}),module.exports=(e=t,((e,t,d,c)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let p of i(t))o.call(e,p)||p===d||r(e,p,{get:()=>t[p],enumerable:!(c=n(t,p))||c.enumerable});return e})(r({},"__esModule",{value:!0}),e));var d=require("electron"),c=e=>`file-explorer-preview:${e}`;function p(){const e={minimizeWindow:()=>d.ipcRenderer.send(c("minimize")),toggleMaximizeWindow:()=>d.ipcRenderer.send(c("toggleMaximize")),closeWindow:()=>d.ipcRenderer.send(c("close")),hideWindow:()=>d.ipcRenderer.send(c("hide")),showWindow:()=>d.ipcRenderer.send(c("show")),onMaximizeChange:e=>{const r=(r,n)=>{e(n)};return d.ipcRenderer.on(c("maximizeChange"),r),()=>d.ipcRenderer.removeListener(c("maximizeChange"),r)}};d.contextBridge.exposeInMainWorld("electronAPI",e)}p();
1
+ var e,r=Object.defineProperty,n=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,t={};((e,n)=>{for(var i in n)r(e,i,{get:n[i],enumerable:!0})})(t,{exposePreviewWindowAPI:()=>p}),module.exports=(e=t,((e,t,d,c)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let p of i(t))o.call(e,p)||p===d||r(e,p,{get:()=>t[p],enumerable:!(c=n(t,p))||c.enumerable});return e})(r({},"__esModule",{value:!0}),e));var d=require("electron"),c=e=>`file-explorer-preview:${e}`;function p(){const e={minimizeWindow:()=>d.ipcRenderer.send(c("minimize")),toggleMaximizeWindow:()=>d.ipcRenderer.send(c("toggleMaximize")),closeWindow:()=>d.ipcRenderer.send(c("close")),hideWindow:()=>d.ipcRenderer.send(c("hide")),showWindow:()=>d.ipcRenderer.send(c("show")),onMaximizeChange:e=>{const r=(r,n)=>{e(n)};return d.ipcRenderer.on(c("maximizeChange"),r),()=>d.ipcRenderer.removeListener(c("maximizeChange"),r)}};d.contextBridge.exposeInMainWorld("electronAPI",e)}p();
@@ -9,10 +9,13 @@ import { FileItem, OperationResult, FileInfo, CompressOptions, CompressResult, E
9
9
  /**
10
10
  * Window 扩展类型
11
11
  */
12
+ interface ReadDirectoryOptions {
13
+ includeHidden?: boolean;
14
+ }
12
15
  declare global {
13
16
  interface Window {
14
17
  fileExplorerAPI?: {
15
- readDirectory: (dirPath: string) => Promise<FileItem[]>;
18
+ readDirectory: (dirPath: string, options?: ReadDirectoryOptions) => Promise<FileItem[]>;
16
19
  readSystemPath: (pathId: string) => Promise<FileItem[]>;
17
20
  getSystemPath: (pathId: string) => Promise<string | null>;
18
21
  readFileContent: (filePath: string) => Promise<string>;
@@ -53,6 +56,7 @@ declare global {
53
56
  total: number;
54
57
  }>>;
55
58
  searchFilesStream: (searchPath: string, pattern: string, searchId: string) => Promise<OperationResult>;
59
+ cancelSearch: (searchId: string) => Promise<OperationResult>;
56
60
  onSearchResults: (callback: (data: {
57
61
  searchId: string;
58
62
  items: FileItem[];
@@ -86,8 +90,8 @@ declare global {
86
90
  progress: TranscodeProgress;
87
91
  }) => void) => () => void;
88
92
  mediaCleanupFile: (filePath: string) => Promise<OperationResult>;
89
- openMediaPreviewWindow: (filePath: string, mediaType: 'image' | 'video' | 'audio') => Promise<OperationResult>;
90
- closeMediaPreviewWindow: (filePath: string) => Promise<OperationResult>;
93
+ openMediaFileApp: (filePath: string, mediaType: 'image' | 'video' | 'audio') => Promise<OperationResult>;
94
+ closeMediaFileApp: (filePath: string, mediaType: 'image' | 'video' | 'audio') => Promise<OperationResult>;
91
95
  };
92
96
  }
93
97
  }
@@ -102,7 +106,7 @@ declare global {
102
106
  * ```
103
107
  */
104
108
  declare function createFileExplorerClient(apiName?: string): {
105
- readDirectory: (dirPath: string) => Promise<FileItem[]>;
109
+ readDirectory: (dirPath: string, options?: ReadDirectoryOptions) => Promise<FileItem[]>;
106
110
  readSystemPath: (pathId: string) => Promise<FileItem[]>;
107
111
  getSystemPath: (pathId: string) => Promise<string | null>;
108
112
  readFileContent: (filePath: string) => Promise<string>;
@@ -143,6 +147,7 @@ declare function createFileExplorerClient(apiName?: string): {
143
147
  total: number;
144
148
  }>>;
145
149
  searchFilesStream: (searchPath: string, pattern: string, searchId: string) => Promise<OperationResult>;
150
+ cancelSearch: (searchId: string) => Promise<OperationResult>;
146
151
  onSearchResults: (callback: (data: {
147
152
  searchId: string;
148
153
  items: FileItem[];
@@ -176,8 +181,8 @@ declare function createFileExplorerClient(apiName?: string): {
176
181
  progress: TranscodeProgress;
177
182
  }) => void) => () => void;
178
183
  mediaCleanupFile: (filePath: string) => Promise<OperationResult>;
179
- openMediaPreviewWindow: (filePath: string, mediaType: "image" | "video" | "audio") => Promise<OperationResult>;
180
- closeMediaPreviewWindow: (filePath: string) => Promise<OperationResult>;
184
+ openMediaFileApp: (filePath: string, mediaType: "image" | "video" | "audio") => Promise<OperationResult>;
185
+ closeMediaFileApp: (filePath: string, mediaType: "image" | "video" | "audio") => Promise<OperationResult>;
181
186
  };
182
187
 
183
188
  export { createFileExplorerClient };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@huyooo/file-explorer-bridge-electron",
3
- "version": "0.4.29",
3
+ "version": "0.4.30",
4
4
  "description": "File Explorer Electron Bridge - IPC integration for Electron apps",
5
5
  "type": "module",
6
6
  "main": "./dist/main/index.js",
@@ -30,8 +30,7 @@
30
30
  "clean": "rm -rf dist"
31
31
  },
32
32
  "dependencies": {
33
- "@huyooo/file-explorer-core": "^0.4.29",
34
- "@huyooo/file-explorer-preview": "^0.4.29"
33
+ "@huyooo/file-explorer-core": "^0.4.30"
35
34
  },
36
35
  "peerDependencies": {
37
36
  "electron": ">=20.0.0"