@lynker-desktop/electron-sdk 0.0.9-alpha.82 → 0.0.9-alpha.85
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/common/index.d.ts +9 -1
- package/common/index.d.ts.map +1 -1
- package/common/index.js.map +1 -1
- package/esm/common/index.d.ts +9 -1
- package/esm/common/index.d.ts.map +1 -1
- package/esm/common/index.js.map +1 -1
- package/esm/main/downloader.d.ts +1 -0
- package/esm/main/downloader.d.ts.map +1 -1
- package/esm/main/downloader.js +74 -8
- package/esm/main/downloader.js.map +1 -1
- package/esm/main/index.d.ts.map +1 -1
- package/esm/main/index.js +46 -11
- package/esm/main/index.js.map +1 -1
- package/main/downloader.d.ts +1 -0
- package/main/downloader.d.ts.map +1 -1
- package/main/downloader.js +74 -8
- package/main/downloader.js.map +1 -1
- package/main/index.d.ts.map +1 -1
- package/main/index.js +46 -11
- package/main/index.js.map +1 -1
- package/package.json +5 -5
package/main/downloader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"downloader.js","sources":["../src/src/main/downloader.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport mime from 'mime-types';\nimport { DownloaderHelper } from 'node-downloader-helper';\nimport { ipcMain, dialog, BrowserWindow, app } from 'electron';\n\n/**\n * 最大重定向次数\n */\nconst MAX_REDIRECTS = 5;\n\n/**\n * 默认文件扩展名\n */\nconst DEFAULT_EXT = '.bin';\n\n/**\n * 默认 MIME 类型\n */\nconst DEFAULT_MIME_TYPE = 'application/octet-stream';\n\n/**\n * 默认超时时间(毫秒):10 分钟\n */\nconst DEFAULT_TIMEOUT = 600000;\n\n/**\n * 默认重试配置\n */\nconst DEFAULT_RETRY = {\n maxRetries: 3,\n delay: 1000\n};\n\n/**\n * 默认文件名\n */\nconst DEFAULT_FILENAME = 'download';\n\n/**\n * 最大文件名计数器(防止无限循环)\n */\nconst MAX_FILENAME_COUNTER = 10000;\n\n/**\n * 下载进度回调函数类型\n */\nexport type DownloadProgressCallback = (progress: {\n url: string; // 正在下载的 URL\n downloaded: number; // 已下载字节数\n total: number; // 总字节数(如果服务器提供 Content-Length)\n percentage: number; // 下载进度百分比 (0-100),如果 total 未知则为 -1\n speed: number; // 下载速度(字节/秒)\n}) => void;\n\n/**\n * 下载选项\n */\nexport interface DownloadOptions {\n /** 唯一标识(IPC 调用时必需) */\n id?: string;\n /** 输出文件路径(可选,如果不提供则使用 URL 的文件名) */\n outputPath?: string;\n /** 输出目录(可选,如果不提供则使用当前目录) */\n outputDir?: string;\n /** 输出文件名(可选,如果不提供则从 URL 提取) */\n fileName?: string;\n /** 是否覆盖已存在的文件(默认 true) */\n override?: boolean;\n /** 是否弹窗选择保存路径(默认 false) */\n showSaveDialog?: boolean;\n /** 保存对话框的默认文件名(可选) */\n defaultPath?: string;\n /** 超时时间(毫秒,默认 10 分钟) */\n timeout?: number;\n /** 重试配置 */\n retry?: {\n maxRetries?: number;\n delay?: number;\n };\n /** 下载进度回调函数(可选) */\n onProgress?: DownloadProgressCallback;\n /** 下载完成回调函数(可选) */\n onComplete?: (filePath: string) => void;\n /** 下载错误回调函数(可选) */\n onError?: (error: Error) => void;\n /** HTTP 请求选项 */\n httpRequestOptions?: {\n headers?: Record<string, string>;\n followRedirect?: boolean;\n maxRedirects?: number;\n };\n}\n\n/**\n * 下载结果\n */\nexport interface DownloadResult {\n /** 是否成功 */\n success: boolean;\n /** 下载的文件路径(成功时返回) */\n filePath?: string;\n /** 错误信息(失败时返回,包含错误类型和详细描述) */\n error?: string;\n /** 错误类型(失败时返回,用于区分不同类型的错误) */\n errorType?: 'NETWORK' | 'FILE_SYSTEM' | 'PERMISSION' | 'VALIDATION' | 'USER_CANCEL' | 'UNKNOWN';\n /** 文件大小(字节,成功时返回) */\n size?: number;\n}\n\n/**\n * 下载器类:提供文件下载功能\n */\nexport class Downloader {\n /** 正在下载的 URL 集合(避免重复下载) */\n private _downloadingUrls = new Map<string, DownloaderHelper>();\n /** 上一次选择的保存文件夹路径 */\n private _lastSelectedDir: string | null = null;\n\n /**\n * 构造函数:初始化下载器并注册 IPC 处理器\n * 注册 `core:downloader` IPC 处理器,用于从渲染进程接收下载请求\n */\n constructor() {\n ipcMain.handle(`core:downloader`, async (event: Electron.IpcMainInvokeEvent, options: DownloadOptions & { url: string; id: string }) => {\n try {\n const { id, url } = options;\n const sender = event.sender as Electron.WebContents;\n\n // 创建进度回调,通过 IPC 发送进度更新到渲染进程\n const progressCallback: DownloadProgressCallback = (progress) => {\n try {\n if (sender && typeof sender.send === 'function') {\n sender.send(`core:downloader:progress`, {\n id,\n data: progress\n });\n }\n } catch (error) {\n // 进度回调失败不影响下载,只记录日志\n console.error(`[Downloader] 发送下载进度失败 (ID: ${id}):`, error);\n }\n };\n\n const result = await this.download(url, options, progressCallback);\n return result;\n } catch (error) {\n // IPC 调用异常处理:解析错误并返回明确的错误信息\n const parsedError = this._parseError(error, options?.url);\n return {\n success: false,\n error: parsedError.message,\n errorType: parsedError.type\n };\n }\n });\n }\n\n /**\n * 下载文件\n *\n * 主要流程:\n * 1. 检查是否正在下载(避免重复下载)\n * 2. 确定输出路径(支持弹窗选择或自动解析)\n * 3. 验证并准备输出目录\n * 4. 处理 base64 data URL 或普通 HTTP 下载\n * 5. 使用临时文件下载,完成后重命名为最终文件\n *\n * @param url 要下载的 URL(支持 HTTP/HTTPS 和 base64 data URL)\n * @param options 下载选项(输出路径、重试配置、回调函数等)\n * @param onProgress 进度回调函数(可选,优先级高于 options.onProgress)\n * @returns Promise<DownloadResult> 下载结果,包含成功/失败状态、文件路径、错误信息等\n */\n public async download(\n url: string,\n options: DownloadOptions = {},\n onProgress?: DownloadProgressCallback\n ): Promise<DownloadResult> {\n // 参数验证:检查 URL 是否有效\n if (!url || typeof url !== 'string' || url.trim().length === 0) {\n return this._createErrorResult('下载 URL 不能为空', 'VALIDATION');\n }\n\n // 生成唯一标识:URL + ID(如果存在),用于避免重复下载\n const downloadKey = this._getDownloadKey(url, options.id);\n\n // 检查是否正在下载,避免重复下载同一资源\n if (this._downloadingUrls.has(downloadKey)) {\n return this._createErrorResult(\n `资源正在下载中,请勿重复下载: ${url}${options.id ? ` (ID: ${options.id})` : ''}`,\n 'VALIDATION'\n );\n }\n\n // 合并进度回调:优先使用传入的 onProgress,其次使用 options.onProgress\n const progressCallback = onProgress || options.onProgress;\n\n // 先检查是否是 base64 data URL(用于确定默认扩展名和特殊处理)\n const base64Info = this._isBase64DataUrl(url);\n const defaultExt = base64Info.isBase64 && base64Info.ext ? base64Info.ext : undefined;\n\n // 确定输出路径:支持弹窗选择或自动解析\n let outputPath: string;\n try {\n if (options.showSaveDialog) {\n // 显示保存对话框,让用户选择保存位置\n const savePath = await this._showSaveDialog(url, options, defaultExt);\n if (!savePath) {\n return this._createErrorResult('用户取消了保存操作', 'USER_CANCEL');\n }\n outputPath = savePath;\n } else {\n // 自动解析输出路径\n outputPath = this._resolveOutputPath(url, options, defaultExt);\n }\n } catch (error) {\n // 路径解析失败:可能是文件系统错误或权限问题\n const parsedError = this._parseError(error, url);\n return this._createErrorResult(\n `确定输出路径失败: ${parsedError.message}`,\n parsedError.type\n );\n }\n\n // 准备输出路径:确保目录存在、检查文件是否已存在\n try {\n const pathCheckResult = await this._prepareOutputPath(outputPath, options);\n if (pathCheckResult) {\n // 文件已存在且不允许覆盖,直接返回已存在的文件信息\n return pathCheckResult;\n }\n } catch (error) {\n // 路径准备失败:可能是权限问题或文件系统错误\n const parsedError = this._parseError(error, url);\n return this._createErrorResult(\n `准备输出路径失败: ${parsedError.message}`,\n parsedError.type\n );\n }\n\n // 提取下载目录和文件名\n let downloadDir = path.dirname(outputPath);\n let downloadFileName = path.basename(outputPath);\n\n // 再次清理文件名,确保不包含 query 参数和特殊字符(防止文件系统错误)\n downloadFileName = this._cleanFileName(downloadFileName);\n\n // 验证下载目录是否可访问,如果不可用则使用系统下载目录作为备用\n if (!this._isDirectoryAccessible(downloadDir)) {\n try {\n downloadDir = app.getPath('downloads');\n // 确保备用目录存在(如果不存在则创建)\n if (!fs.existsSync(downloadDir)) {\n fs.mkdirSync(downloadDir, { recursive: true });\n }\n // 验证备用目录是否可访问\n if (!this._isDirectoryAccessible(downloadDir)) {\n return this._createErrorResult(\n `无法访问下载目录: ${downloadDir},请检查目录权限`,\n 'PERMISSION'\n );\n }\n } catch (error) {\n const parsedError = this._parseError(error, url);\n return this._createErrorResult(\n `无法创建或访问备用下载目录: ${parsedError.message}`,\n parsedError.type\n );\n }\n }\n\n // 更新 outputPath 使用清理后的文件名和验证后的目录\n outputPath = path.join(downloadDir, downloadFileName);\n\n // 如果是 base64 data URL,使用已确定的输出路径进行特殊处理(无需网络请求)\n if (base64Info.isBase64 && base64Info.ext && base64Info.mimeType && base64Info.data) {\n return await this._handleBase64Download(\n url,\n { ext: base64Info.ext, mimeType: base64Info.mimeType, data: base64Info.data },\n outputPath,\n options,\n progressCallback\n );\n }\n\n // 使用临时文件下载(.cache 后缀),避免下载中断时文件不完整\n // 下载完成后会将临时文件重命名为最终文件\n const tempFilePath = path.join(downloadDir, downloadFileName + '.cache');\n\n return new Promise<DownloadResult>((resolve, reject) => {\n // 创建下载器实例(使用 node-downloader-helper)\n const dl = new DownloaderHelper(url, downloadDir, {\n fileName: downloadFileName + '.cache',\n retry: {\n maxRetries: options.retry?.maxRetries ?? DEFAULT_RETRY.maxRetries,\n delay: options.retry?.delay ?? DEFAULT_RETRY.delay\n },\n timeout: options.timeout ?? DEFAULT_TIMEOUT,\n override: true, // 临时文件总是覆盖,避免残留文件\n httpRequestOptions: {\n followRedirect: options.httpRequestOptions?.followRedirect ?? true,\n maxRedirects: options.httpRequestOptions?.maxRedirects ?? MAX_REDIRECTS,\n headers: options.httpRequestOptions?.headers\n }\n });\n\n // 记录正在下载的 URL(使用 URL + ID 作为 key),用于避免重复下载\n this._downloadingUrls.set(downloadKey, dl);\n\n // 监听下载进度事件\n if (progressCallback) {\n dl.on('progress', (stats) => {\n try {\n progressCallback({\n url,\n downloaded: stats.downloaded || 0,\n total: stats.total || 0,\n percentage: stats.progress !== undefined ? Math.round(stats.progress) : -1,\n speed: stats.speed || 0\n });\n } catch (error) {\n // 进度回调失败不影响下载,只记录日志\n console.error(`[Downloader] 进度回调执行失败 (${url}):`, error);\n }\n });\n }\n\n // 监听下载完成事件\n dl.on('end', () => {\n // 从下载列表中移除\n this._downloadingUrls.delete(downloadKey);\n\n // 将临时文件重命名为最终文件(原子操作,确保文件完整性)\n fs.rename(tempFilePath, outputPath, (renameErr) => {\n if (renameErr) {\n // 文件重命名失败:可能是权限问题或文件被占用\n const parsedError = this._parseError(renameErr, url);\n const error = new Error(\n `文件重命名失败: 无法将临时文件 \"${tempFilePath}\" 重命名为 \"${outputPath}\"。${parsedError.message}`\n );\n\n // 调用错误回调\n if (options.onError) {\n options.onError(error);\n }\n\n // reject 应该传入 Error 对象,而不是 DownloadResult\n // 将错误类型附加到错误对象上\n (error as any).errorType = parsedError.type;\n reject(error);\n } else {\n try {\n // 获取文件大小并返回成功结果\n const stats = fs.statSync(outputPath);\n const result = this._createSuccessResult(outputPath, stats.size);\n\n // 调用完成回调\n if (options.onComplete) {\n options.onComplete(outputPath);\n }\n\n resolve(result);\n } catch (error) {\n // 获取文件信息失败\n const parsedError = this._parseError(error, url);\n const errorObj = new Error(`下载完成但无法获取文件信息: ${parsedError.message}`);\n // 将错误类型附加到错误对象上\n (errorObj as any).errorType = parsedError.type;\n reject(errorObj);\n }\n }\n });\n });\n\n // 统一的错误处理函数\n const handleError = (error: Error | unknown, isUserCancel: boolean = false) => {\n // 从下载列表中移除\n this._downloadingUrls.delete(downloadKey);\n\n // 清理临时文件(忽略删除失败,避免影响错误处理)\n fs.promises.unlink(tempFilePath).catch(() => {\n // 临时文件删除失败不影响错误处理流程\n });\n\n // 解析错误信息\n const parsedError = this._parseError(error, url);\n const errorType = isUserCancel ? 'USER_CANCEL' : parsedError.type;\n const errorMessage = isUserCancel\n ? `下载已取消: ${url}`\n : parsedError.message;\n\n // 创建错误对象(包含错误类型信息)\n const errorObj = new Error(errorMessage);\n // 将错误类型附加到错误对象上,供 catch 处理时使用\n (errorObj as any).errorType = errorType;\n\n // 调用错误回调\n if (options.onError) {\n options.onError(errorObj);\n }\n\n // reject 应该传入 Error 对象,而不是 DownloadResult\n reject(errorObj);\n };\n\n // 监听下载错误事件(网络错误、服务器错误等)\n dl.on('error', (err) => {\n const error = err instanceof Error ? err : new Error(`下载失败: ${url}`);\n handleError(error, false);\n });\n\n // 监听下载停止事件(用户取消或手动停止)\n dl.on('stop', () => {\n const error = new Error(`下载已停止: ${url}`);\n handleError(error, true);\n });\n\n // 开始下载\n dl.start().catch((err) => {\n // 启动下载失败:可能是 URL 无效、网络不可达等\n const error = err instanceof Error ? err : new Error(`启动下载失败: ${url}`);\n handleError(error, false);\n });\n }).catch((error): DownloadResult => {\n // Promise 异常捕获:返回格式化的错误结果\n // 如果错误对象已经包含 errorType,直接使用;否则解析错误\n if (error instanceof Error && (error as any).errorType) {\n return this._createErrorResult(error.message, (error as any).errorType);\n }\n const parsedError = this._parseError(error, url);\n return this._createErrorResult(parsedError.message, parsedError.type);\n });\n }\n\n /**\n * 生成下载任务的唯一标识\n * @param url 下载 URL\n * @param id 可选的任务 ID\n * @returns 唯一标识\n */\n private _getDownloadKey(url: string, id?: string): string {\n return id ? `${url}::${id}` : url;\n }\n\n /**\n * 取消下载\n * @param url 要取消的 URL\n * @param id 可选的任务 ID\n * @returns 是否成功取消\n */\n public cancel(url: string, id?: string): boolean {\n const downloadKey = this._getDownloadKey(url, id);\n const dl = this._downloadingUrls.get(downloadKey);\n if (dl) {\n dl.stop();\n this._downloadingUrls.delete(downloadKey);\n return true;\n }\n return false;\n }\n\n /**\n * 取消所有正在进行的下载\n */\n public cancelAll(): void {\n for (const [url, dl] of this._downloadingUrls.entries()) {\n dl.stop();\n }\n this._downloadingUrls.clear();\n }\n\n /**\n * 检查指定 URL 是否正在下载\n * @param url 要检查的 URL\n * @param id 可选的任务 ID\n * @returns 是否正在下载\n */\n public isDownloading(url: string, id?: string): boolean {\n const downloadKey = this._getDownloadKey(url, id);\n return this._downloadingUrls.has(downloadKey);\n }\n\n /**\n * 获取正在下载的任务列表\n * @returns 正在下载的任务信息数组,包含 URL 和 ID(如果有)\n */\n public getDownloadingUrls(): Array<{ url: string; id?: string }> {\n return Array.from(this._downloadingUrls.keys()).map(key => {\n const parts = key.split('::');\n if (parts.length === 2 && parts[0] && parts[1]) {\n return { url: parts[0], id: parts[1] };\n }\n return { url: key };\n });\n }\n\n /**\n * 获取文件名(统一处理所有来源)\n * @param url 下载 URL\n * @param options 下载选项\n * @param defaultExt 默认扩展名(可选,用于 base64 URL)\n * @returns 清理后的文件名\n */\n private _getFileName(url: string, options: DownloadOptions, defaultExt?: string): string {\n // 优先级:defaultPath > fileName > defaultExt > URL提取\n if (options.defaultPath) {\n return this._cleanFileName(path.basename(options.defaultPath));\n }\n\n if (options.fileName) {\n return this._cleanFileName(options.fileName);\n }\n\n if (defaultExt) {\n return this._cleanFileName(`${DEFAULT_FILENAME}.${defaultExt}`);\n }\n // 从 URL 中提取文件名(_extractFileNameFromUrl 已经包含清理逻辑)\n return this._extractFileNameFromUrl(url);\n }\n\n /**\n * 检查目录是否存在且有访问权限\n *\n * 检查项:\n * 1. 路径是否有效(非空字符串)\n * 2. 目录是否存在\n * 3. 路径是否为目录(而非文件)\n * 4. 是否有读写权限\n *\n * @param dirPath 目录路径\n * @returns 如果目录存在且有读写权限则返回 true,否则返回 false\n */\n private _isDirectoryAccessible(dirPath: string): boolean {\n // 参数验证:检查路径是否有效\n if (!dirPath || typeof dirPath !== 'string') {\n return false;\n }\n\n try {\n // 检查目录是否存在\n if (!fs.existsSync(dirPath)) {\n return false;\n }\n\n // 检查是否是目录(而非文件)\n const stats = fs.statSync(dirPath);\n if (!stats.isDirectory()) {\n return false;\n }\n\n // 检查是否有读写权限(R_OK: 读权限, W_OK: 写权限)\n fs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK);\n return true;\n } catch {\n // 如果任何检查失败(不存在、不是目录、无权限等),返回 false\n return false;\n }\n }\n\n /**\n * 显示保存对话框\n *\n * 功能说明:\n * 1. 确定默认保存目录(优先级:defaultPath > outputDir > _lastSelectedDir > 系统下载目录)\n * 2. 验证并更新 _lastSelectedDir(如果不可访问则重置)\n * 3. 生成唯一文件名(如果文件已存在,添加数字后缀)\n * 4. 显示 Electron 保存对话框\n * 5. 记录用户选择的目录(用于下次默认使用)\n *\n * @param url 下载 URL(用于提取默认文件名)\n * @param options 下载选项(包含 defaultPath、outputDir 等)\n * @param defaultExt 默认扩展名(可选,用于 base64 URL)\n * @returns Promise<string | null> 用户选择的保存路径,如果取消则返回 null\n */\n private async _showSaveDialog(url: string, options: DownloadOptions, defaultExt?: string): Promise<string | null> {\n // 获取并清理默认文件名\n let defaultFileName = this._getFileName(url, options, defaultExt);\n\n // 获取默认目录\n let defaultDir: string | undefined;\n if (options.defaultPath) {\n defaultDir = path.dirname(options.defaultPath);\n } else if (options.outputDir) {\n defaultDir = path.resolve(options.outputDir);\n } else {\n // 如果没有指定目录,使用上一次选择的文件夹,如果没有则使用下载目录\n // 检查 _lastSelectedDir 是否可用,如果不可用则重置为下载目录\n if (this._lastSelectedDir && !this._isDirectoryAccessible(this._lastSelectedDir)) {\n const downloadsPath = app.getPath('downloads');\n // 验证下载目录是否可用,如果可用则使用,否则设为 null\n this._lastSelectedDir = this._isDirectoryAccessible(downloadsPath) ? downloadsPath : null;\n }\n defaultDir = this._lastSelectedDir || app.getPath('downloads');\n }\n\n // 如果指定了目录,检查文件是否存在并生成唯一文件名\n if (defaultDir) {\n defaultFileName = this._generateUniqueFileName(defaultDir, defaultFileName);\n }\n\n // 构建默认路径\n const defaultPath = defaultDir ? path.join(defaultDir, defaultFileName) : defaultFileName;\n\n // 获取当前活动的 BrowserWindow\n const focusedWindow = BrowserWindow.getFocusedWindow();\n const allWindows = BrowserWindow.getAllWindows();\n const parentWindow = focusedWindow || (allWindows.length > 0 ? allWindows[0] : undefined);\n\n // 显示保存对话框\n const dialogOptions = {\n defaultPath,\n title: '保存文件',\n buttonLabel: '保存',\n filters: [\n // 尝试从文件名推断文件类型\n ...(path.extname(defaultFileName) ? [{\n name: '所有文件',\n extensions: ['*']\n }] : [])\n ]\n };\n\n // 根据是否有父窗口调用不同的方法\n const result = parentWindow\n ? await dialog.showSaveDialog(parentWindow, dialogOptions)\n : await dialog.showSaveDialog(dialogOptions);\n\n if (result.canceled || !result.filePath) {\n return null;\n }\n\n // 记录用户选择的文件夹路径,用于下次默认使用\n const selectedDir = path.dirname(result.filePath);\n if (selectedDir) {\n // 验证选择的目录是否可访问,只有可访问时才保存\n if (this._isDirectoryAccessible(selectedDir)) {\n this._lastSelectedDir = selectedDir;\n } else {\n // 如果选择的目录不可访问,尝试使用下载目录\n const downloadsPath = app.getPath('downloads');\n this._lastSelectedDir = this._isDirectoryAccessible(downloadsPath) ? downloadsPath : null;\n }\n }\n\n return result.filePath;\n }\n\n /**\n * 检测并处理 base64 data URL\n * @param url 资源URL\n * @returns 如果是 base64 URL,返回 true、文件扩展名、MIME 类型和数据;否则返回 false\n */\n private _isBase64DataUrl(url: string): { isBase64: boolean, ext?: string, mimeType?: string, data?: string } {\n if (!url.startsWith('data:')) {\n return { isBase64: false };\n }\n\n try {\n // 解析 data URL 格式:data:[<mediatype>][;base64],<data>\n const commaIndex = url.indexOf(',');\n if (commaIndex === -1) {\n return { isBase64: false };\n }\n\n const header = url.substring(0, commaIndex);\n const data = url.substring(commaIndex + 1);\n\n // 检查是否包含 base64 标识\n if (!header.includes('base64')) {\n return { isBase64: false };\n }\n\n // 从 mediatype 中提取文件扩展名和 MIME 类型\n // 例如:data:image/png;base64 -> png, image/png\n // 例如:data:image/jpeg;base64 -> jpeg, image/jpeg\n let ext = DEFAULT_EXT.replace(/^\\./, '');\n let mimeType = DEFAULT_MIME_TYPE;\n const mimeMatch = header.match(/data:([^;]+)/);\n if (mimeMatch && mimeMatch[1]) {\n mimeType = mimeMatch[1];\n // 使用 mime-types 包从 MIME 类型获取扩展名\n const extension = mime.extension(mimeType);\n if (extension) {\n ext = extension;\n }\n }\n\n return { isBase64: true, ext, mimeType, data };\n } catch (error) {\n return { isBase64: false };\n }\n }\n\n /**\n * 保存 base64 数据到文件\n *\n * 处理流程:\n * 1. 将 base64 字符串解码为 Buffer\n * 2. 将 Buffer 写入目标文件路径\n *\n * @param base64Data base64 编码的数据字符串\n * @param filePath 目标文件路径(完整路径,包含文件名)\n * @throws 如果解码失败或文件写入失败,抛出错误\n */\n private async _saveBase64ToFile(base64Data: string, filePath: string): Promise<void> {\n try {\n // 解码 base64 数据为 Buffer\n const buffer = Buffer.from(base64Data, 'base64');\n\n // 使用 Promise 版本的 writeFile 写入文件\n // Buffer 继承自 Uint8Array,可以直接使用\n await fs.promises.writeFile(filePath, buffer as Uint8Array);\n } catch (error) {\n // 文件保存失败:可能是权限问题、磁盘空间不足、路径无效等\n const errorMessage = error instanceof Error ? error.message : '未知错误';\n throw new Error(`保存 base64 文件失败 (${filePath}): ${errorMessage}`);\n }\n }\n\n /**\n * 准备输出路径\n *\n * 主要功能:\n * 1. 确保输出目录存在(不存在则创建)\n * 2. 检查文件是否已存在\n * 3. 如果文件已存在且不允许覆盖,返回已存在的文件信息\n *\n * @param outputPath 输出文件路径\n * @param options 下载选项(包含 override 选项)\n * @returns 如果文件已存在且不允许覆盖,返回已存在的文件信息;否则返回 null\n * @throws 如果目录创建失败或权限不足,抛出错误\n */\n private async _prepareOutputPath(\n outputPath: string,\n options: DownloadOptions\n ): Promise<DownloadResult | null> {\n const downloadDir = path.dirname(outputPath);\n\n // 确保目录存在:如果不存在则创建(递归创建父目录)\n if (!fs.existsSync(downloadDir)) {\n try {\n fs.mkdirSync(downloadDir, { recursive: true });\n } catch (error) {\n // 目录创建失败:可能是权限问题或路径无效\n const parsedError = this._parseError(error);\n throw new Error(`无法创建输出目录 \"${downloadDir}\": ${parsedError.message}`);\n }\n }\n\n // 验证目录是否可访问\n if (!this._isDirectoryAccessible(downloadDir)) {\n throw new Error(`无法访问输出目录 \"${downloadDir}\",请检查目录权限`);\n }\n\n // 如果文件已存在且不允许覆盖,直接返回已存在的文件信息\n if (fs.existsSync(outputPath) && !(options.override ?? true)) {\n try {\n const stats = fs.statSync(outputPath);\n return this._createSuccessResult(outputPath, stats.size);\n } catch (error) {\n // 获取文件信息失败:可能是权限问题\n const parsedError = this._parseError(error);\n throw new Error(`无法访问已存在的文件 \"${outputPath}\": ${parsedError.message}`);\n }\n }\n\n return null;\n }\n\n /**\n * 创建成功结果\n * @param filePath 文件路径\n * @param size 文件大小(字节)\n * @returns DownloadResult 成功结果对象\n */\n private _createSuccessResult(filePath: string, size: number): DownloadResult {\n return {\n success: true,\n filePath,\n size\n };\n }\n\n /**\n * 创建错误结果\n * @param error 错误信息\n * @param errorType 错误类型(可选,用于区分不同类型的错误)\n * @returns DownloadResult 错误结果对象\n */\n private _createErrorResult(error: string, errorType?: DownloadResult['errorType']): DownloadResult {\n return {\n success: false,\n error,\n errorType: errorType || 'UNKNOWN'\n };\n }\n\n /**\n * 从错误对象中提取错误类型和详细信息\n * @param error 错误对象\n * @param url 下载的 URL(用于上下文信息)\n * @returns 包含错误类型和详细错误信息的对象\n */\n private _parseError(error: unknown, url?: string): { type: DownloadResult['errorType']; message: string } {\n if (error instanceof Error) {\n const errorMessage = error.message.toLowerCase();\n const errorCode = (error as any).code?.toLowerCase() || '';\n\n // 网络相关错误\n if (\n errorMessage.includes('network') ||\n errorMessage.includes('timeout') ||\n errorMessage.includes('econnrefused') ||\n errorMessage.includes('enotfound') ||\n errorMessage.includes('etimedout') ||\n errorCode.includes('timeout') ||\n errorCode.includes('econnrefused') ||\n errorCode.includes('enotfound') ||\n errorCode.includes('etimedout')\n ) {\n return {\n type: 'NETWORK',\n message: `网络错误: ${error.message}${url ? ` (URL: ${url})` : ''}`\n };\n }\n\n // 文件系统相关错误\n if (\n errorMessage.includes('enoent') ||\n errorMessage.includes('eacces') ||\n errorMessage.includes('eperm') ||\n errorMessage.includes('file') ||\n errorMessage.includes('directory') ||\n errorMessage.includes('path') ||\n errorCode.includes('enoent') ||\n errorCode.includes('eacces') ||\n errorCode.includes('eperm')\n ) {\n if (errorMessage.includes('permission') || errorMessage.includes('eacces') || errorMessage.includes('eperm')) {\n return {\n type: 'PERMISSION',\n message: `权限错误: ${error.message}${url ? ` (URL: ${url})` : ''}`\n };\n }\n return {\n type: 'FILE_SYSTEM',\n message: `文件系统错误: ${error.message}${url ? ` (URL: ${url})` : ''}`\n };\n }\n\n // 验证相关错误\n if (\n errorMessage.includes('invalid') ||\n errorMessage.includes('validation') ||\n errorMessage.includes('格式') ||\n errorMessage.includes('无效')\n ) {\n return {\n type: 'VALIDATION',\n message: `验证错误: ${error.message}${url ? ` (URL: ${url})` : ''}`\n };\n }\n\n // 用户取消\n if (errorMessage.includes('cancel') || errorMessage.includes('取消')) {\n return {\n type: 'USER_CANCEL',\n message: error.message\n };\n }\n\n // 其他错误\n return {\n type: 'UNKNOWN',\n message: `未知错误: ${error.message}${url ? ` (URL: ${url})` : ''}`\n };\n }\n\n // 非 Error 对象\n return {\n type: 'UNKNOWN',\n message: `未知错误: ${String(error)}${url ? ` (URL: ${url})` : ''}`\n };\n }\n\n /**\n * 处理 base64 data URL 的下载\n *\n * base64 data URL 格式:data:[<mediatype>][;base64],<data>\n * 例如:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...\n *\n * 处理流程:\n * 1. 验证 base64 数据有效性\n * 2. 触发进度回调(模拟 100% 完成)\n * 3. 解码并保存 base64 数据到文件\n * 4. 返回成功结果\n *\n * @param url base64 data URL\n * @param base64Info base64 信息(扩展名、MIME 类型、数据)\n * @param outputPath 已确定的输出路径\n * @param options 下载选项\n * @param progressCallback 进度回调(可选)\n * @returns Promise<DownloadResult> 下载结果\n */\n private async _handleBase64Download(\n url: string,\n base64Info: { ext: string; mimeType: string; data: string },\n outputPath: string,\n options: DownloadOptions,\n progressCallback?: DownloadProgressCallback\n ): Promise<DownloadResult> {\n // 验证 base64 数据有效性\n if (!base64Info.data || !base64Info.ext) {\n return this._createErrorResult(\n `无效的 base64 data URL: 缺少数据或扩展名 (URL: ${url.substring(0, 50)}...)`,\n 'VALIDATION'\n );\n }\n\n try {\n // 计算数据长度(用于进度回调)\n const dataLength = Buffer.from(base64Info.data, 'base64').length;\n\n // 模拟进度回调(base64 数据通常很小,立即完成)\n if (progressCallback) {\n progressCallback({\n url,\n downloaded: dataLength,\n total: dataLength,\n percentage: 100,\n speed: 0\n });\n }\n\n // 保存 base64 数据到文件\n await this._saveBase64ToFile(base64Info.data, outputPath);\n\n // 获取文件大小并返回成功结果\n const stats = fs.statSync(outputPath);\n const result = this._createSuccessResult(outputPath, stats.size);\n\n // 调用完成回调\n if (options.onComplete) {\n options.onComplete(outputPath);\n }\n\n return result;\n } catch (error) {\n // base64 文件保存失败:可能是文件系统错误或权限问题\n const parsedError = this._parseError(error, url);\n const err = error instanceof Error ? error : new Error(`保存 base64 文件失败: ${parsedError.message}`);\n\n // 调用错误回调\n if (options.onError) {\n options.onError(err);\n }\n\n return this._createErrorResult(\n `保存 base64 文件失败: ${parsedError.message}`,\n parsedError.type\n );\n }\n }\n\n /**\n * 生成唯一的文件名(如果文件已存在,添加数字后缀)\n *\n * 命名规则:\n * - 如果文件不存在,返回原始文件名\n * - 如果文件已存在,添加数字后缀:filename(1).ext, filename(2).ext, ...\n * - 最多尝试 MAX_FILENAME_COUNTER 次,防止无限循环\n *\n * 示例:\n * - \"test.pdf\" -> \"test.pdf\" (如果不存在)\n * - \"test.pdf\" -> \"test(1).pdf\" (如果 test.pdf 已存在)\n * - \"test(1).pdf\" -> \"test(2).pdf\" (如果 test(1).pdf 也已存在)\n *\n * @param dir 目录路径\n * @param fileName 原始文件名(包含扩展名)\n * @returns 唯一的文件名(如果原文件不存在则返回原文件名,否则返回带数字后缀的文件名)\n */\n private _generateUniqueFileName(dir: string, fileName: string): string {\n // 分离文件名和扩展名\n const ext = path.extname(fileName);\n const nameWithoutExt = path.basename(fileName, ext);\n\n // 检查原始文件名是否存在\n const originalPath = path.join(dir, fileName);\n if (!fs.existsSync(originalPath)) {\n return fileName;\n }\n\n // 如果存在,尝试添加数字后缀\n let counter = 1;\n let newFileName: string;\n let newPath: string;\n\n do {\n newFileName = `${nameWithoutExt}(${counter})${ext}`;\n newPath = path.join(dir, newFileName);\n counter++;\n } while (fs.existsSync(newPath) && counter < MAX_FILENAME_COUNTER);\n\n return newFileName;\n }\n\n /**\n * 清理文件名,移除 query 参数和特殊字符\n * @param fileName 原始文件名\n * @returns 清理后的文件名\n */\n private _cleanFileName(fileName: string): string {\n if (!fileName || fileName.length === 0) {\n return DEFAULT_FILENAME;\n }\n\n // 移除 query 参数(如果文件名中包含 ?)\n const queryIndex = fileName.indexOf('?');\n if (queryIndex !== -1) {\n fileName = fileName.substring(0, queryIndex);\n }\n\n // 解码 URL 编码的字符(如 %20 -> 空格)\n try {\n fileName = decodeURIComponent(fileName);\n } catch {\n // 如果解码失败,使用原始文件名\n }\n\n // 清理文件名中的特殊字符(文件系统不允许的字符)\n // 移除或替换:/ \\ : * ? \" < > |\n fileName = fileName.replace(/[/\\\\:*?\"<>|]/g, '_');\n\n // 移除前后空格和点号(Windows 不允许)\n fileName = fileName.trim().replace(/^\\.+|\\.+$/g, '');\n\n // 如果清理后文件名为空,使用默认文件名\n if (!fileName || fileName.length === 0) {\n fileName = DEFAULT_FILENAME;\n }\n\n return fileName;\n }\n\n /**\n * 从 URL 中提取文件名\n * @param url 下载 URL\n * @returns 文件名(已清理特殊字符,不包含query参数)\n */\n private _extractFileNameFromUrl(url: string): string {\n if (!url || typeof url !== 'string' || url.trim().length === 0) {\n return `${DEFAULT_FILENAME}${DEFAULT_EXT}`;\n }\n\n try {\n // 确保 URL 是完整的(如果缺少协议,添加 https://)\n let normalizedUrl = url.trim();\n if (!normalizedUrl.match(/^https?:\\/\\//i)) {\n normalizedUrl = `https://${normalizedUrl}`;\n }\n\n const urlObj = new URL(normalizedUrl);\n\n // 验证 pathname 是否有效\n if (!urlObj.pathname || urlObj.pathname === '/' || urlObj.pathname.length === 0) {\n return `${DEFAULT_FILENAME}${DEFAULT_EXT}`;\n }\n\n // 只使用 pathname 部分,确保不包含 query 参数\n let fileName = path.basename(urlObj.pathname);\n\n // 如果 pathname 以 / 结尾或 basename 为空,尝试从路径中提取\n if (!fileName || fileName === '/' || fileName.length === 0) {\n // 移除首尾的斜杠,然后取最后一部分\n const pathParts = urlObj.pathname.replace(/^\\/+|\\/+$/g, '').split('/');\n fileName = pathParts[pathParts.length - 1] || DEFAULT_FILENAME;\n }\n\n // 如果还是没有有效的文件名,使用默认值\n if (!fileName || fileName === '/' || fileName.length === 0) {\n return `${DEFAULT_FILENAME}${DEFAULT_EXT}`;\n }\n\n // 解码 URL 编码的字符(如 %20 -> 空格)\n try {\n fileName = decodeURIComponent(fileName);\n } catch {\n // 如果解码失败,使用原始文件名\n }\n\n // 清理文件名中的特殊字符(文件系统不允许的字符)\n // 移除或替换:/ \\ : * ? \" < > |\n fileName = fileName.replace(/[/\\\\:*?\"<>|]/g, '_');\n\n // 移除前后空格和点号(Windows 不允许)\n fileName = fileName.trim().replace(/^\\.+|\\.+$/g, '');\n\n // 如果清理后文件名为空,使用默认文件名\n if (!fileName || fileName.length === 0) {\n fileName = DEFAULT_FILENAME;\n }\n\n // 确保有扩展名\n return path.extname(fileName) ? fileName : `${fileName}${DEFAULT_EXT}`;\n } catch (error) {\n // URL 解析失败,尝试手动提取\n try {\n // 移除 query 参数和 hash\n const urlWithoutQuery = url.split('?')[0];\n const cleanUrl = urlWithoutQuery ? urlWithoutQuery.split('#')[0] : url;\n if (cleanUrl) {\n // 尝试提取最后一个路径段\n const match = cleanUrl.match(/\\/([^\\/]+)$/);\n if (match && match[1]) {\n let fileName = match[1];\n // 清理文件名\n fileName = fileName.replace(/[/\\\\:*?\"<>|]/g, '_');\n fileName = fileName.trim().replace(/^\\.+|\\.+$/g, '');\n if (fileName && fileName.length > 0) {\n return path.extname(fileName) ? fileName : `${fileName}${DEFAULT_EXT}`;\n }\n }\n }\n } catch {\n // 忽略手动提取的错误\n }\n return `${DEFAULT_FILENAME}${DEFAULT_EXT}`;\n }\n }\n\n /**\n * 解析输出路径\n * @param url 下载 URL\n * @param options 下载选项\n * @param defaultExt 默认扩展名(可选,用于 base64 URL)\n * @returns 输出文件路径\n */\n private _resolveOutputPath(url: string, options: DownloadOptions, defaultExt?: string): string {\n // 如果提供了完整路径,直接使用(但需要清理文件名部分)\n if (options.outputPath) {\n const dir = path.dirname(options.outputPath);\n const fileName = this._cleanFileName(path.basename(options.outputPath));\n return path.resolve(path.join(dir, fileName));\n }\n\n // 确定输出目录:优先使用指定的目录,否则使用 Electron 的下载目录\n const outputDir = options.outputDir\n ? path.resolve(options.outputDir)\n : app.getPath('downloads');\n\n // 使用统一的文件名获取方法\n const fileName = this._getFileName(url, options, defaultExt);\n\n return path.join(outputDir, fileName);\n }\n}\n\n/**\n * 默认下载器实例(单例)\n */\nlet defaultDownloader: Downloader | null = null;\n\n/**\n * 获取默认下载器实例\n * @returns Downloader 实例\n */\nexport function getDownloader(): Downloader {\n if (!defaultDownloader) {\n defaultDownloader = new Downloader();\n }\n return defaultDownloader;\n}\n\n/**\n * 下载文件的便捷函数\n * @param url 要下载的 URL\n * @param options 下载选项\n * @param onProgress 进度回调函数(可选)\n * @returns Promise<DownloadResult> 下载结果\n */\nexport async function downloadFile(\n url: string,\n options: DownloadOptions = {},\n onProgress?: DownloadProgressCallback\n): Promise<DownloadResult> {\n const downloader = getDownloader();\n return downloader.download(url, options, onProgress);\n}\n\n"],"names":["ipcMain","app","DownloaderHelper","BrowserWindow","dialog"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"downloader.js","sources":["../src/src/main/downloader.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport mime from 'mime-types';\nimport { DownloaderHelper } from 'node-downloader-helper';\nimport { ipcMain, dialog, BrowserWindow, app } from 'electron';\n\n/**\n * 最大重定向次数\n */\nconst MAX_REDIRECTS = 5;\n\n/**\n * 默认文件扩展名\n */\nconst DEFAULT_EXT = '.bin';\n\n/**\n * 默认 MIME 类型\n */\nconst DEFAULT_MIME_TYPE = 'application/octet-stream';\n\n/**\n * 默认超时时间(毫秒):10 分钟\n */\nconst DEFAULT_TIMEOUT = 600000;\n\n/**\n * 默认重试配置\n */\nconst DEFAULT_RETRY = {\n maxRetries: 3,\n delay: 1000\n};\n\n/**\n * 默认文件名\n */\nconst DEFAULT_FILENAME = 'download';\n\n/**\n * 最大文件名计数器(防止无限循环)\n */\nconst MAX_FILENAME_COUNTER = 10000;\n\n/**\n * 下载进度回调函数类型\n */\nexport type DownloadProgressCallback = (progress: {\n url: string; // 正在下载的 URL\n downloaded: number; // 已下载字节数\n total: number; // 总字节数(如果服务器提供 Content-Length)\n percentage: number; // 下载进度百分比 (0-100),如果 total 未知则为 -1\n speed: number; // 下载速度(字节/秒)\n}) => void;\n\n/**\n * 下载选项\n */\nexport interface DownloadOptions {\n /** 唯一标识(IPC 调用时必需) */\n id?: string;\n /** 输出文件路径(可选,如果不提供则使用 URL 的文件名) */\n outputPath?: string;\n /** 输出目录(可选,如果不提供则使用当前目录) */\n outputDir?: string;\n /** 输出文件名(可选,如果不提供则从 URL 提取) */\n fileName?: string;\n /** 是否覆盖已存在的文件(默认 true) */\n override?: boolean;\n /** 是否弹窗选择保存路径(默认 false) */\n showSaveDialog?: boolean;\n /** 保存对话框的默认文件名(可选) */\n defaultPath?: string;\n /** 超时时间(毫秒,默认 10 分钟) */\n timeout?: number;\n /** 重试配置 */\n retry?: {\n maxRetries?: number;\n delay?: number;\n };\n /** 下载进度回调函数(可选) */\n onProgress?: DownloadProgressCallback;\n /** 下载完成回调函数(可选) */\n onComplete?: (filePath: string) => void;\n /** 下载错误回调函数(可选) */\n onError?: (error: Error) => void;\n /** HTTP 请求选项 */\n httpRequestOptions?: {\n headers?: Record<string, string>;\n followRedirect?: boolean;\n maxRedirects?: number;\n };\n}\n\n/**\n * 下载结果\n */\nexport interface DownloadResult {\n /** 是否成功 */\n success: boolean;\n /** 下载的文件路径(成功时返回) */\n filePath?: string;\n /** 错误信息(失败时返回,包含错误类型和详细描述) */\n error?: string;\n /** 错误类型(失败时返回,用于区分不同类型的错误) */\n errorType?: 'NETWORK' | 'FILE_SYSTEM' | 'PERMISSION' | 'VALIDATION' | 'USER_CANCEL' | 'UNKNOWN';\n /** 文件大小(字节,成功时返回) */\n size?: number;\n}\n\n/**\n * 下载器类:提供文件下载功能\n */\nexport class Downloader {\n /** 正在下载的 URL 集合(避免重复下载) */\n private _downloadingUrls = new Map<string, DownloaderHelper>();\n /** 上一次选择的保存文件夹路径 */\n private _lastSelectedDir: string | null = null;\n\n /**\n * 构造函数:初始化下载器并注册 IPC 处理器\n * 注册 `core:downloader` IPC 处理器,用于从渲染进程接收下载请求\n */\n constructor() {\n ipcMain.handle(`core:downloader`, async (event: Electron.IpcMainInvokeEvent, options: DownloadOptions & { url: string; id: string }) => {\n try {\n const { id, url } = options;\n const sender = event.sender as Electron.WebContents;\n\n // 创建进度回调,通过 IPC 发送进度更新到渲染进程\n const progressCallback: DownloadProgressCallback = (progress) => {\n try {\n if (sender && typeof sender.send === 'function') {\n sender.send(`core:downloader:progress`, {\n id,\n data: progress\n });\n }\n } catch (error) {\n // 进度回调失败不影响下载,只记录日志\n console.error(`[Downloader] 发送下载进度失败 (ID: ${id}):`, error);\n }\n };\n\n const result = await this.download(url, options, progressCallback);\n return result;\n } catch (error) {\n // IPC 调用异常处理:解析错误并返回明确的错误信息\n const parsedError = this._parseError(error, options?.url);\n return {\n success: false,\n error: parsedError.message,\n errorType: parsedError.type\n };\n }\n });\n }\n\n /**\n * 下载文件\n *\n * 主要流程:\n * 1. 检查是否正在下载(避免重复下载)\n * 2. 确定输出路径(支持弹窗选择或自动解析)\n * 3. 验证并准备输出目录\n * 4. 处理 base64 data URL 或普通 HTTP 下载\n * 5. 使用临时文件下载,完成后重命名为最终文件\n *\n * @param url 要下载的 URL(支持 HTTP/HTTPS 和 base64 data URL)\n * @param options 下载选项(输出路径、重试配置、回调函数等)\n * @param onProgress 进度回调函数(可选,优先级高于 options.onProgress)\n * @returns Promise<DownloadResult> 下载结果,包含成功/失败状态、文件路径、错误信息等\n */\n public async download(\n url: string,\n options: DownloadOptions = {},\n onProgress?: DownloadProgressCallback\n ): Promise<DownloadResult> {\n // 参数验证:检查 URL 是否有效\n if (!url || typeof url !== 'string' || url.trim().length === 0) {\n return this._createErrorResult('下载 URL 不能为空', 'VALIDATION');\n }\n\n // 生成唯一标识:URL + ID(如果存在),用于避免重复下载\n const downloadKey = this._getDownloadKey(url, options.id);\n\n // 检查是否正在下载,避免重复下载同一资源\n if (this._downloadingUrls.has(downloadKey)) {\n return this._createErrorResult(\n `资源正在下载中,请勿重复下载: ${url}${options.id ? ` (ID: ${options.id})` : ''}`,\n 'VALIDATION'\n );\n }\n\n // 合并进度回调:优先使用传入的 onProgress,其次使用 options.onProgress\n const progressCallback = onProgress || options.onProgress;\n\n // 先检查是否是 base64 data URL(用于确定默认扩展名和特殊处理)\n const base64Info = this._isBase64DataUrl(url);\n const defaultExt = base64Info.isBase64 && base64Info.ext ? base64Info.ext : undefined;\n\n // 确定输出路径:支持弹窗选择或自动解析\n let outputPath: string;\n try {\n if (options.showSaveDialog) {\n // 显示保存对话框,让用户选择保存位置\n const savePath = await this._showSaveDialog(url, options, defaultExt);\n if (!savePath) {\n return this._createErrorResult('用户取消了保存操作', 'USER_CANCEL');\n }\n outputPath = savePath;\n } else {\n // 自动解析输出路径\n outputPath = this._resolveOutputPath(url, options, defaultExt);\n }\n\n // 验证 outputPath 是否有效\n if (!outputPath || typeof outputPath !== 'string' || outputPath.trim().length === 0) {\n return this._createErrorResult(\n '无法确定输出路径:路径解析结果无效',\n 'VALIDATION'\n );\n }\n } catch (error) {\n // 路径解析失败:可能是文件系统错误或权限问题\n const parsedError = this._parseError(error, url);\n return this._createErrorResult(\n `确定输出路径失败: ${parsedError.message}`,\n parsedError.type\n );\n }\n\n // 准备输出路径:确保目录存在、检查文件是否已存在\n try {\n const pathCheckResult = await this._prepareOutputPath(outputPath, options);\n if (pathCheckResult) {\n // 文件已存在且不允许覆盖,直接返回已存在的文件信息\n return pathCheckResult;\n }\n } catch (error) {\n // 路径准备失败:可能是权限问题或文件系统错误\n const parsedError = this._parseError(error, url);\n return this._createErrorResult(\n `准备输出路径失败: ${parsedError.message}`,\n parsedError.type\n );\n }\n\n // 提取下载目录和文件名\n let downloadDir = path.dirname(outputPath);\n let downloadFileName = path.basename(outputPath);\n\n // 再次清理文件名,确保不包含 query 参数和特殊字符(防止文件系统错误)\n downloadFileName = this._cleanFileName(downloadFileName);\n\n // 验证下载目录是否可访问,如果不可用则使用系统下载目录作为备用\n if (!this._isDirectoryAccessible(downloadDir)) {\n try {\n downloadDir = app.getPath('downloads');\n // 确保备用目录存在(如果不存在则创建)\n if (!fs.existsSync(downloadDir)) {\n fs.mkdirSync(downloadDir, { recursive: true });\n }\n // 验证备用目录是否可访问\n if (!this._isDirectoryAccessible(downloadDir)) {\n return this._createErrorResult(\n `无法访问下载目录: ${downloadDir},请检查目录权限`,\n 'PERMISSION'\n );\n }\n } catch (error) {\n const parsedError = this._parseError(error, url);\n return this._createErrorResult(\n `无法创建或访问备用下载目录: ${parsedError.message}`,\n parsedError.type\n );\n }\n }\n\n // 更新 outputPath 使用清理后的文件名和验证后的目录\n outputPath = path.join(downloadDir, downloadFileName);\n\n // 如果是 base64 data URL,使用已确定的输出路径进行特殊处理(无需网络请求)\n if (base64Info.isBase64 && base64Info.ext && base64Info.mimeType && base64Info.data) {\n return await this._handleBase64Download(\n url,\n { ext: base64Info.ext, mimeType: base64Info.mimeType, data: base64Info.data },\n outputPath,\n options,\n progressCallback\n );\n }\n\n // 使用临时文件下载(.cache 后缀),避免下载中断时文件不完整\n // 下载完成后会将临时文件重命名为最终文件\n const tempFilePath = path.join(downloadDir, downloadFileName + '.cache');\n\n return new Promise<DownloadResult>((resolve, reject) => {\n // 创建下载器实例(使用 node-downloader-helper)\n const dl = new DownloaderHelper(url, downloadDir, {\n fileName: downloadFileName + '.cache',\n retry: {\n maxRetries: options.retry?.maxRetries ?? DEFAULT_RETRY.maxRetries,\n delay: options.retry?.delay ?? DEFAULT_RETRY.delay\n },\n timeout: options.timeout ?? DEFAULT_TIMEOUT,\n override: true, // 临时文件总是覆盖,避免残留文件\n httpRequestOptions: {\n followRedirect: options.httpRequestOptions?.followRedirect ?? true,\n maxRedirects: options.httpRequestOptions?.maxRedirects ?? MAX_REDIRECTS,\n headers: options.httpRequestOptions?.headers\n }\n });\n\n // 记录正在下载的 URL(使用 URL + ID 作为 key),用于避免重复下载\n this._downloadingUrls.set(downloadKey, dl);\n\n // 监听下载进度事件\n if (progressCallback) {\n dl.on('progress', (stats) => {\n try {\n progressCallback({\n url,\n downloaded: stats.downloaded || 0,\n total: stats.total || 0,\n percentage: stats.progress !== undefined ? Math.round(stats.progress) : -1,\n speed: stats.speed || 0\n });\n } catch (error) {\n // 进度回调失败不影响下载,只记录日志\n console.error(`[Downloader] 进度回调执行失败 (${url}):`, error);\n }\n });\n }\n\n // 监听下载完成事件\n dl.on('end', () => {\n // 从下载列表中移除\n this._downloadingUrls.delete(downloadKey);\n\n // 将临时文件重命名为最终文件(原子操作,确保文件完整性)\n fs.rename(tempFilePath, outputPath, (renameErr) => {\n if (renameErr) {\n // 文件重命名失败:可能是权限问题或文件被占用\n const parsedError = this._parseError(renameErr, url);\n const error = new Error(\n `文件重命名失败: 无法将临时文件 \"${tempFilePath}\" 重命名为 \"${outputPath}\"。${parsedError.message}`\n );\n\n // 调用错误回调\n if (options.onError) {\n options.onError(error);\n }\n\n // reject 应该传入 Error 对象,而不是 DownloadResult\n // 将错误类型附加到错误对象上\n (error as any).errorType = parsedError.type;\n reject(error);\n } else {\n try {\n // 获取文件大小并返回成功结果\n const stats = fs.statSync(outputPath);\n const result = this._createSuccessResult(outputPath, stats.size);\n\n // 调用完成回调\n if (options.onComplete) {\n options.onComplete(outputPath);\n }\n\n resolve(result);\n } catch (error) {\n // 获取文件信息失败\n const parsedError = this._parseError(error, url);\n const errorObj = new Error(`下载完成但无法获取文件信息: ${parsedError.message}`);\n // 将错误类型附加到错误对象上\n (errorObj as any).errorType = parsedError.type;\n reject(errorObj);\n }\n }\n });\n });\n\n // 统一的错误处理函数\n const handleError = (error: Error | unknown, isUserCancel: boolean = false) => {\n // 从下载列表中移除\n this._downloadingUrls.delete(downloadKey);\n\n // 清理临时文件(忽略删除失败,避免影响错误处理)\n fs.promises.unlink(tempFilePath).catch(() => {\n // 临时文件删除失败不影响错误处理流程\n });\n\n // 解析错误信息\n const parsedError = this._parseError(error, url);\n const errorType = isUserCancel ? 'USER_CANCEL' : parsedError.type;\n const errorMessage = isUserCancel\n ? `下载已取消: ${url}`\n : parsedError.message;\n\n // 创建错误对象(包含错误类型信息)\n const errorObj = new Error(errorMessage);\n // 将错误类型附加到错误对象上,供 catch 处理时使用\n (errorObj as any).errorType = errorType;\n\n // 调用错误回调\n if (options.onError) {\n options.onError(errorObj);\n }\n\n // reject 应该传入 Error 对象,而不是 DownloadResult\n reject(errorObj);\n };\n\n // 监听下载错误事件(网络错误、服务器错误等)\n dl.on('error', (err) => {\n const error = err instanceof Error ? err : new Error(`下载失败: ${url}`);\n handleError(error, false);\n });\n\n // 监听下载停止事件(用户取消或手动停止)\n dl.on('stop', () => {\n const error = new Error(`下载已停止: ${url}`);\n handleError(error, true);\n });\n\n // 开始下载\n dl.start().catch((err) => {\n // 启动下载失败:可能是 URL 无效、网络不可达等\n const error = err instanceof Error ? err : new Error(`启动下载失败: ${url}`);\n handleError(error, false);\n });\n }).catch((error): DownloadResult => {\n // Promise 异常捕获:返回格式化的错误结果\n // 如果错误对象已经包含 errorType,直接使用;否则解析错误\n if (error instanceof Error && (error as any).errorType) {\n return this._createErrorResult(error.message, (error as any).errorType);\n }\n const parsedError = this._parseError(error, url);\n return this._createErrorResult(parsedError.message, parsedError.type);\n });\n }\n\n /**\n * 生成下载任务的唯一标识\n * @param url 下载 URL\n * @param id 可选的任务 ID\n * @returns 唯一标识\n */\n private _getDownloadKey(url: string, id?: string): string {\n return id ? `${url}::${id}` : url;\n }\n\n /**\n * 取消下载\n * @param url 要取消的 URL\n * @param id 可选的任务 ID\n * @returns 是否成功取消\n */\n public cancel(url: string, id?: string): boolean {\n const downloadKey = this._getDownloadKey(url, id);\n const dl = this._downloadingUrls.get(downloadKey);\n if (dl) {\n dl.stop();\n this._downloadingUrls.delete(downloadKey);\n return true;\n }\n return false;\n }\n\n /**\n * 取消所有正在进行的下载\n */\n public cancelAll(): void {\n for (const [url, dl] of this._downloadingUrls.entries()) {\n dl.stop();\n }\n this._downloadingUrls.clear();\n }\n\n /**\n * 检查指定 URL 是否正在下载\n * @param url 要检查的 URL\n * @param id 可选的任务 ID\n * @returns 是否正在下载\n */\n public isDownloading(url: string, id?: string): boolean {\n const downloadKey = this._getDownloadKey(url, id);\n return this._downloadingUrls.has(downloadKey);\n }\n\n /**\n * 获取正在下载的任务列表\n * @returns 正在下载的任务信息数组,包含 URL 和 ID(如果有)\n */\n public getDownloadingUrls(): Array<{ url: string; id?: string }> {\n return Array.from(this._downloadingUrls.keys()).map(key => {\n const parts = key.split('::');\n if (parts.length === 2 && parts[0] && parts[1]) {\n return { url: parts[0], id: parts[1] };\n }\n return { url: key };\n });\n }\n\n /**\n * 获取文件名(统一处理所有来源)\n * @param url 下载 URL\n * @param options 下载选项\n * @param defaultExt 默认扩展名(可选,用于 base64 URL)\n * @returns 清理后的文件名\n */\n private _getFileName(url: string, options: DownloadOptions, defaultExt?: string): string {\n // 优先级:defaultPath > fileName > defaultExt > URL提取\n if (options.defaultPath) {\n return this._cleanFileName(path.basename(options.defaultPath));\n }\n\n if (options.fileName) {\n return this._cleanFileName(options.fileName);\n }\n\n if (defaultExt) {\n return this._cleanFileName(`${DEFAULT_FILENAME}.${defaultExt}`);\n }\n // 从 URL 中提取文件名(_extractFileNameFromUrl 已经包含清理逻辑)\n return this._extractFileNameFromUrl(url);\n }\n\n /**\n * 检查目录是否存在且有访问权限\n *\n * 检查项:\n * 1. 路径是否有效(非空字符串)\n * 2. 目录是否存在\n * 3. 路径是否为目录(而非文件)\n * 4. 是否有读写权限\n *\n * @param dirPath 目录路径\n * @returns 如果目录存在且有读写权限则返回 true,否则返回 false\n */\n private _isDirectoryAccessible(dirPath: string): boolean {\n // 参数验证:检查路径是否有效\n if (!dirPath || typeof dirPath !== 'string') {\n return false;\n }\n\n try {\n // 检查目录是否存在\n if (!fs.existsSync(dirPath)) {\n return false;\n }\n\n // 检查是否是目录(而非文件)\n const stats = fs.statSync(dirPath);\n if (!stats.isDirectory()) {\n return false;\n }\n\n // 检查是否有读写权限(R_OK: 读权限, W_OK: 写权限)\n fs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK);\n return true;\n } catch {\n // 如果任何检查失败(不存在、不是目录、无权限等),返回 false\n return false;\n }\n }\n\n /**\n * 显示保存对话框\n *\n * 功能说明:\n * 1. 确定默认保存目录(优先级:defaultPath > outputDir > _lastSelectedDir > 系统下载目录)\n * 2. 验证并更新 _lastSelectedDir(如果不可访问则重置)\n * 3. 生成唯一文件名(如果文件已存在,添加数字后缀)\n * 4. 显示 Electron 保存对话框\n * 5. 记录用户选择的目录(用于下次默认使用)\n *\n * @param url 下载 URL(用于提取默认文件名)\n * @param options 下载选项(包含 defaultPath、outputDir 等)\n * @param defaultExt 默认扩展名(可选,用于 base64 URL)\n * @returns Promise<string | null> 用户选择的保存路径,如果取消则返回 null\n */\n private async _showSaveDialog(url: string, options: DownloadOptions, defaultExt?: string): Promise<string | null> {\n // 获取并清理默认文件名\n let defaultFileName = this._getFileName(url, options, defaultExt);\n\n // 获取默认目录\n let defaultDir: string | undefined;\n if (options.defaultPath) {\n defaultDir = path.dirname(options.defaultPath);\n } else if (options.outputDir) {\n defaultDir = path.resolve(options.outputDir);\n } else {\n // 如果没有指定目录,使用上一次选择的文件夹,如果没有则使用下载目录\n // 检查 _lastSelectedDir 是否可用,如果不可用则重置为下载目录\n if (this._lastSelectedDir && !this._isDirectoryAccessible(this._lastSelectedDir)) {\n const downloadsPath = app.getPath('downloads');\n // 验证下载目录是否可用,如果可用则使用,否则设为 null\n this._lastSelectedDir = this._isDirectoryAccessible(downloadsPath) ? downloadsPath : null;\n }\n defaultDir = this._lastSelectedDir || app.getPath('downloads');\n }\n\n // 如果指定了目录,检查文件是否存在并生成唯一文件名\n if (defaultDir) {\n defaultFileName = this._generateUniqueFileName(defaultDir, defaultFileName);\n }\n\n // 构建默认路径\n const defaultPath = defaultDir ? path.join(defaultDir, defaultFileName) : defaultFileName;\n\n // 获取当前活动的 BrowserWindow\n const focusedWindow = BrowserWindow.getFocusedWindow();\n const allWindows = BrowserWindow.getAllWindows();\n const parentWindow = focusedWindow || (allWindows.length > 0 ? allWindows[0] : undefined);\n\n // 显示保存对话框\n const dialogOptions = {\n defaultPath,\n title: '保存文件',\n buttonLabel: '保存',\n filters: [\n // 尝试从文件名推断文件类型\n ...(path.extname(defaultFileName) ? [{\n name: '所有文件',\n extensions: ['*']\n }] : [])\n ]\n };\n\n // 根据是否有父窗口调用不同的方法\n const result = parentWindow\n ? await dialog.showSaveDialog(parentWindow, dialogOptions)\n : await dialog.showSaveDialog(dialogOptions);\n\n if (result.canceled || !result.filePath) {\n return null;\n }\n\n // 记录用户选择的文件夹路径,用于下次默认使用\n const selectedDir = path.dirname(result.filePath);\n if (selectedDir) {\n // 验证选择的目录是否可访问,只有可访问时才保存\n if (this._isDirectoryAccessible(selectedDir)) {\n this._lastSelectedDir = selectedDir;\n } else {\n // 如果选择的目录不可访问,尝试使用下载目录\n const downloadsPath = app.getPath('downloads');\n this._lastSelectedDir = this._isDirectoryAccessible(downloadsPath) ? downloadsPath : null;\n }\n }\n\n return result.filePath;\n }\n\n /**\n * 检测并处理 base64 data URL\n * @param url 资源URL\n * @returns 如果是 base64 URL,返回 true、文件扩展名、MIME 类型和数据;否则返回 false\n */\n private _isBase64DataUrl(url: string): { isBase64: boolean, ext?: string, mimeType?: string, data?: string } {\n if (!url.startsWith('data:')) {\n return { isBase64: false };\n }\n\n try {\n // 解析 data URL 格式:data:[<mediatype>][;base64],<data>\n const commaIndex = url.indexOf(',');\n if (commaIndex === -1) {\n return { isBase64: false };\n }\n\n const header = url.substring(0, commaIndex);\n const data = url.substring(commaIndex + 1);\n\n // 检查是否包含 base64 标识\n if (!header.includes('base64')) {\n return { isBase64: false };\n }\n\n // 从 mediatype 中提取文件扩展名和 MIME 类型\n // 例如:data:image/png;base64 -> png, image/png\n // 例如:data:image/jpeg;base64 -> jpeg, image/jpeg\n let ext = DEFAULT_EXT.replace(/^\\./, '');\n let mimeType = DEFAULT_MIME_TYPE;\n const mimeMatch = header.match(/data:([^;]+)/);\n if (mimeMatch && mimeMatch[1]) {\n mimeType = mimeMatch[1];\n // 使用 mime-types 包从 MIME 类型获取扩展名\n const extension = mime.extension(mimeType);\n if (extension) {\n ext = extension;\n }\n }\n\n return { isBase64: true, ext, mimeType, data };\n } catch (error) {\n return { isBase64: false };\n }\n }\n\n /**\n * 保存 base64 数据到文件\n *\n * 处理流程:\n * 1. 将 base64 字符串解码为 Buffer\n * 2. 将 Buffer 写入目标文件路径\n *\n * @param base64Data base64 编码的数据字符串\n * @param filePath 目标文件路径(完整路径,包含文件名)\n * @throws 如果解码失败或文件写入失败,抛出错误\n */\n private async _saveBase64ToFile(base64Data: string, filePath: string): Promise<void> {\n try {\n // 解码 base64 数据为 Buffer\n const buffer = Buffer.from(base64Data, 'base64');\n\n // 使用 Promise 版本的 writeFile 写入文件\n // Buffer 继承自 Uint8Array,可以直接使用\n await fs.promises.writeFile(filePath, buffer as Uint8Array);\n } catch (error) {\n // 文件保存失败:可能是权限问题、磁盘空间不足、路径无效等\n const errorMessage = error instanceof Error ? error.message : '未知错误';\n throw new Error(`保存 base64 文件失败 (${filePath}): ${errorMessage}`);\n }\n }\n\n /**\n * 准备输出路径\n *\n * 主要功能:\n * 1. 确保输出目录存在(不存在则创建)\n * 2. 检查文件是否已存在\n * 3. 如果文件已存在且不允许覆盖,返回已存在的文件信息\n *\n * @param outputPath 输出文件路径\n * @param options 下载选项(包含 override 选项)\n * @returns 如果文件已存在且不允许覆盖,返回已存在的文件信息;否则返回 null\n * @throws 如果目录创建失败或权限不足,抛出错误\n */\n private async _prepareOutputPath(\n outputPath: string,\n options: DownloadOptions\n ): Promise<DownloadResult | null> {\n // 参数验证:确保 outputPath 是有效的非空字符串\n if (!outputPath || typeof outputPath !== 'string' || outputPath.trim().length === 0) {\n throw new Error(`输出路径无效: ${outputPath}`);\n }\n\n // 规范化路径(解析相对路径、处理 .. 等)\n const normalizedPath = path.resolve(outputPath);\n\n // 验证规范化后的路径是否有效\n if (!normalizedPath || normalizedPath.trim().length === 0) {\n throw new Error(`无法解析输出路径: ${outputPath}`);\n }\n\n const downloadDir = path.dirname(normalizedPath);\n\n // 使用规范化后的路径\n outputPath = normalizedPath;\n\n // 确保目录存在:如果不存在则创建(递归创建父目录)\n if (!fs.existsSync(downloadDir)) {\n try {\n fs.mkdirSync(downloadDir, { recursive: true });\n } catch (error) {\n // 目录创建失败:可能是权限问题或路径无效\n const parsedError = this._parseError(error);\n throw new Error(`无法创建输出目录 \"${downloadDir}\": ${parsedError.message}`);\n }\n }\n\n // 验证目录是否可访问\n if (!this._isDirectoryAccessible(downloadDir)) {\n throw new Error(`无法访问输出目录 \"${downloadDir}\",请检查目录权限`);\n }\n\n // 如果文件已存在且不允许覆盖,直接返回已存在的文件信息\n if (fs.existsSync(outputPath) && !(options.override ?? true)) {\n try {\n const stats = fs.statSync(outputPath);\n return this._createSuccessResult(outputPath, stats.size);\n } catch (error) {\n // 获取文件信息失败:可能是权限问题\n const parsedError = this._parseError(error);\n throw new Error(`无法访问已存在的文件 \"${outputPath}\": ${parsedError.message}`);\n }\n }\n\n return null;\n }\n\n /**\n * 创建成功结果\n * @param filePath 文件路径\n * @param size 文件大小(字节)\n * @returns DownloadResult 成功结果对象\n */\n private _createSuccessResult(filePath: string, size: number): DownloadResult {\n return {\n success: true,\n filePath,\n size\n };\n }\n\n /**\n * 创建错误结果\n * @param error 错误信息\n * @param errorType 错误类型(可选,用于区分不同类型的错误)\n * @returns DownloadResult 错误结果对象\n */\n private _createErrorResult(error: string, errorType?: DownloadResult['errorType']): DownloadResult {\n return {\n success: false,\n error,\n errorType: errorType || 'UNKNOWN'\n };\n }\n\n /**\n * 从错误对象中提取错误类型和详细信息\n * @param error 错误对象\n * @param url 下载的 URL(用于上下文信息)\n * @returns 包含错误类型和详细错误信息的对象\n */\n private _parseError(error: unknown, url?: string): { type: DownloadResult['errorType']; message: string } {\n if (error instanceof Error) {\n const errorMessage = error.message.toLowerCase();\n const errorCode = (error as any).code?.toLowerCase() || '';\n\n // 网络相关错误\n if (\n errorMessage.includes('network') ||\n errorMessage.includes('timeout') ||\n errorMessage.includes('econnrefused') ||\n errorMessage.includes('enotfound') ||\n errorMessage.includes('etimedout') ||\n errorCode.includes('timeout') ||\n errorCode.includes('econnrefused') ||\n errorCode.includes('enotfound') ||\n errorCode.includes('etimedout')\n ) {\n return {\n type: 'NETWORK',\n message: `网络错误: ${error.message}${url ? ` (URL: ${url})` : ''}`\n };\n }\n\n // 文件系统相关错误\n if (\n errorMessage.includes('enoent') ||\n errorMessage.includes('eacces') ||\n errorMessage.includes('eperm') ||\n errorMessage.includes('file') ||\n errorMessage.includes('directory') ||\n errorMessage.includes('path') ||\n errorCode.includes('enoent') ||\n errorCode.includes('eacces') ||\n errorCode.includes('eperm')\n ) {\n if (errorMessage.includes('permission') || errorMessage.includes('eacces') || errorMessage.includes('eperm')) {\n return {\n type: 'PERMISSION',\n message: `权限错误: ${error.message}${url ? ` (URL: ${url})` : ''}`\n };\n }\n return {\n type: 'FILE_SYSTEM',\n message: `文件系统错误: ${error.message}${url ? ` (URL: ${url})` : ''}`\n };\n }\n\n // 验证相关错误\n if (\n errorMessage.includes('invalid') ||\n errorMessage.includes('validation') ||\n errorMessage.includes('格式') ||\n errorMessage.includes('无效')\n ) {\n return {\n type: 'VALIDATION',\n message: `验证错误: ${error.message}${url ? ` (URL: ${url})` : ''}`\n };\n }\n\n // 用户取消\n if (errorMessage.includes('cancel') || errorMessage.includes('取消')) {\n return {\n type: 'USER_CANCEL',\n message: error.message\n };\n }\n\n // 其他错误\n return {\n type: 'UNKNOWN',\n message: `未知错误: ${error.message}${url ? ` (URL: ${url})` : ''}`\n };\n }\n\n // 非 Error 对象\n return {\n type: 'UNKNOWN',\n message: `未知错误: ${String(error)}${url ? ` (URL: ${url})` : ''}`\n };\n }\n\n /**\n * 处理 base64 data URL 的下载\n *\n * base64 data URL 格式:data:[<mediatype>][;base64],<data>\n * 例如:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...\n *\n * 处理流程:\n * 1. 验证 base64 数据有效性\n * 2. 触发进度回调(模拟 100% 完成)\n * 3. 解码并保存 base64 数据到文件\n * 4. 返回成功结果\n *\n * @param url base64 data URL\n * @param base64Info base64 信息(扩展名、MIME 类型、数据)\n * @param outputPath 已确定的输出路径\n * @param options 下载选项\n * @param progressCallback 进度回调(可选)\n * @returns Promise<DownloadResult> 下载结果\n */\n private async _handleBase64Download(\n url: string,\n base64Info: { ext: string; mimeType: string; data: string },\n outputPath: string,\n options: DownloadOptions,\n progressCallback?: DownloadProgressCallback\n ): Promise<DownloadResult> {\n // 验证 base64 数据有效性\n if (!base64Info.data || !base64Info.ext) {\n return this._createErrorResult(\n `无效的 base64 data URL: 缺少数据或扩展名 (URL: ${url.substring(0, 50)}...)`,\n 'VALIDATION'\n );\n }\n\n try {\n // 计算数据长度(用于进度回调)\n const dataLength = Buffer.from(base64Info.data, 'base64').length;\n\n // 模拟进度回调(base64 数据通常很小,立即完成)\n if (progressCallback) {\n progressCallback({\n url,\n downloaded: dataLength,\n total: dataLength,\n percentage: 100,\n speed: 0\n });\n }\n\n // 保存 base64 数据到文件\n await this._saveBase64ToFile(base64Info.data, outputPath);\n\n // 获取文件大小并返回成功结果\n const stats = fs.statSync(outputPath);\n const result = this._createSuccessResult(outputPath, stats.size);\n\n // 调用完成回调\n if (options.onComplete) {\n options.onComplete(outputPath);\n }\n\n return result;\n } catch (error) {\n // base64 文件保存失败:可能是文件系统错误或权限问题\n const parsedError = this._parseError(error, url);\n const err = error instanceof Error ? error : new Error(`保存 base64 文件失败: ${parsedError.message}`);\n\n // 调用错误回调\n if (options.onError) {\n options.onError(err);\n }\n\n return this._createErrorResult(\n `保存 base64 文件失败: ${parsedError.message}`,\n parsedError.type\n );\n }\n }\n\n /**\n * 生成唯一的文件名(如果文件已存在,添加数字后缀)\n *\n * 命名规则:\n * - 如果文件不存在,返回原始文件名\n * - 如果文件已存在,添加数字后缀:filename(1).ext, filename(2).ext, ...\n * - 最多尝试 MAX_FILENAME_COUNTER 次,防止无限循环\n *\n * 示例:\n * - \"test.pdf\" -> \"test.pdf\" (如果不存在)\n * - \"test.pdf\" -> \"test(1).pdf\" (如果 test.pdf 已存在)\n * - \"test(1).pdf\" -> \"test(2).pdf\" (如果 test(1).pdf 也已存在)\n *\n * @param dir 目录路径\n * @param fileName 原始文件名(包含扩展名)\n * @returns 唯一的文件名(如果原文件不存在则返回原文件名,否则返回带数字后缀的文件名)\n */\n private _generateUniqueFileName(dir: string, fileName: string): string {\n // 分离文件名和扩展名\n const ext = path.extname(fileName);\n const nameWithoutExt = path.basename(fileName, ext);\n\n // 检查原始文件名是否存在\n const originalPath = path.join(dir, fileName);\n if (!fs.existsSync(originalPath)) {\n return fileName;\n }\n\n // 如果存在,尝试添加数字后缀\n let counter = 1;\n let newFileName: string;\n let newPath: string;\n\n do {\n newFileName = `${nameWithoutExt}(${counter})${ext}`;\n newPath = path.join(dir, newFileName);\n counter++;\n } while (fs.existsSync(newPath) && counter < MAX_FILENAME_COUNTER);\n\n return newFileName;\n }\n\n /**\n * 清理文件名,移除 query 参数和特殊字符\n * @param fileName 原始文件名\n * @returns 清理后的文件名\n */\n private _cleanFileName(fileName: string): string {\n if (!fileName || fileName.length === 0) {\n return DEFAULT_FILENAME;\n }\n\n // 移除 query 参数(如果文件名中包含 ?)\n const queryIndex = fileName.indexOf('?');\n if (queryIndex !== -1) {\n fileName = fileName.substring(0, queryIndex);\n }\n\n // 解码 URL 编码的字符(如 %20 -> 空格)\n try {\n fileName = decodeURIComponent(fileName);\n } catch {\n // 如果解码失败,使用原始文件名\n }\n\n // 清理文件名中的特殊字符(文件系统不允许的字符)\n // 移除或替换:/ \\ : * ? \" < > |\n fileName = fileName.replace(/[/\\\\:*?\"<>|]/g, '_');\n\n // 移除前后空格和点号(Windows 不允许)\n fileName = fileName.trim().replace(/^\\.+|\\.+$/g, '');\n\n // 如果清理后文件名为空,使用默认文件名\n if (!fileName || fileName.length === 0) {\n fileName = DEFAULT_FILENAME;\n }\n\n return fileName;\n }\n\n /**\n * 从 URL 中提取文件名\n * @param url 下载 URL\n * @returns 文件名(已清理特殊字符,不包含query参数)\n */\n private _extractFileNameFromUrl(url: string): string {\n if (!url || typeof url !== 'string' || url.trim().length === 0) {\n return `${DEFAULT_FILENAME}${DEFAULT_EXT}`;\n }\n\n try {\n // 确保 URL 是完整的(如果缺少协议,添加 https://)\n let normalizedUrl = url.trim();\n if (!normalizedUrl.match(/^https?:\\/\\//i)) {\n normalizedUrl = `https://${normalizedUrl}`;\n }\n\n const urlObj = new URL(normalizedUrl);\n\n // 验证 pathname 是否有效\n if (!urlObj.pathname || urlObj.pathname === '/' || urlObj.pathname.length === 0) {\n return `${DEFAULT_FILENAME}${DEFAULT_EXT}`;\n }\n\n // 只使用 pathname 部分,确保不包含 query 参数\n let fileName = path.basename(urlObj.pathname);\n\n // 如果 pathname 以 / 结尾或 basename 为空,尝试从路径中提取\n if (!fileName || fileName === '/' || fileName.length === 0) {\n // 移除首尾的斜杠,然后取最后一部分\n const pathParts = urlObj.pathname.replace(/^\\/+|\\/+$/g, '').split('/');\n fileName = pathParts[pathParts.length - 1] || DEFAULT_FILENAME;\n }\n\n // 如果还是没有有效的文件名,使用默认值\n if (!fileName || fileName === '/' || fileName.length === 0) {\n return `${DEFAULT_FILENAME}${DEFAULT_EXT}`;\n }\n\n // 解码 URL 编码的字符(如 %20 -> 空格)\n try {\n fileName = decodeURIComponent(fileName);\n } catch {\n // 如果解码失败,使用原始文件名\n }\n\n // 清理文件名中的特殊字符(文件系统不允许的字符)\n // 移除或替换:/ \\ : * ? \" < > |\n fileName = fileName.replace(/[/\\\\:*?\"<>|]/g, '_');\n\n // 移除前后空格和点号(Windows 不允许)\n fileName = fileName.trim().replace(/^\\.+|\\.+$/g, '');\n\n // 如果清理后文件名为空,使用默认文件名\n if (!fileName || fileName.length === 0) {\n fileName = DEFAULT_FILENAME;\n }\n\n // 确保有扩展名\n return path.extname(fileName) ? fileName : `${fileName}${DEFAULT_EXT}`;\n } catch (error) {\n // URL 解析失败,尝试手动提取\n try {\n // 移除 query 参数和 hash\n const urlWithoutQuery = url.split('?')[0];\n const cleanUrl = urlWithoutQuery ? urlWithoutQuery.split('#')[0] : url;\n if (cleanUrl) {\n // 尝试提取最后一个路径段\n const match = cleanUrl.match(/\\/([^\\/]+)$/);\n if (match && match[1]) {\n let fileName = match[1];\n // 清理文件名\n fileName = fileName.replace(/[/\\\\:*?\"<>|]/g, '_');\n fileName = fileName.trim().replace(/^\\.+|\\.+$/g, '');\n if (fileName && fileName.length > 0) {\n return path.extname(fileName) ? fileName : `${fileName}${DEFAULT_EXT}`;\n }\n }\n }\n } catch {\n // 忽略手动提取的错误\n }\n return `${DEFAULT_FILENAME}${DEFAULT_EXT}`;\n }\n }\n\n /**\n * 解析输出路径\n * @param url 下载 URL\n * @param options 下载选项\n * @param defaultExt 默认扩展名(可选,用于 base64 URL)\n * @returns 输出文件路径\n * @throws 如果无法解析有效路径,抛出错误\n */\n private _resolveOutputPath(url: string, options: DownloadOptions, defaultExt?: string): string {\n // 如果提供了完整路径,直接使用(但需要清理文件名部分)\n if (options.outputPath) {\n // 验证 outputPath 是否有效\n if (typeof options.outputPath !== 'string' || options.outputPath.trim().length === 0) {\n throw new Error(`无效的输出路径: ${options.outputPath}`);\n }\n\n try {\n const dir = path.dirname(options.outputPath);\n const fileName = this._cleanFileName(path.basename(options.outputPath));\n\n // 验证文件名是否有效\n if (!fileName || fileName.trim().length === 0) {\n throw new Error(`无法从路径中提取有效文件名: ${options.outputPath}`);\n }\n\n const resolvedPath = path.resolve(path.join(dir, fileName));\n\n // 验证解析后的路径是否有效\n if (!resolvedPath || resolvedPath.trim().length === 0) {\n throw new Error(`路径解析失败: ${options.outputPath}`);\n }\n\n return resolvedPath;\n } catch (error) {\n if (error instanceof Error) {\n throw error;\n }\n throw new Error(`解析输出路径失败: ${String(error)}`);\n }\n }\n\n // 确定输出目录:优先使用指定的目录,否则使用 Electron 的下载目录\n let outputDir: string;\n try {\n if (options.outputDir) {\n if (typeof options.outputDir !== 'string' || options.outputDir.trim().length === 0) {\n throw new Error(`无效的输出目录: ${options.outputDir}`);\n }\n outputDir = path.resolve(options.outputDir);\n } else {\n outputDir = app.getPath('downloads');\n }\n\n // 验证输出目录是否有效\n if (!outputDir || outputDir.trim().length === 0) {\n throw new Error('无法获取有效的输出目录');\n }\n } catch (error) {\n if (error instanceof Error) {\n throw error;\n }\n throw new Error(`确定输出目录失败: ${String(error)}`);\n }\n\n // 使用统一的文件名获取方法\n const fileName = this._getFileName(url, options, defaultExt);\n\n // 验证文件名是否有效\n if (!fileName || fileName.trim().length === 0) {\n throw new Error('无法获取有效的文件名');\n }\n\n const finalPath = path.join(outputDir, fileName);\n\n // 验证最终路径是否有效\n if (!finalPath || finalPath.trim().length === 0) {\n throw new Error('无法构建有效的输出路径');\n }\n\n return finalPath;\n }\n}\n\n/**\n * 默认下载器实例(单例)\n */\nlet defaultDownloader: Downloader | null = null;\n\n/**\n * 获取默认下载器实例\n * @returns Downloader 实例\n */\nexport function getDownloader(): Downloader {\n if (!defaultDownloader) {\n defaultDownloader = new Downloader();\n }\n return defaultDownloader;\n}\n\n/**\n * 下载文件的便捷函数\n * @param url 要下载的 URL\n * @param options 下载选项\n * @param onProgress 进度回调函数(可选)\n * @returns Promise<DownloadResult> 下载结果\n */\nexport async function downloadFile(\n url: string,\n options: DownloadOptions = {},\n onProgress?: DownloadProgressCallback\n): Promise<DownloadResult> {\n const downloader = getDownloader();\n return downloader.download(url, options, onProgress);\n}\n\n"],"names":["ipcMain","app","DownloaderHelper","BrowserWindow","dialog"],"mappings":"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"}
|
package/main/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/main/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAS3C,OAAO,KAAK,GAAG,MAAM,mCAAmC,CAAA;AAExD,OAAO,KAAK,aAAa,MAAM,8CAA8C,CAAA;AAC7E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gDAAgD,CAAA;AAC9F,OAAO,EAAuB,KAAK,YAAY,EAAE,KAAK,oBAAoB,EAAE,KAAK,qBAAqB,EAAE,KAAK,mBAAmB,EAAqB,MAAM,WAAW,CAAC;AACvK,OAAO,EAAmB,WAAW,EAAgB,MAAM,SAAS,CAAC;AAGrE,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE5E,OAAO,EAAkC,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,KAAK,aAAa,MAAM,gBAAgB,CAAC;AAGhD,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,WAAW,EAAE,CAAC;AAMjE,eAAO,IAAI,aAAa,SAAQ,CAAC;AAIjC,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,OAAO,GAAG,CAAC,OAAO,CAAC;IACxB,aAAa,EAAE,aAAa,CAAC,cAAc,CAAC;IAC5C,UAAU,EAAE,MAAM,MAAM,CAAC;IACzB,aAAa,EAAE,CAAC,OAAO,EAAE,oBAAoB,EAAE,SAAS,CAAC,EAAE,qBAAqB,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAClH,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,KAAK,CAAC;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;IACrJ,gBAAgB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC;IAC7D,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,aAAa,CAAC;IAC7C,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;IAC5C,UAAU,EAAE,UAAU,CAAC;CACxB;AAkBD;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,YAAa;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IAAC,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IAAC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,KAAG,QAsGxU,CAAA;AAED,YAAY;AACZ,eAAO,MAAM,MAAM,QAAO,QAOzB,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,aAGT,MAAM,SAoDtB,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,KAAK,YAAa,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/main/index.ts"],"names":[],"mappings":"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"}
|
package/main/index.js
CHANGED
|
@@ -255,17 +255,49 @@ const serve = (options) => {
|
|
|
255
255
|
};
|
|
256
256
|
const createHandler = (item) => {
|
|
257
257
|
return async (request, callback) => {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
258
|
+
try {
|
|
259
|
+
// 动态获取目录路径:如果是函数则调用,否则直接使用字符串
|
|
260
|
+
let directoryPath;
|
|
261
|
+
const requestUrl = new URL(request.url);
|
|
262
|
+
const requestInfo = {
|
|
263
|
+
url: request.url,
|
|
264
|
+
pathname: requestUrl.pathname
|
|
265
|
+
};
|
|
266
|
+
if (typeof item.directory === 'function') {
|
|
267
|
+
// directory 是函数,调用它获取路径(支持同步和异步函数)
|
|
268
|
+
const result = item.directory(requestInfo);
|
|
269
|
+
directoryPath = result instanceof Promise ? await result : result;
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
// directory 是字符串,直接使用
|
|
273
|
+
directoryPath = item.directory;
|
|
274
|
+
}
|
|
275
|
+
// 验证目录路径是否有效
|
|
276
|
+
if (!directoryPath || typeof directoryPath !== 'string' || directoryPath.trim().length === 0) {
|
|
277
|
+
callback({ error: FILE_NOT_FOUND });
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
// 确保目录路径是绝对路径
|
|
281
|
+
const resolvedDirectory = path.isAbsolute(directoryPath)
|
|
282
|
+
? directoryPath
|
|
283
|
+
: path.resolve(electron.app.getAppPath(), directoryPath);
|
|
284
|
+
const indexPath = path.join(resolvedDirectory, 'index.html');
|
|
285
|
+
const filePath = path.join(resolvedDirectory, decodeURIComponent(requestInfo.pathname));
|
|
286
|
+
const resolvedPath = await getPath(filePath);
|
|
287
|
+
const targetPath = resolvedPath || indexPath;
|
|
288
|
+
const ext = path.extname(targetPath).toLowerCase();
|
|
289
|
+
if (resolvedPath || !ext || ext === '.html' || ext === '.asar') {
|
|
290
|
+
callback({
|
|
291
|
+
path: resolvedPath || indexPath
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
callback({ error: FILE_NOT_FOUND });
|
|
296
|
+
}
|
|
267
297
|
}
|
|
268
|
-
|
|
298
|
+
catch (error) {
|
|
299
|
+
// 处理动态路径获取或文件访问时的错误
|
|
300
|
+
console.error('[serve] Handler error:', error);
|
|
269
301
|
callback({ error: FILE_NOT_FOUND });
|
|
270
302
|
}
|
|
271
303
|
};
|
|
@@ -275,7 +307,10 @@ const serve = (options) => {
|
|
|
275
307
|
...item,
|
|
276
308
|
isCorsEnabled: !!item?.isCorsEnabled,
|
|
277
309
|
scheme: item?.scheme || 'app',
|
|
278
|
-
|
|
310
|
+
// 如果 directory 是函数,保留函数;如果是字符串,则解析为绝对路径
|
|
311
|
+
directory: typeof item.directory === 'function'
|
|
312
|
+
? item.directory
|
|
313
|
+
: path.resolve(electron.app.getAppPath(), item.directory),
|
|
279
314
|
};
|
|
280
315
|
});
|
|
281
316
|
// 注册自定义协议的权限配置
|
package/main/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/src/main/index.ts"],"sourcesContent":["import type { WebContents } from 'electron'\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport {promisify} from 'node:util';\nimport electron, { app, webContents } from 'electron';\nimport md5 from 'md5';\nimport { v5 as uuidv5 } from 'uuid';\nimport lodash from 'lodash';\nimport * as remote from '@electron/remote/main'\nimport * as ipc from '@lynker-desktop/electron-ipc/main'\nimport * as logs from '@lynker-desktop/electron-logs/main'\nimport * as windowManager from '@lynker-desktop/electron-window-manager/main'\nimport type { PreloadWebContentsConfig } from '@lynker-desktop/electron-window-manager/common'\nimport { IPC_GET_APP_METRICS, type ServeOptions, type VideoDownloadOptions, type VideoProgressCallback, type VideoDownloadResult, type CacheOptions } from '../common';\nimport { initializeStore, getAppStore, appStoreInit } from './store';\nimport { initializeClipboard } from './clipboard';\nimport { initializeShortcut } from './shortcut';\nimport { ResourceCache, type ResourceCacheOptions } from './resource-cache';\nimport { downloadVideo, clearVideoCache, getVideoCacheStats, removeVideoCache, getFileUrl, setFFmpegPath } from './video-downloader';\nimport { DownloadOptions, getDownloader, Downloader } from './downloader';\nimport type ElectronStore from 'electron-store';\n\n// 重新导出 ResourceCache 相关类型和类,以便外部使用\nexport { ResourceCache, type ResourceCacheOptions, getAppStore };\n\nif (!remote.isInitialized()) {\n remote.initialize();\n}\n\nexport let isInitialized = false;\n// 等待初始化的回调队列\nconst readyCallbacks: Array<(sdk: SDK_TYPE) => void> = [];\n\nexport interface SDK_TYPE {\n ipc: typeof ipc.mainIPC;\n windowManager: windowManager.WindowsManager,\n getPreload: () => string;\n downloadVideo: (options: VideoDownloadOptions, callbacks?: VideoProgressCallback) => Promise<VideoDownloadResult>;\n clearVideoCache: (outputDir: string) => void;\n getVideoCacheStats: (outputDir: string) => { size: number; entries: Array<{ fileName: string; filePath: string; fileSize: number; mtime: number }> };\n removeVideoCache: (options: VideoDownloadOptions) => boolean;\n getAppStore: (name: string) => ElectronStore;\n appStoreInit: (stores: string[]) => boolean;\n downloader: Downloader;\n}\n\n\nfunction findWebContentsByPid(pid: number): {id: number, url: string} | undefined {\n const all = webContents.getAllWebContents();\n\n const wc = all.find((wc) => {\n try {\n return wc.getOSProcessId() === pid;\n } catch (e) {\n return false;\n }\n });\n // @ts-ignore\n return wc ? {id: wc.id, url: wc.getURL()} : undefined;\n}\n\n\n/**\n * 初始化\n * @param protocol 唤起协议 例:dgz\n * @param preload 预加载js 必须传\n * @param loadingViewUrl 窗口管理默认loading页面\n * @returns\n */\nexport const initialize = (options: { protocol: string, preload: string, loadingViewUrl?: string, errorViewUrl?: string, preloadWebContentsConfig?: PreloadWebContentsConfig, webviewDomainWhiteList?: string[], serveOptions?: ServeOptions, resourceCacheOptions?: ResourceCacheOptions, ffmpegPath?: string, appStores?: string[] }): SDK_TYPE => {\n let {protocol, preload, loadingViewUrl, serveOptions = [], errorViewUrl, preloadWebContentsConfig, webviewDomainWhiteList, resourceCacheOptions} = options;\n if (isInitialized) {\n // @ts-ignore\n return global['__GLBOAL_ELECTRON_SDK__'];\n }\n isInitialized = true;\n ipc.initialize();\n logs.initialize();\n initializeStore();\n initializeClipboard();\n initializeShortcut();\n if (options.appStores && options.appStores.length) {\n appStoreInit(options.appStores as string[]);\n }\n if (options.ffmpegPath) {\n setFFmpegPath(options.ffmpegPath);\n }\n const wm = windowManager.initialize(preload, loadingViewUrl, errorViewUrl, preloadWebContentsConfig, webviewDomainWhiteList || []);\n if (protocol) {\n registerProtocol(protocol);\n }\n if (!serveOptions) {\n serveOptions = []\n }\n if (resourceCacheOptions) {\n if (resourceCacheOptions.cacheDir) {\n serveOptions.push({\n scheme: ResourceCache.scheme,\n directory: resourceCacheOptions.cacheDir,\n })\n }\n }\n if (serveOptions && serveOptions.length) {\n serve(serveOptions);\n }\n if (resourceCacheOptions) {\n app.on('ready', () => {\n new ResourceCache(electron.session.defaultSession, resourceCacheOptions);\n });\n }\n class SDK {\n static ipc = ipc.mainIPC;\n static windowManager = wm;\n static getPreload = () => preload;\n static downloader = getDownloader();\n static downloadVideo = downloadVideo;\n static clearVideoCache = clearVideoCache;\n static getVideoCacheStats = getVideoCacheStats;\n static removeVideoCache = removeVideoCache;\n static getAppStore = getAppStore;\n static appStoreInit = appStoreInit;\n }\n ipc.mainIPC.handleRenderer(IPC_GET_APP_METRICS, async () => {\n const metrics = app.getAppMetrics().map(i => {\n const webContents = findWebContentsByPid(i.pid || 0);\n console.log('webContents', webContents);\n return {\n ...i,\n webContents: webContents?.id || undefined,\n url: webContents?.url,\n }\n })\n return JSON.stringify(metrics);\n })\n ipc.mainIPC.handleRenderer(`__sdk_transcode_video__`, async (options:VideoDownloadOptions) => {\n const md5Options = md5(JSON.stringify(options.url));\n downloadVideo(options, {\n onDownloadProgress: (progress) => {\n ipc.mainIPC.invokeAllRendererNotReply(`__sdk_transcode_video_callback_${md5Options}__`, {\n type: 'downloadProgress',\n data: progress\n });\n },\n onTranscodeProgress: (progress) => {\n ipc.mainIPC.invokeAllRendererNotReply(`__sdk_transcode_video_callback_${md5Options}__`, {\n type: 'transcodeProgress',\n data: progress\n });\n },\n onComplete: (result) => {\n ipc.mainIPC.invokeAllRendererNotReply(`__sdk_transcode_video_callback_${md5Options}__`, {\n type: 'complete',\n data: result\n });\n },\n });\n return true;\n })\n // @ts-ignore\n global['__GLBOAL_ELECTRON_SDK__'] = SDK;\n // 调用所有等待初始化的回调\n readyCallbacks.forEach(callback => {\n try {\n callback(SDK);\n } catch (error) {\n console.error('onReady callback error:', error);\n }\n });\n // 清空回调队列\n readyCallbacks.length = 0;\n return SDK;\n}\n\n/** 后续再优化 */\nexport const getSDK = (): SDK_TYPE => {\n // @ts-ignore\n if (!global['__GLBOAL_ELECTRON_SDK__']) {\n throw '请在ready前先调用initialize'\n }\n // @ts-ignore\n return global['__GLBOAL_ELECTRON_SDK__'];\n}\n\n/**\n * 注册唤起\n */\nexport const registerProtocol = (() => {\n let isRegister = false;\n let launchOptions = ``;\n return (protocol: string) => {\n if (isRegister) {\n return;\n }\n isRegister = true;\n if (process.defaultApp) {\n if (process.argv.length >= 2) {\n app.setAsDefaultProtocolClient(protocol, process.execPath, [path.resolve(lodash.get(process, `argv[1]`, ''))]);\n }\n } else {\n app.setAsDefaultProtocolClient(protocol);\n }\n const handleUrl = (url: string) => {\n launchOptions = `${url ?? ''}`;\n ipc.mainIPC.invokeAllRendererNotReply('__GLOBAL_CHANGE_LAUNCH_OPTIONS__', url)\n };\n\n function handleArgv(argv: string[]) {\n const prefix = `${protocol}:`;\n const offset = app?.isPackaged ? 1 : 2;\n const url = argv.find((arg, i) => i >= offset && arg.startsWith(prefix));\n if (url) handleUrl(url);\n }\n\n handleArgv(process.argv);\n\n app.on('second-instance', (event, argv) => {\n console.info(event)\n if (process.platform === 'win32') {\n // Windows\n handleArgv(argv);\n }\n });\n\n // macOS\n app.on('open-url', (event, urlStr) => {\n console.info(event)\n handleUrl(urlStr);\n });\n\n\n app.on(\"open-url\", (_event, url) => {\n handleUrl(url);\n });\n ipc.mainIPC.handleRenderer('__GLOBAL_GET_LAUNCH_OPTIONS__', async () => {\n return launchOptions;\n })\n ipc.mainIPC.handleRenderer('__GLOBAL_DEL_LAUNCH_OPTIONS__', async () => {\n launchOptions = ``;\n return launchOptions;\n })\n }\n})();\n\n/**\n * 注册协议\n * @param options\n * @returns\n */\nexport const serve = (options: ServeOptions) => {\n if (!options.length) {\n\t\tthrow new Error('请传入配置');\n\t}\n const stat = promisify(fs.stat);\n\n // See https://cs.chromium.org/chromium/src/net/base/net_error_list.h\n const FILE_NOT_FOUND = -6;\n\n const getPath: any = async (path_: string) => {\n try {\n const result = await stat(path_);\n\n if (result.isFile()) {\n return path_;\n }\n\n if (result.isDirectory()) {\n return getPath(path.join(path_, 'index.html'));\n }\n } catch (_) {}\n };\n\n const createHandler = (item: any) => {\n return async (request: any, callback: any) => {\n const indexPath = path.join(item.directory, 'index.html');\n const filePath = path.join(item.directory, decodeURIComponent(new URL(request.url).pathname));\n const resolvedPath = await getPath(filePath);\n const targetPath = resolvedPath || indexPath;\n const ext = path.extname(targetPath).toLowerCase();\n\n if (resolvedPath || !ext || ext === '.html' || ext === '.asar') {\n callback({\n path: resolvedPath || indexPath\n });\n } else {\n callback({error: FILE_NOT_FOUND});\n }\n }\n };\n\n\toptions = options.map((item) => {\n\t\treturn {\n\t\t\t...item,\n\t\t\tisCorsEnabled: !!item?.isCorsEnabled,\n\t\t\tscheme: item?.scheme || 'app',\n\t\t\tdirectory: path.resolve(electron.app.getAppPath(), item.directory),\n\t\t}\n\t})\n // 注册自定义协议的权限配置\n // 说明:\n // bypassCSP: 是否绕过内容安全策略(CSP),允许加载本地资源时不受 CSP 限制\n // standard: 使协议表现得像标准协议(如 http/https),支持标准 API\n // secure: 标记为安全协议,允许安全相关的操作\n // allowServiceWorkers: 允许该协议下注册 Service Worker\n // supportFetchAPI: 允许 fetch/XHR 等 API 访问该协议资源\n // corsEnabled: 是否启用跨域资源共享(CORS)\n // stream: 支持流式传输\n\telectron.protocol.registerSchemesAsPrivileged(options.map((item) => {\n\t\treturn {\n\t\t\tscheme: item.scheme,\n\t\t\tprivileges: {\n bypassCSP: true,\n\t\t\t\tstandard: true,\n\t\t\t\tsecure: true,\n\t\t\t\tallowServiceWorkers: true,\n\t\t\t\tsupportFetchAPI: true,\n\t\t\t\tcorsEnabled: item.isCorsEnabled ?? false,\n stream: true,\n\t\t\t}\n\t\t}\n\t}));\n\treturn new Promise((resolve, reject) => {\n\t\ttry {\n\t\t\telectron.app.on('ready', () => {\n\t\t\t\toptions.forEach((item) => {\n\t\t\t\t\tconst handler = createHandler(item);\n\t\t\t\t\tconst session = item.partition ? electron.session.fromPartition(item.partition) : electron.session.defaultSession;\n\t\t\t\t\tsession.protocol.registerFileProtocol(item.scheme, handler);\n\t\t\t\t})\n\t\t\t\tresolve(true)\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treject(error)\n\t\t}\n\t})\n}\n\n\n/**\n * @electron/remote/main enable方法\n * @param webContents\n * @returns\n */\nexport const enable = (webContents: WebContents) => remote.enable(webContents);\n\n/**\n * 获取随机UUID\n * @param key\n * @returns\n */\nexport function getRandomUUID(key: string = `${Date.now()}`): string {\n let webcrypto!: Crypto;\n let randomValue = Math?.random()?.toString()?.replace('0.', '');\n try {\n if (!webcrypto && !!window && window?.crypto) {\n webcrypto = window.crypto;\n }\n } catch (error) {console.log}\n try {\n const ar = webcrypto.getRandomValues(new Uint8Array(12));\n randomValue = `${md5(ar)}` || randomValue;\n } catch (error) {}\n const uuid = uuidv5(\n `${JSON.stringify(key)}_${Date.now()}_${randomValue}`,\n uuidv5.URL,\n );\n return uuid;\n}\n\n\n/**\n * 获取定制Session\n */\nexport const getCustomSession = windowManager.getCustomSession;\n\n/**\n * 等待 SDK 初始化完成\n * @param callback 初始化完成后的回调函数\n */\nexport const onReady = (callback: (sdk: SDK_TYPE) => void) => {\n if (isInitialized) {\n // 已经初始化,直接调用回调\n // @ts-ignore\n const sdk = global['__GLBOAL_ELECTRON_SDK__'];\n if (sdk) {\n callback(sdk);\n } else {\n // 如果 SDK 不存在,添加到队列等待\n readyCallbacks.push(callback);\n }\n } else {\n // 还没初始化,添加到队列等待\n readyCallbacks.push(callback);\n }\n};\n\n/**\n * 获取SDK实例\n * @returns\n */\nexport default new Proxy({} as SDK_TYPE & { onReady: typeof onReady }, {\n get(_target, prop) {\n if (prop === 'onReady') {\n return onReady;\n }\n if (!isInitialized) {\n throw new Error('请在ready前先调用initialize');\n }\n if (!prop) {\n // @ts-ignore\n return global['__GLBOAL_ELECTRON_SDK__'];\n }\n // @ts-ignore\n return global['__GLBOAL_ELECTRON_SDK__'][prop];\n },\n set() {\n return false;\n }\n}) as SDK_TYPE & { onReady: typeof onReady };\n"],"names":["remote","isInitialized","webContents","ipc","logs","initializeStore","initializeClipboard","initializeShortcut","appStoreInit","setFFmpegPath","windowManager","ResourceCache","app","getDownloader","downloadVideo","clearVideoCache","getVideoCacheStats","removeVideoCache","getAppStore","IPC_GET_APP_METRICS","promisify","uuid","uuidv5"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/src/main/index.ts"],"sourcesContent":["import type { WebContents } from 'electron'\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport {promisify} from 'node:util';\nimport electron, { app, webContents } from 'electron';\nimport md5 from 'md5';\nimport { v5 as uuidv5 } from 'uuid';\nimport lodash from 'lodash';\nimport * as remote from '@electron/remote/main'\nimport * as ipc from '@lynker-desktop/electron-ipc/main'\nimport * as logs from '@lynker-desktop/electron-logs/main'\nimport * as windowManager from '@lynker-desktop/electron-window-manager/main'\nimport type { PreloadWebContentsConfig } from '@lynker-desktop/electron-window-manager/common'\nimport { IPC_GET_APP_METRICS, type ServeOptions, type VideoDownloadOptions, type VideoProgressCallback, type VideoDownloadResult, type CacheOptions } from '../common';\nimport { initializeStore, getAppStore, appStoreInit } from './store';\nimport { initializeClipboard } from './clipboard';\nimport { initializeShortcut } from './shortcut';\nimport { ResourceCache, type ResourceCacheOptions } from './resource-cache';\nimport { downloadVideo, clearVideoCache, getVideoCacheStats, removeVideoCache, getFileUrl, setFFmpegPath } from './video-downloader';\nimport { DownloadOptions, getDownloader, Downloader } from './downloader';\nimport type ElectronStore from 'electron-store';\n\n// 重新导出 ResourceCache 相关类型和类,以便外部使用\nexport { ResourceCache, type ResourceCacheOptions, getAppStore };\n\nif (!remote.isInitialized()) {\n remote.initialize();\n}\n\nexport let isInitialized = false;\n// 等待初始化的回调队列\nconst readyCallbacks: Array<(sdk: SDK_TYPE) => void> = [];\n\nexport interface SDK_TYPE {\n ipc: typeof ipc.mainIPC;\n windowManager: windowManager.WindowsManager,\n getPreload: () => string;\n downloadVideo: (options: VideoDownloadOptions, callbacks?: VideoProgressCallback) => Promise<VideoDownloadResult>;\n clearVideoCache: (outputDir: string) => void;\n getVideoCacheStats: (outputDir: string) => { size: number; entries: Array<{ fileName: string; filePath: string; fileSize: number; mtime: number }> };\n removeVideoCache: (options: VideoDownloadOptions) => boolean;\n getAppStore: (name: string) => ElectronStore;\n appStoreInit: (stores: string[]) => boolean;\n downloader: Downloader;\n}\n\n\nfunction findWebContentsByPid(pid: number): {id: number, url: string} | undefined {\n const all = webContents.getAllWebContents();\n\n const wc = all.find((wc) => {\n try {\n return wc.getOSProcessId() === pid;\n } catch (e) {\n return false;\n }\n });\n // @ts-ignore\n return wc ? {id: wc.id, url: wc.getURL()} : undefined;\n}\n\n\n/**\n * 初始化\n * @param protocol 唤起协议 例:dgz\n * @param preload 预加载js 必须传\n * @param loadingViewUrl 窗口管理默认loading页面\n * @returns\n */\nexport const initialize = (options: { protocol: string, preload: string, loadingViewUrl?: string, errorViewUrl?: string, preloadWebContentsConfig?: PreloadWebContentsConfig, webviewDomainWhiteList?: string[], serveOptions?: ServeOptions, resourceCacheOptions?: ResourceCacheOptions, ffmpegPath?: string, appStores?: string[] }): SDK_TYPE => {\n let {protocol, preload, loadingViewUrl, serveOptions = [], errorViewUrl, preloadWebContentsConfig, webviewDomainWhiteList, resourceCacheOptions} = options;\n if (isInitialized) {\n // @ts-ignore\n return global['__GLBOAL_ELECTRON_SDK__'];\n }\n isInitialized = true;\n ipc.initialize();\n logs.initialize();\n initializeStore();\n initializeClipboard();\n initializeShortcut();\n if (options.appStores && options.appStores.length) {\n appStoreInit(options.appStores as string[]);\n }\n if (options.ffmpegPath) {\n setFFmpegPath(options.ffmpegPath);\n }\n const wm = windowManager.initialize(preload, loadingViewUrl, errorViewUrl, preloadWebContentsConfig, webviewDomainWhiteList || []);\n if (protocol) {\n registerProtocol(protocol);\n }\n if (!serveOptions) {\n serveOptions = []\n }\n if (resourceCacheOptions) {\n if (resourceCacheOptions.cacheDir) {\n serveOptions.push({\n scheme: ResourceCache.scheme,\n directory: resourceCacheOptions.cacheDir,\n })\n }\n }\n if (serveOptions && serveOptions.length) {\n serve(serveOptions);\n }\n if (resourceCacheOptions) {\n app.on('ready', () => {\n new ResourceCache(electron.session.defaultSession, resourceCacheOptions);\n });\n }\n class SDK {\n static ipc = ipc.mainIPC;\n static windowManager = wm;\n static getPreload = () => preload;\n static downloader = getDownloader();\n static downloadVideo = downloadVideo;\n static clearVideoCache = clearVideoCache;\n static getVideoCacheStats = getVideoCacheStats;\n static removeVideoCache = removeVideoCache;\n static getAppStore = getAppStore;\n static appStoreInit = appStoreInit;\n }\n ipc.mainIPC.handleRenderer(IPC_GET_APP_METRICS, async () => {\n const metrics = app.getAppMetrics().map(i => {\n const webContents = findWebContentsByPid(i.pid || 0);\n console.log('webContents', webContents);\n return {\n ...i,\n webContents: webContents?.id || undefined,\n url: webContents?.url,\n }\n })\n return JSON.stringify(metrics);\n })\n ipc.mainIPC.handleRenderer(`__sdk_transcode_video__`, async (options:VideoDownloadOptions) => {\n const md5Options = md5(JSON.stringify(options.url));\n downloadVideo(options, {\n onDownloadProgress: (progress) => {\n ipc.mainIPC.invokeAllRendererNotReply(`__sdk_transcode_video_callback_${md5Options}__`, {\n type: 'downloadProgress',\n data: progress\n });\n },\n onTranscodeProgress: (progress) => {\n ipc.mainIPC.invokeAllRendererNotReply(`__sdk_transcode_video_callback_${md5Options}__`, {\n type: 'transcodeProgress',\n data: progress\n });\n },\n onComplete: (result) => {\n ipc.mainIPC.invokeAllRendererNotReply(`__sdk_transcode_video_callback_${md5Options}__`, {\n type: 'complete',\n data: result\n });\n },\n });\n return true;\n })\n // @ts-ignore\n global['__GLBOAL_ELECTRON_SDK__'] = SDK;\n // 调用所有等待初始化的回调\n readyCallbacks.forEach(callback => {\n try {\n callback(SDK);\n } catch (error) {\n console.error('onReady callback error:', error);\n }\n });\n // 清空回调队列\n readyCallbacks.length = 0;\n return SDK;\n}\n\n/** 后续再优化 */\nexport const getSDK = (): SDK_TYPE => {\n // @ts-ignore\n if (!global['__GLBOAL_ELECTRON_SDK__']) {\n throw '请在ready前先调用initialize'\n }\n // @ts-ignore\n return global['__GLBOAL_ELECTRON_SDK__'];\n}\n\n/**\n * 注册唤起\n */\nexport const registerProtocol = (() => {\n let isRegister = false;\n let launchOptions = ``;\n return (protocol: string) => {\n if (isRegister) {\n return;\n }\n isRegister = true;\n if (process.defaultApp) {\n if (process.argv.length >= 2) {\n app.setAsDefaultProtocolClient(protocol, process.execPath, [path.resolve(lodash.get(process, `argv[1]`, ''))]);\n }\n } else {\n app.setAsDefaultProtocolClient(protocol);\n }\n const handleUrl = (url: string) => {\n launchOptions = `${url ?? ''}`;\n ipc.mainIPC.invokeAllRendererNotReply('__GLOBAL_CHANGE_LAUNCH_OPTIONS__', url)\n };\n\n function handleArgv(argv: string[]) {\n const prefix = `${protocol}:`;\n const offset = app?.isPackaged ? 1 : 2;\n const url = argv.find((arg, i) => i >= offset && arg.startsWith(prefix));\n if (url) handleUrl(url);\n }\n\n handleArgv(process.argv);\n\n app.on('second-instance', (event, argv) => {\n console.info(event)\n if (process.platform === 'win32') {\n // Windows\n handleArgv(argv);\n }\n });\n\n // macOS\n app.on('open-url', (event, urlStr) => {\n console.info(event)\n handleUrl(urlStr);\n });\n\n\n app.on(\"open-url\", (_event, url) => {\n handleUrl(url);\n });\n ipc.mainIPC.handleRenderer('__GLOBAL_GET_LAUNCH_OPTIONS__', async () => {\n return launchOptions;\n })\n ipc.mainIPC.handleRenderer('__GLOBAL_DEL_LAUNCH_OPTIONS__', async () => {\n launchOptions = ``;\n return launchOptions;\n })\n }\n})();\n\n/**\n * 注册协议\n * @param options\n * @returns\n */\nexport const serve = (options: ServeOptions) => {\n if (!options.length) {\n\t\tthrow new Error('请传入配置');\n\t}\n const stat = promisify(fs.stat);\n\n // See https://cs.chromium.org/chromium/src/net/base/net_error_list.h\n const FILE_NOT_FOUND = -6;\n\n const getPath: any = async (path_: string) => {\n try {\n const result = await stat(path_);\n\n if (result.isFile()) {\n return path_;\n }\n\n if (result.isDirectory()) {\n return getPath(path.join(path_, 'index.html'));\n }\n } catch (_) {}\n };\n\n const createHandler = (item: any) => {\n return async (request: any, callback: any) => {\n try {\n // 动态获取目录路径:如果是函数则调用,否则直接使用字符串\n let directoryPath: string;\n const requestUrl = new URL(request.url);\n const requestInfo = {\n url: request.url,\n pathname: requestUrl.pathname\n };\n\n if (typeof item.directory === 'function') {\n // directory 是函数,调用它获取路径(支持同步和异步函数)\n const result = item.directory(requestInfo);\n directoryPath = result instanceof Promise ? await result : result;\n } else {\n // directory 是字符串,直接使用\n directoryPath = item.directory;\n }\n\n // 验证目录路径是否有效\n if (!directoryPath || typeof directoryPath !== 'string' || directoryPath.trim().length === 0) {\n callback({error: FILE_NOT_FOUND});\n return;\n }\n\n // 确保目录路径是绝对路径\n const resolvedDirectory = path.isAbsolute(directoryPath)\n ? directoryPath\n : path.resolve(electron.app.getAppPath(), directoryPath);\n\n const indexPath = path.join(resolvedDirectory, 'index.html');\n const filePath = path.join(resolvedDirectory, decodeURIComponent(requestInfo.pathname));\n const resolvedPath = await getPath(filePath);\n const targetPath = resolvedPath || indexPath;\n const ext = path.extname(targetPath).toLowerCase();\n\n if (resolvedPath || !ext || ext === '.html' || ext === '.asar') {\n callback({\n path: resolvedPath || indexPath\n });\n } else {\n callback({error: FILE_NOT_FOUND});\n }\n } catch (error) {\n // 处理动态路径获取或文件访问时的错误\n console.error('[serve] Handler error:', error);\n callback({error: FILE_NOT_FOUND});\n }\n }\n };\n\n\toptions = options.map((item) => {\n\t\treturn {\n\t\t\t...item,\n\t\t\tisCorsEnabled: !!item?.isCorsEnabled,\n\t\t\tscheme: item?.scheme || 'app',\n\t\t\t// 如果 directory 是函数,保留函数;如果是字符串,则解析为绝对路径\n\t\t\tdirectory: typeof item.directory === 'function'\n\t\t\t\t? item.directory\n\t\t\t\t: path.resolve(electron.app.getAppPath(), item.directory),\n\t\t}\n\t})\n // 注册自定义协议的权限配置\n // 说明:\n // bypassCSP: 是否绕过内容安全策略(CSP),允许加载本地资源时不受 CSP 限制\n // standard: 使协议表现得像标准协议(如 http/https),支持标准 API\n // secure: 标记为安全协议,允许安全相关的操作\n // allowServiceWorkers: 允许该协议下注册 Service Worker\n // supportFetchAPI: 允许 fetch/XHR 等 API 访问该协议资源\n // corsEnabled: 是否启用跨域资源共享(CORS)\n // stream: 支持流式传输\n\telectron.protocol.registerSchemesAsPrivileged(options.map((item) => {\n\t\treturn {\n\t\t\tscheme: item.scheme,\n\t\t\tprivileges: {\n bypassCSP: true,\n\t\t\t\tstandard: true,\n\t\t\t\tsecure: true,\n\t\t\t\tallowServiceWorkers: true,\n\t\t\t\tsupportFetchAPI: true,\n\t\t\t\tcorsEnabled: item.isCorsEnabled ?? false,\n stream: true,\n\t\t\t}\n\t\t}\n\t}));\n\treturn new Promise((resolve, reject) => {\n\t\ttry {\n\t\t\telectron.app.on('ready', () => {\n\t\t\t\toptions.forEach((item) => {\n\t\t\t\t\tconst handler = createHandler(item);\n\t\t\t\t\tconst session = item.partition ? electron.session.fromPartition(item.partition) : electron.session.defaultSession;\n\t\t\t\t\tsession.protocol.registerFileProtocol(item.scheme, handler);\n\t\t\t\t})\n\t\t\t\tresolve(true)\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treject(error)\n\t\t}\n\t})\n}\n\n\n/**\n * @electron/remote/main enable方法\n * @param webContents\n * @returns\n */\nexport const enable = (webContents: WebContents) => remote.enable(webContents);\n\n/**\n * 获取随机UUID\n * @param key\n * @returns\n */\nexport function getRandomUUID(key: string = `${Date.now()}`): string {\n let webcrypto!: Crypto;\n let randomValue = Math?.random()?.toString()?.replace('0.', '');\n try {\n if (!webcrypto && !!window && window?.crypto) {\n webcrypto = window.crypto;\n }\n } catch (error) {console.log}\n try {\n const ar = webcrypto.getRandomValues(new Uint8Array(12));\n randomValue = `${md5(ar)}` || randomValue;\n } catch (error) {}\n const uuid = uuidv5(\n `${JSON.stringify(key)}_${Date.now()}_${randomValue}`,\n uuidv5.URL,\n );\n return uuid;\n}\n\n\n/**\n * 获取定制Session\n */\nexport const getCustomSession = windowManager.getCustomSession;\n\n/**\n * 等待 SDK 初始化完成\n * @param callback 初始化完成后的回调函数\n */\nexport const onReady = (callback: (sdk: SDK_TYPE) => void) => {\n if (isInitialized) {\n // 已经初始化,直接调用回调\n // @ts-ignore\n const sdk = global['__GLBOAL_ELECTRON_SDK__'];\n if (sdk) {\n callback(sdk);\n } else {\n // 如果 SDK 不存在,添加到队列等待\n readyCallbacks.push(callback);\n }\n } else {\n // 还没初始化,添加到队列等待\n readyCallbacks.push(callback);\n }\n};\n\n/**\n * 获取SDK实例\n * @returns\n */\nexport default new Proxy({} as SDK_TYPE & { onReady: typeof onReady }, {\n get(_target, prop) {\n if (prop === 'onReady') {\n return onReady;\n }\n if (!isInitialized) {\n throw new Error('请在ready前先调用initialize');\n }\n if (!prop) {\n // @ts-ignore\n return global['__GLBOAL_ELECTRON_SDK__'];\n }\n // @ts-ignore\n return global['__GLBOAL_ELECTRON_SDK__'][prop];\n },\n set() {\n return false;\n }\n}) as SDK_TYPE & { onReady: typeof onReady };\n"],"names":["remote","isInitialized","webContents","ipc","logs","initializeStore","initializeClipboard","initializeShortcut","appStoreInit","setFFmpegPath","windowManager","ResourceCache","app","getDownloader","downloadVideo","clearVideoCache","getVideoCacheStats","removeVideoCache","getAppStore","IPC_GET_APP_METRICS","promisify","uuid","uuidv5"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lynker-desktop/electron-sdk",
|
|
3
|
-
"version": "0.0.9-alpha.
|
|
3
|
+
"version": "0.0.9-alpha.85",
|
|
4
4
|
"description": "electron-sdk",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"electron",
|
|
@@ -53,9 +53,9 @@
|
|
|
53
53
|
"packageManager": "pnpm@9.6.0",
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@electron/remote": "^2.1.2",
|
|
56
|
-
"@lynker-desktop/electron-ipc": "0.0.9-alpha.
|
|
57
|
-
"@lynker-desktop/electron-logs": "0.0.9-alpha.
|
|
58
|
-
"@lynker-desktop/electron-window-manager": "0.0.9-alpha.
|
|
56
|
+
"@lynker-desktop/electron-ipc": "0.0.9-alpha.85",
|
|
57
|
+
"@lynker-desktop/electron-logs": "0.0.9-alpha.85",
|
|
58
|
+
"@lynker-desktop/electron-window-manager": "0.0.9-alpha.85",
|
|
59
59
|
"electron-store": "^11.0.2",
|
|
60
60
|
"events": "^3.3.0",
|
|
61
61
|
"lodash": "^4.17.21",
|
|
@@ -92,5 +92,5 @@
|
|
|
92
92
|
"tslib": "^2.6.3",
|
|
93
93
|
"typescript": "^5.5.3"
|
|
94
94
|
},
|
|
95
|
-
"gitHead": "
|
|
95
|
+
"gitHead": "e8a8bea3dd669b7d30b0ca8e3e0f1a06f7bceca3"
|
|
96
96
|
}
|