AssetPro/electron/preload.ts

300 lines
8.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Electron Preload 脚本
*
* 这是渲染进程和主进程之间的安全桥梁
* 通过 contextBridge 安全地暴露 API 给渲染进程
*
* 安全说明:
* - contextIsolation: true 确保渲染进程无法直接访问 Node.js API
* - 所有暴露的方法都经过 IPC 通道与主进程通信
* - 不要在这里导入 electron-store 或其他 Node.js 模块
*/
import { contextBridge, ipcRenderer } from 'electron'
// IPC 通道名称(与 ipc.ts 保持一致)
const IPC_CHANNELS = {
SAVE_FILE: 'file:save',
READ_FILE: 'file:read',
GET_SETTINGS: 'settings:get',
SAVE_SETTINGS: 'settings:save',
// 缓存操作
CACHE_SET_JSON: 'cache:setJSON',
CACHE_GET_JSON: 'cache:getJSON',
CACHE_SET_BINARY: 'cache:setBinary',
CACHE_GET_BINARY: 'cache:getBinary',
CACHE_HAS: 'cache:has',
CACHE_DELETE: 'cache:delete',
CACHE_CLEAR_NAMESPACE: 'cache:clearNamespace',
CACHE_CLEAR_ALL: 'cache:clearAll',
CACHE_GET_STATS: 'cache:getStats',
// 窗口操作
WINDOW_MINIMIZE: 'window:minimize',
WINDOW_MAXIMIZE: 'window:maximize',
WINDOW_CLOSE: 'window:close',
// Git/System 操作
DIALOG_OPEN_DIRECTORY: 'dialog:openDirectory',
GIT_CLONE: 'git:clone'
} as const
// API 响应类型定义
interface FileOperationResult {
success: boolean
message: string
path?: string | null
content?: string | null
canceled?: boolean
}
interface GitOperationResult {
success: boolean
message: string
stdout?: string
}
interface SettingsOperationResult {
success: boolean
message?: string
data?: unknown
}
interface CacheOperationResult {
success: boolean
message?: string
data?: any
exists?: boolean
}
interface WindowOperationResult {
success: boolean
message?: string
isMaximized?: boolean
}
// 暴露给渲染进程的 API 接口
interface ElectronAPI {
// 文件操作
file: {
save: (content: string, filename?: string) => Promise<FileOperationResult>
read: (filename?: string) => Promise<FileOperationResult>
openDirectory: () => Promise<FileOperationResult>
}
// Git 操作
git: {
clone: (repoUrl: string, targetDir: string) => Promise<GitOperationResult>
onProgress: (callback: (data: { repoUrl: string; raw: string }) => void) => void
removeListener: () => void
}
// 设置操作
settings: {
get: (key?: string) => Promise<SettingsOperationResult>
save: (key: string, value: unknown) => Promise<SettingsOperationResult>
}
// 缓存操作
cache: {
setJSON: (key: string, data: any, config?: { maxAge?: number; namespace?: string }) => Promise<CacheOperationResult>
getJSON: (key: string, config?: { maxAge?: number; namespace?: string }) => Promise<CacheOperationResult>
setBinary: (key: string, buffer: Buffer, type?: 'binary' | 'image', config?: { maxAge?: number; namespace?: string }) => Promise<CacheOperationResult>
getBinary: (key: string, config?: { maxAge?: number; namespace?: string }) => Promise<CacheOperationResult>
has: (key: string, config?: { namespace?: string }) => Promise<CacheOperationResult>
delete: (key: string, namespace?: string) => Promise<CacheOperationResult>
clearNamespace: (namespace: string) => Promise<CacheOperationResult>
clearAll: () => Promise<CacheOperationResult>
getStats: () => Promise<CacheOperationResult>
}
// 窗口操作
window: {
minimize: () => Promise<WindowOperationResult>
maximize: () => Promise<WindowOperationResult>
close: () => Promise<WindowOperationResult>
}
}
// 通过 contextBridge 安全地暴露 API
const electronAPI: ElectronAPI = {
// ============================================
// 文件操作 API
// ============================================
file: {
/**
* 保存文件到桌面
* @param content - 文件内容
* @param filename - 文件名(可选,默认为 demo-note.txt
*/
save: (content: string, filename?: string) => {
return ipcRenderer.invoke(IPC_CHANNELS.SAVE_FILE, content, filename)
},
/**
* 从桌面读取文件
* @param filename - 文件名(可选,默认为 demo-note.txt
*/
read: (filename?: string) => {
return ipcRenderer.invoke(IPC_CHANNELS.READ_FILE, filename)
},
/**
* 打开目录选择对话框
*/
openDirectory: () => {
return ipcRenderer.invoke(IPC_CHANNELS.DIALOG_OPEN_DIRECTORY)
}
},
// ============================================
// Git 操作 API
// ============================================
git: {
/**
* 克隆 Git 仓库
* @param repoUrl - 仓库地址
* @param targetDir - 目标目录
*/
clone: (repoUrl: string, targetDir: string) => {
return ipcRenderer.invoke(IPC_CHANNELS.GIT_CLONE, repoUrl, targetDir)
},
/**
* 监听 Git 进度
*/
onProgress: (callback: (data: { repoUrl: string; raw: string }) => void) => {
// 移除旧的监听器以防止重复 (简化处理,实际应该支持多监听器或由调用者管理)
ipcRenderer.removeAllListeners('git:progress')
ipcRenderer.on('git:progress', (_event, data) => {
callback(data)
})
},
/**
* 移除监听器
*/
removeListener: () => {
ipcRenderer.removeAllListeners('git:progress')
}
},
// ============================================
// 设置操作 API
// ============================================
settings: {
/**
* 获取用户设置
* @param key - 设置键名(可选,不传返回所有设置)
*/
get: (key?: string) => {
return ipcRenderer.invoke(IPC_CHANNELS.GET_SETTINGS, key)
},
/**
* 保存用户设置
* @param key - 设置键名
* @param value - 设置值
*/
save: (key: string, value: unknown) => {
return ipcRenderer.invoke(IPC_CHANNELS.SAVE_SETTINGS, key, value)
}
},
// ============================================
// 缓存操作 API
// ============================================
cache: {
/**
* 设置JSON缓存
*/
setJSON: (key: string, data: any, config?: { maxAge?: number; namespace?: string }) => {
return ipcRenderer.invoke(IPC_CHANNELS.CACHE_SET_JSON, key, data, config)
},
/**
* 获取JSON缓存
*/
getJSON: (key: string, config?: { maxAge?: number; namespace?: string }) => {
return ipcRenderer.invoke(IPC_CHANNELS.CACHE_GET_JSON, key, config)
},
/**
* 设置二进制缓存
*/
setBinary: (key: string, buffer: Buffer, type?: 'binary' | 'image', config?: { maxAge?: number; namespace?: string }) => {
return ipcRenderer.invoke(IPC_CHANNELS.CACHE_SET_BINARY, key, buffer, type, config)
},
/**
* 获取二进制缓存
*/
getBinary: (key: string, config?: { maxAge?: number; namespace?: string }) => {
return ipcRenderer.invoke(IPC_CHANNELS.CACHE_GET_BINARY, key, config)
},
/**
* 检查缓存是否存在
*/
has: (key: string, config?: { namespace?: string }) => {
return ipcRenderer.invoke(IPC_CHANNELS.CACHE_HAS, key, config)
},
/**
* 删除单个缓存
*/
delete: (key: string, namespace?: string) => {
return ipcRenderer.invoke(IPC_CHANNELS.CACHE_DELETE, key, namespace)
},
/**
* 清空命名空间缓存
*/
clearNamespace: (namespace: string) => {
return ipcRenderer.invoke(IPC_CHANNELS.CACHE_CLEAR_NAMESPACE, namespace)
},
/**
* 清空所有缓存
*/
clearAll: () => {
return ipcRenderer.invoke(IPC_CHANNELS.CACHE_CLEAR_ALL)
},
/**
* 获取缓存统计信息
*/
getStats: () => {
return ipcRenderer.invoke(IPC_CHANNELS.CACHE_GET_STATS)
}
},
// ============================================
// 窗口操作 API
// ============================================
window: {
/**
* 最小化窗口
*/
minimize: () => {
return ipcRenderer.invoke(IPC_CHANNELS.WINDOW_MINIMIZE)
},
/**
* 最大化/还原窗口
*/
maximize: () => {
return ipcRenderer.invoke(IPC_CHANNELS.WINDOW_MAXIMIZE)
},
/**
* 关闭窗口
*/
close: () => {
return ipcRenderer.invoke(IPC_CHANNELS.WINDOW_CLOSE)
}
}
}
// 暴露 API 到 window.electronAPI
contextBridge.exposeInMainWorld('electronAPI', electronAPI)
// TypeScript 类型声明(供渲染进程使用)
declare global {
interface Window {
electronAPI: ElectronAPI
}
}