UNPKG

@neosjs/electron-toolkit

Version:

neosjs electron toolkit

1,427 lines (1,403 loc) 61.3 kB
/*! * @neosjs/electron-toolkit * Version: 1.0.1 * Copyright (c) 2021-PRESENT NeosJS * ReleaseTime: 2025/5/1 16:45:38 */ "use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __esm = (fn, res) => function __init() { return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; }; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // ../../node_modules/.pnpm/tsup@8.4.0_jiti@2.4.2_postcss@8.5.3_tsx@4.19.3_typescript@5.8.3_yaml@2.7.1/node_modules/tsup/assets/cjs_shims.js var init_cjs_shims = __esm({ "../../node_modules/.pnpm/tsup@8.4.0_jiti@2.4.2_postcss@8.5.3_tsx@4.19.3_typescript@5.8.3_yaml@2.7.1/node_modules/tsup/assets/cjs_shims.js"() { "use strict"; } }); // ../../node_modules/.pnpm/dayjs@1.11.13/node_modules/dayjs/dayjs.min.js var require_dayjs_min = __commonJS({ "../../node_modules/.pnpm/dayjs@1.11.13/node_modules/dayjs/dayjs.min.js"(exports2, module2) { "use strict"; init_cjs_shims(); !function(t, e) { "object" == typeof exports2 && "undefined" != typeof module2 ? module2.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e(); }(exports2, function() { "use strict"; var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), ordinal: function(t2) { var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100; return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]"; } }, m = function(t2, e2, n2) { var r2 = String(t2); return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2; }, v = { s: m, z: function(t2) { var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60; return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0"); }, m: function t2(e2, n2) { if (e2.date() < n2.date()) return -t2(n2, e2); var r2 = 12 * (n2.year() - e2.year()) + (n2.month() - e2.month()), i2 = e2.clone().add(r2, c), s2 = n2 - i2 < 0, u2 = e2.clone().add(r2 + (s2 ? -1 : 1), c); return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0); }, a: function(t2) { return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2); }, p: function(t2) { return { M: c, y: h, w: o, d: a, D: d, h: u, m: s, s: i, ms: r, Q: f }[t2] || String(t2 || "").toLowerCase().replace(/s$/, ""); }, u: function(t2) { return void 0 === t2; } }, g = "en", D = {}; D[g] = M; var p = "$isDayjsObject", S = function(t2) { return t2 instanceof _ || !(!t2 || !t2[p]); }, w = function t2(e2, n2, r2) { var i2; if (!e2) return g; if ("string" == typeof e2) { var s2 = e2.toLowerCase(); D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2); var u2 = e2.split("-"); if (!i2 && u2.length > 1) return t2(u2[0]); } else { var a2 = e2.name; D[a2] = e2, i2 = a2; } return !r2 && i2 && (g = i2), i2 || !r2 && g; }, O = function(t2, e2) { if (S(t2)) return t2.clone(); var n2 = "object" == typeof e2 ? e2 : {}; return n2.date = t2, n2.args = arguments, new _(n2); }, b = v; b.l = w, b.i = S, b.w = function(t2, e2) { return O(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset }); }; var _ = function() { function M2(t2) { this.$L = w(t2.locale, null, true), this.parse(t2), this.$x = this.$x || t2.x || {}, this[p] = true; } var m2 = M2.prototype; return m2.parse = function(t2) { this.$d = function(t3) { var e2 = t3.date, n2 = t3.utc; if (null === e2) return /* @__PURE__ */ new Date(NaN); if (b.u(e2)) return /* @__PURE__ */ new Date(); if (e2 instanceof Date) return new Date(e2); if ("string" == typeof e2 && !/Z$/i.test(e2)) { var r2 = e2.match($); if (r2) { var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3); return n2 ? new Date(Date.UTC(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2)) : new Date(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2); } } return new Date(e2); }(t2), this.init(); }, m2.init = function() { var t2 = this.$d; this.$y = t2.getFullYear(), this.$M = t2.getMonth(), this.$D = t2.getDate(), this.$W = t2.getDay(), this.$H = t2.getHours(), this.$m = t2.getMinutes(), this.$s = t2.getSeconds(), this.$ms = t2.getMilliseconds(); }, m2.$utils = function() { return b; }, m2.isValid = function() { return !(this.$d.toString() === l); }, m2.isSame = function(t2, e2) { var n2 = O(t2); return this.startOf(e2) <= n2 && n2 <= this.endOf(e2); }, m2.isAfter = function(t2, e2) { return O(t2) < this.startOf(e2); }, m2.isBefore = function(t2, e2) { return this.endOf(e2) < O(t2); }, m2.$g = function(t2, e2, n2) { return b.u(t2) ? this[e2] : this.set(n2, t2); }, m2.unix = function() { return Math.floor(this.valueOf() / 1e3); }, m2.valueOf = function() { return this.$d.getTime(); }, m2.startOf = function(t2, e2) { var n2 = this, r2 = !!b.u(e2) || e2, f2 = b.p(t2), l2 = function(t3, e3) { var i2 = b.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2); return r2 ? i2 : i2.endOf(a); }, $2 = function(t3, e3) { return b.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2); }, y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : ""); switch (f2) { case h: return r2 ? l2(1, 0) : l2(31, 11); case c: return r2 ? l2(1, M3) : l2(0, M3 + 1); case o: var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2; return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3); case a: case d: return $2(v2 + "Hours", 0); case u: return $2(v2 + "Minutes", 1); case s: return $2(v2 + "Seconds", 2); case i: return $2(v2 + "Milliseconds", 3); default: return this.clone(); } }, m2.endOf = function(t2) { return this.startOf(t2, false); }, m2.$set = function(t2, e2) { var n2, o2 = b.p(t2), f2 = "set" + (this.$u ? "UTC" : ""), l2 = (n2 = {}, n2[a] = f2 + "Date", n2[d] = f2 + "Date", n2[c] = f2 + "Month", n2[h] = f2 + "FullYear", n2[u] = f2 + "Hours", n2[s] = f2 + "Minutes", n2[i] = f2 + "Seconds", n2[r] = f2 + "Milliseconds", n2)[o2], $2 = o2 === a ? this.$D + (e2 - this.$W) : e2; if (o2 === c || o2 === h) { var y2 = this.clone().set(d, 1); y2.$d[l2]($2), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d; } else l2 && this.$d[l2]($2); return this.init(), this; }, m2.set = function(t2, e2) { return this.clone().$set(t2, e2); }, m2.get = function(t2) { return this[b.p(t2)](); }, m2.add = function(r2, f2) { var d2, l2 = this; r2 = Number(r2); var $2 = b.p(f2), y2 = function(t2) { var e2 = O(l2); return b.w(e2.date(e2.date() + Math.round(t2 * r2)), l2); }; if ($2 === c) return this.set(c, this.$M + r2); if ($2 === h) return this.set(h, this.$y + r2); if ($2 === a) return y2(1); if ($2 === o) return y2(7); var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$2] || 1, m3 = this.$d.getTime() + r2 * M3; return b.w(m3, this); }, m2.subtract = function(t2, e2) { return this.add(-1 * t2, e2); }, m2.format = function(t2) { var e2 = this, n2 = this.$locale(); if (!this.isValid()) return n2.invalidDate || l; var r2 = t2 || "YYYY-MM-DDTHH:mm:ssZ", i2 = b.z(this), s2 = this.$H, u2 = this.$m, a2 = this.$M, o2 = n2.weekdays, c2 = n2.months, f2 = n2.meridiem, h2 = function(t3, n3, i3, s3) { return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3); }, d2 = function(t3) { return b.s(s2 % 12 || 12, t3, "0"); }, $2 = f2 || function(t3, e3, n3) { var r3 = t3 < 12 ? "AM" : "PM"; return n3 ? r3.toLowerCase() : r3; }; return r2.replace(y, function(t3, r3) { return r3 || function(t4) { switch (t4) { case "YY": return String(e2.$y).slice(-2); case "YYYY": return b.s(e2.$y, 4, "0"); case "M": return a2 + 1; case "MM": return b.s(a2 + 1, 2, "0"); case "MMM": return h2(n2.monthsShort, a2, c2, 3); case "MMMM": return h2(c2, a2); case "D": return e2.$D; case "DD": return b.s(e2.$D, 2, "0"); case "d": return String(e2.$W); case "dd": return h2(n2.weekdaysMin, e2.$W, o2, 2); case "ddd": return h2(n2.weekdaysShort, e2.$W, o2, 3); case "dddd": return o2[e2.$W]; case "H": return String(s2); case "HH": return b.s(s2, 2, "0"); case "h": return d2(1); case "hh": return d2(2); case "a": return $2(s2, u2, true); case "A": return $2(s2, u2, false); case "m": return String(u2); case "mm": return b.s(u2, 2, "0"); case "s": return String(e2.$s); case "ss": return b.s(e2.$s, 2, "0"); case "SSS": return b.s(e2.$ms, 3, "0"); case "Z": return i2; } return null; }(t3) || i2.replace(":", ""); }); }, m2.utcOffset = function() { return 15 * -Math.round(this.$d.getTimezoneOffset() / 15); }, m2.diff = function(r2, d2, l2) { var $2, y2 = this, M3 = b.p(d2), m3 = O(r2), v2 = (m3.utcOffset() - this.utcOffset()) * e, g2 = this - m3, D2 = function() { return b.m(y2, m3); }; switch (M3) { case h: $2 = D2() / 12; break; case c: $2 = D2(); break; case f: $2 = D2() / 3; break; case o: $2 = (g2 - v2) / 6048e5; break; case a: $2 = (g2 - v2) / 864e5; break; case u: $2 = g2 / n; break; case s: $2 = g2 / e; break; case i: $2 = g2 / t; break; default: $2 = g2; } return l2 ? $2 : b.a($2); }, m2.daysInMonth = function() { return this.endOf(c).$D; }, m2.$locale = function() { return D[this.$L]; }, m2.locale = function(t2, e2) { if (!t2) return this.$L; var n2 = this.clone(), r2 = w(t2, e2, true); return r2 && (n2.$L = r2), n2; }, m2.clone = function() { return b.w(this.$d, this); }, m2.toDate = function() { return new Date(this.valueOf()); }, m2.toJSON = function() { return this.isValid() ? this.toISOString() : null; }, m2.toISOString = function() { return this.$d.toISOString(); }, m2.toString = function() { return this.$d.toUTCString(); }, M2; }(), k = _.prototype; return O.prototype = k, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", c], ["$y", h], ["$D", d]].forEach(function(t2) { k[t2[1]] = function(e2) { return this.$g(e2, t2[0], t2[1]); }; }), O.extend = function(t2, e2) { return t2.$i || (t2(e2, _, O), t2.$i = true), O; }, O.locale = w, O.isDayjs = S, O.unix = function(t2) { return O(1e3 * t2); }, O.en = D[g], O.Ls = D, O.p = {}, O; }); } }); // src/main/index.ts var main_exports = {}; __export(main_exports, { default: () => main_default }); module.exports = __toCommonJS(main_exports); init_cjs_shims(); // package.json var version = "1.0.1"; // src/main/core/AppManager.ts init_cjs_shims(); var import_electron2 = require("electron"); var import_node_events = require("events"); // src/main/platform.ts init_cjs_shims(); var import_electron = require("electron"); var is = { dev: !import_electron.app.isPackaged, devMode: !!process.defaultApp }; var platform = { isWindows: process.platform === "win32", isMacOS: process.platform === "darwin", isLinux: process.platform === "linux", isMac: process.platform === "darwin", isWin: process.platform === "win32", isDev: !import_electron.app.isPackaged, isDevMode: !!process.defaultApp }; // src/main/core/LoggerManager.ts init_cjs_shims(); var import_electron_log = __toESM(require("electron-log"), 1); // src/shared/utils.ts init_cjs_shims(); var import_dayjs = __toESM(require_dayjs_min(), 1); function isFunction(obj) { return typeof obj === "function"; } var bytesToSize = (bytes) => { if (bytes === 0) return "0B"; const k = 1024; const sizes = ["B", "K", "M", "G", "T", "P", "E", "Z", "Y"]; const i = Math.floor(Math.log(bytes) / Math.log(k)); return Number((bytes / k ** i).toPrecision(3)) + sizes[i]; }; var DATE_FORMAT = "YYYY-MM-DD"; var formatToDate = (date = void 0, formatStr = DATE_FORMAT) => { return (0, import_dayjs.default)(date).format(formatStr); }; var timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; var YYYYMMDD = (/* @__PURE__ */ new Date()).toLocaleString("en-CA", { timeZone }).slice(0, 10); // src/main/core/LoggerManager.ts var env = process.env.NODE_ENV; import_electron_log.default.initialize(); import_electron_log.default.transports.file.fileName = `${formatToDate(/* @__PURE__ */ new Date())}_${env}.log`; import_electron_log.default.transports.file.level = "info"; import_electron_log.default.transports.file.maxSize = 5 * 1024 * 1024; import_electron_log.default.transports.console.format = `[{y}-{m}-{d} {h}:{i}:{s}.{ms}] [{level}] {text}`; import_electron_log.default.transports.console.level = "info"; var getLogger = (name) => import_electron_log.default.scope(name); import_electron_log.default.info("=================================="); // src/main/core/AppManager.ts var AppManager = class _AppManager extends import_node_events.EventEmitter { static instance = {}; maxListeners; static logger; constructor() { super(); this.maxListeners = 20; _AppManager.logger = getLogger("AppManager"); _AppManager.logger.info("\u521D\u59CB\u5316 AppManager \u6A21\u5757"); } static getInstance() { if (Object.keys(this.instance).length === 0) { this.instance = new _AppManager(); } return this.instance; } // 是否是开发模式 isDevMode() { return !!process.defaultApp; } // 是否准备好 isReady() { return import_electron2.app.isReady(); } // 重新启动 relaunch() { import_electron2.app.relaunch(); } // 退出 quit() { import_electron2.app.quit(); } // 退出 exit(code = 0) { import_electron2.app.exit(code); } // 获取应用名称 getName() { return import_electron2.app.getName(); } // 设置应用名称 setName(name) { if (!name) return; import_electron2.app.setName(name); } // 获取应用路径 getPath() { return import_electron2.app.getAppPath(); } // 获取应用路径 getPathByName(name) { if (!name) return ""; return import_electron2.app.getPath(name); } // 设置应用日志路径 setLogsPath(path2) { if (!path2) return; import_electron2.app.setAppLogsPath(path2); } // 设置应用路径 setPath(name, path2) { if (!name || !path2) return; import_electron2.app.setPath(name, path2); } // 获取应用版本 getVersion() { return import_electron2.app.getVersion(); } // 设置应用用户模型ID setUserModelId(id) { if (platform.isWindows) { import_electron2.app.setAppUserModelId(platform.isDev ? process.execPath : id); } } // 设置应用自动启动 setAutoLaunch(auto) { if (platform.isLinux) return false; const isOpenAtLogin = () => { return import_electron2.app.getLoginItemSettings().openAtLogin; }; if (isOpenAtLogin() !== auto) { import_electron2.app.setLoginItemSettings({ openAtLogin: auto }); return isOpenAtLogin() === auto; } else { return true; } } // 获取应用区域 getLocale() { return import_electron2.app.getLocale(); } // 获取应用区域代码 getLocaleCountryCode() { return import_electron2.app.getLocaleCountryCode(); } // 获取系统区域 getSystemLocale() { return import_electron2.app.getSystemLocale(); } // 获取系统区域语言 getPreferredSystemLanguages() { return import_electron2.app.getPreferredSystemLanguages(); } }; // src/main/core/AutoLaunchManager.ts init_cjs_shims(); var import_electron3 = require("electron"); var AutoLaunchManager = class _AutoLaunchManager { static instance = {}; static logger; constructor() { _AutoLaunchManager.logger = getLogger("AutoLaunchManager"); _AutoLaunchManager.logger.info("\u521D\u59CB\u5316 AutoLaunchManager \u6A21\u5757"); } static getInstance() { if (Object.keys(this.instance).length === 0) { this.instance = new _AutoLaunchManager(); } return this.instance; } enable() { return new Promise((resolve) => { const enabled = import_electron3.app.getLoginItemSettings({ args: ["--opened-at-login=1"] }).openAtLogin; if (enabled) { resolve(); } import_electron3.app.setLoginItemSettings({ args: ["--opened-at-login=1"], openAtLogin: true }); resolve(); }); } disable() { return new Promise((resolve) => { import_electron3.app.setLoginItemSettings({ openAtLogin: false }); resolve(); }); } isEnabled() { return new Promise((resolve) => { const enabled = import_electron3.app.getLoginItemSettings({ args: ["--opened-at-login=1"] }).openAtLogin; resolve(enabled); }); } }; // src/main/core/DevtoolManager.ts init_cjs_shims(); var import_electron_devtools_installer = require("electron-devtools-installer"); var DevtoolManager = class _DevtoolManager { static instance = {}; static logger; constructor() { _DevtoolManager.logger = getLogger("DevtoolManager"); _DevtoolManager.logger.info("\u521D\u59CB\u5316 DevtoolManager \u6A21\u5757"); } static getInstance() { if (Object.keys(this.instance).length === 0) { this.instance = new _DevtoolManager(); } return this.instance; } /** * 安装开发者工具 * @returns {Promise<void>} */ async setupDevTools() { try { await (0, import_electron_devtools_installer.installExtension)(import_electron_devtools_installer.VUEJS_DEVTOOLS, { loadExtensionOptions: { allowFileAccess: true } }); _DevtoolManager.logger.info(`\u5B89\u88C5 Vue DevTools \u6210\u529F`); } catch (error) { _DevtoolManager.logger.warn(`\u5B89\u88C5 Vue DevTools \u5931\u8D25:`, error); } } }; // src/main/core/DownloadManager.ts init_cjs_shims(); var import_ext_name = __toESM(require("ext-name"), 1); var import_node_events3 = require("events"); var import_node_path = require("path"); var import_electron6 = require("electron"); var import_unused_filename = require("unused-filename"); // src/shared/ipcEvents.ts init_cjs_shims(); var ipcMainEvents = [ "START_DOWNLOAD" /* START_DOWNLOAD */, // 开始下载 "PROGRESS_DOWNLOAD" /* PROGRESS_DOWNLOAD */, // 下载进度 "PAUSE_DOWNLOAD" /* PAUSE_DOWNLOAD */, // 暂停下载 "RESUME_DOWNLOAD" /* RESUME_DOWNLOAD */, // 恢复下载 "CANCEL_DOWNLOAD" /* CANCEL_DOWNLOAD */, // 取消下载 "COMPLETED_DOWNLOAD" /* COMPLETED_DOWNLOAD */, // 下载完成 "REGISTER_SHORTCUT" /* REGISTER_SHORTCUT */, // 注册快捷键 "CLEAN_CACHE" /* CLEAN_CACHE */, // 清理缓存 "CLEAN_STORAGE" /* CLEAN_STORAGE */, // 清理存储 "invoke" /* INVOKE */, // 调用 "SET_WINDOW_SIZE" /* SET_WINDOW_SIZE */, // 设置窗口大小 "SET_WINDOW_ABLE" /* SET_WINDOW_ABLE */, // 设置窗口可操作 "OPEN_PATH_SYNC" /* OPEN_PATH_SYNC */, // 打开文件系统 "PATH_EXISTS" /* PATH_EXISTS */ // 路径是否存在 ]; var WEBCONTENTS_READY_FOR_IPC_SIGNAL = "WEBCONTENTS_READY_FOR_IPC_SIGNAL"; var ipcUpdaterEvents = [ "checking-for-update" /* CHECKING_FOR_UPDATE */, "update-available" /* UPDATE_AVAILABLE */, "update-not-available" /* UPDATE_NOT_AVAILABLE */, "update-downloaded" /* UPDATE_DOWNLOADED */, "update-cancelled" /* UPDATE_CANCELLED */, "download-progress" /* DOWNLOAD_PROGRESS */, "error" /* UPDATE_ERROR */, "login" /* UPDATE_LOGIN */ ]; // src/shared/types.ts init_cjs_shims(); // src/main/core/IpcManager.ts init_cjs_shims(); var import_electron5 = require("electron"); var import_node_events2 = require("events"); // src/main/core/WindowManager.ts init_cjs_shims(); var import_electron4 = require("electron"); var WindowManager = class _WindowManager { static instance = {}; static ipc; static logger; browserWindow = null; constructor() { _WindowManager.logger = getLogger("WindowManager"); _WindowManager.logger.info("\u521D\u59CB\u5316 WindowManager \u6A21\u5757"); _WindowManager.ipc = IpcManager.getInstance(); } /** * 获取单例 */ static getInstance() { if (Object.keys(this.instance).length === 0) { this.instance = new _WindowManager(); } return this.instance; } /** * 监听渲染进程事件 */ static onRendererEvent() { _WindowManager.ipc.on("SET_WINDOW_SIZE" /* SET_WINDOW_SIZE */, (event, size) => { const win = import_electron4.BrowserWindow.fromWebContents(event.sender); if (!win) return; win.setSize(size.width, size.height); }); _WindowManager.ipc.on("SET_WINDOW_ABLE" /* SET_WINDOW_ABLE */, (event, data) => { const { type, flag, win = null } = data; const window_ = win || import_electron4.BrowserWindow.fromWebContents(event.sender); if (!type || !window_) return; switch (type) { case "maximize": window_.setMaximizable(flag); break; case "minimize": window_.setMinimizable(flag); break; case "close": window_.setClosable(flag); break; case "move": window_.setMovable(flag); break; case "resize": window_.setResizable(flag); break; case "fullscreen": window_.setFullScreenable(flag); break; default: break; } }); } /** * 监听窗口快捷键 * @param {BrowserWindow | null} window 窗口 * @param {ShortcutOptions} shortcutOptions 快捷键选项 */ static onWindowShortcuts(window, shortcutOptions) { if (!window) return; const { webContents } = window; const { escToCloseWindow = false, zoom = false } = shortcutOptions || {}; webContents.on("before-input-event", (event, input) => { if (input.type === "keyDown") { if (!is.dev) { if (input.code === "KeyR" && (input.control || input.meta)) event.preventDefault(); if (input.code === "KeyI" && (input.alt && input.meta || input.control && input.shift)) { event.preventDefault(); } } else { if (input.code === "F12") { if (webContents.isDevToolsOpened()) { webContents.closeDevTools(); } else { webContents.openDevTools({ mode: "undocked" }); console.log("Open dev tool..."); } } } if (escToCloseWindow) { if (input.code === "Escape" && input.key !== "Process") { window.close(); event.preventDefault(); } } if (!zoom) { if (input.code === "Minus" && (input.control || input.meta)) event.preventDefault(); if (input.code === "Equal" && input.shift && (input.control || input.meta)) event.preventDefault(); } } }); } // 注册无边框窗口IPC static registerFramelessWindowIpc() { this.ipc.on("invoke" /* INVOKE */, (event, action) => { const win = import_electron4.BrowserWindow.fromWebContents(event.sender); if (!win) return; switch (action) { case "show": win.show(); break; case "showInactive": win.showInactive(); break; case "min": win.minimize(); break; case "max": win.maximize(); break; case "unmax": win.isMaximized() && win.unmaximize(); break; case "close": win.close(); break; case "toggleFullscreen": win.setFullScreen(!win.isFullScreen()); break; case "exitFullscreen": win.setFullScreen(false); break; case "fullScreen": win.setFullScreen(true); break; case "center": win.center(); break; default: break; } }); } /** * 设置浏览器窗口 * @param {BrowserWindow | null} window 窗口 */ setBrowserWindow(window) { this.browserWindow = window; } /** * 初始化 * @param {BrowserWindow | null} window 窗口 * @param {ShortcutOptions} shortcutOptions 快捷键选项 */ setupWindowManager(window, shortcutOptions) { this.setBrowserWindow(window); const win = this.browserWindow || window; _WindowManager.registerFramelessWindowIpc(); _WindowManager.onWindowShortcuts(win, shortcutOptions); _WindowManager.onRendererEvent(); } }; // src/main/core/IpcManager.ts var IpcManager = class _IpcManager extends import_node_events2.EventEmitter { readyWebContents = /* @__PURE__ */ new WeakSet(); messageQueue = /* @__PURE__ */ new WeakMap(); static instance = {}; maxListeners; logger; constructor() { super(); this.maxListeners = 20; this.logger = getLogger("IpcManager"); this.logger.info("\u521D\u59CB\u5316 IpcManager \u6A21\u5757"); import_electron5.ipcMain.removeAllListeners(WEBCONTENTS_READY_FOR_IPC_SIGNAL); ipcMainEvents.forEach((event) => { import_electron5.ipcMain.removeAllListeners(event); import_electron5.ipcMain.on(event, (...args) => { this.emit(event, ...args); }); }); import_electron5.ipcMain.on(WEBCONTENTS_READY_FOR_IPC_SIGNAL, (event) => { this.logger.info("webContents\u5DF2\u7ECF\u51C6\u5907\u597D"); this.readyWebContents.add(event.sender); const queue = this.messageQueue.get(event.sender); this.messageQueue.delete(event.sender); if (!queue) return; for (const item of queue) { this.send(item[0], item[1], event.sender); } }); } static getInstance() { if (Object.keys(this.instance).length === 0) { this.instance = new _IpcManager(); } return this.instance; } /** * 发送消息 * @param {IpcEvents} channel 事件名 * @param {Array<any>} args 参数 * @param {WebContents} target 目标 */ send(channel, args, target) { const _target = target || WindowManager.getInstance().browserWindow?.webContents; if (!_target) { const win = import_electron5.BrowserWindow.getFocusedWindow(); if (win) this.send(channel, args, win?.webContents); return; } const _args = args || []; if (!this.readyWebContents.has(_target)) { const existing = this.messageQueue.get(_target) || []; this.messageQueue.set(_target, [...existing, [channel, args]]); return; } _target.isDestroyed() || _target.send(channel, ..._args); } /** * 监听消息 * @param {IpcEvents} channel 事件名 * @param {Function} listener 监听器 */ handle(channel, listener) { import_electron5.ipcMain.removeHandler(channel); import_electron5.ipcMain.handle(channel, listener); } /** * 监听消息一次 * @param {IpcEvents} channel 事件名 * @param {Function} listener 监听器 */ handleOnce(channel, listener) { import_electron5.ipcMain.handleOnce(channel, listener); } /** * 发送消息 * @param {IpcEvents} channel 事件名 * @param {any} message 消息 * @param {MessagePortMain[]} transfer 传输 * @param {Electron.WebContents} target 目标 */ postMessage(channel, message, transfer, target) { const _target = target || WindowManager.getInstance().browserWindow?.webContents; if (!_target) { const window = import_electron5.BrowserWindow.getFocusedWindow(); window?.webContents.postMessage(channel, message, transfer); return; } _target.postMessage(channel, message, transfer); } }; // src/main/core/DownloadManager.ts var DownloadManager = class _DownloadManager extends import_node_events3.EventEmitter { static instance = {}; downloadItems = /* @__PURE__ */ new Set(); maxListeners; static logger; constructor() { super(); this.maxListeners = 20; _DownloadManager.logger = getLogger("DownloadManager"); _DownloadManager.logger.info("\u521D\u59CB\u5316 DownloadManager \u6A21\u5757"); this.setupDownloadManager(); } /** * 获取单例 */ static getInstance() { if (Object.keys(this.instance).length === 0) { this.instance = new _DownloadManager(); } return this.instance; } setupDownloadManager() { const ipcManager = IpcManager.getInstance(); ipcManager.handle("DESTROY" /* DESTROY */, () => { this.downloadItems = /* @__PURE__ */ new Set(); this.removeAllListeners(); }); ipcManager.handle("START_DOWNLOAD" /* START_DOWNLOAD */, async (event, url, options) => { const win = import_electron6.BrowserWindow.getFocusedWindow(); if (!win) return _DownloadManager.logger.error("\u6CA1\u6709\u627E\u5230\u7A97\u53E3"); try { await this.start(win, url, { ...options, onStart: (info) => { !win.isDestroyed() && event?.sender?.send(encodeURI(url), info, "start"); }, onCancel: (item) => { !win.isDestroyed() && event?.sender?.send(encodeURI(url), item, "cancel"); }, onProgress: (progress) => { !win.isDestroyed() && event?.sender?.send(encodeURI(url), progress, "progress"); }, onPause: (item) => { !win.isDestroyed() && event?.sender?.send(encodeURI(url), item, "pause"); }, onComplete: (info) => { !win.isDestroyed() && event?.sender?.send(encodeURI(url), info, "complete"); }, onFail: (item) => { !win.isDestroyed() && event?.sender?.send(encodeURI(url), item, "fail"); } }); return encodeURI(url); } catch (error) { console.error(error); return ""; } }); ipcManager.on("PAUSE_DOWNLOAD" /* PAUSE_DOWNLOAD */, (_event, fileUrl) => { this.pause(fileUrl); }); ipcManager.on("RESUME_DOWNLOAD" /* RESUME_DOWNLOAD */, (_event, fileUrl) => { this.resume(fileUrl); }); ipcManager.on("CANCEL_DOWNLOAD" /* CANCEL_DOWNLOAD */, (_event, fileUrl) => { this.cancel(fileUrl); }); } /** * 获取文件名 * @param {string} name 文件名 * @param {string} mime 文件类型 * @returns {string} 文件名 */ getFilenameFromMime(name, mime) { const extensions = import_ext_name.default.mime(mime); if (extensions.length !== 1) return name; return `${name}.${extensions[0].ext}`; } /** * 注册监听 * @param {Electron.Session} session 会话 * @param {DownloadOptions} options 选项 */ registerListener(session2, options) { return new Promise((resolve, reject) => { let receivedBytes = 0; let completedBytes = 0; let totalBytes = 0; const activeDownloadItems = () => this.downloadItems.size; const progressDownloadItems = () => receivedBytes / totalBytes; options = { showBadge: true, showProgressBar: true, ...options }; const listener = (_event, item, webContents) => { this.downloadItems.add(item); totalBytes += item.getTotalBytes(); const window_ = import_electron6.BrowserWindow.fromWebContents(webContents); if (!window_) throw new Error("\u83B7\u53D6\u7A97\u53E3\u5931\u8D25"); if (options.directory && !(0, import_node_path.isAbsolute)(options.directory)) throw new Error("`directory` \u9009\u9879\u5FC5\u987B\u662F\u7EDD\u5BF9\u8DEF\u5F84"); const { overwrite, saveAs, onProgress, onComplete, onStart, onCancel, onFail, onPause, onTotalProgress, showProgressBar, showBadge, unregisterWhenDone, openFolderWhenDone } = options; const directory = options.directory ?? AppManager.getInstance().getPathByName("downloads" /* DOWNLOADS */); let filePath; if (options.filename) { filePath = (0, import_node_path.join)(directory, options.filename); } else { const filename = item.getFilename(); const name = (0, import_node_path.extname)(filename) ? filename : this.getFilenameFromMime(filename, item.getMimeType()); filePath = overwrite ? (0, import_node_path.join)(directory, name) : (0, import_unused_filename.unusedFilenameSync)((0, import_node_path.join)(directory, name)); } const errorMessage = options.errorMessage ?? "\u4E0B\u8F7D {fileName} \u5931\u8D25"; if (saveAs) { item.setSaveDialogOptions({ defaultPath: filePath, ...options.dialogOptions }); } else { item.setSavePath(filePath); } item.on("updated", (_event2, state) => { receivedBytes = completedBytes; for (const item2 of this.downloadItems) { receivedBytes += item2.getReceivedBytes(); } if (showBadge && ["darwin", "linux"].includes(process.platform)) { import_electron6.app.badgeCount = activeDownloadItems(); } if (!window_.isDestroyed() && showProgressBar) { window_.setProgressBar(progressDownloadItems()); } if (state === "interrupted") { _DownloadManager.logger.info("\u4E0B\u8F7D\u4E2D\u65AD\uFF0C\u53EF\u4EE5\u6062\u590D"); } else if (state === "progressing") { if (item.isPaused()) { _DownloadManager.logger.info("\u4E0B\u8F7D\u6682\u505C"); if (isFunction(onPause)) { onPause({ filename: item.getFilename(), filePath: item.getSavePath(), fileSize: item.getReceivedBytes(), mimeType: item.getMimeType(), fileUrl: item.getURL(), percent: item.getPercentComplete(), percentBytes: progressDownloadItems(), transferredBytes: receivedBytes, totalBytes, speed: item.getCurrentBytesPerSecond() }); } } else { if (isFunction(onProgress)) { const itemTransferredBytes = item.getReceivedBytes(); const itemTotalBytes = item.getTotalBytes(); onProgress({ filename: item.getFilename(), filePath: item.getSavePath(), fileSize: item.getReceivedBytes(), mimeType: item.getMimeType(), fileUrl: item.getURL(), percent: item.getPercentComplete(), percentBytes: itemTotalBytes ? itemTransferredBytes / itemTotalBytes : 0, transferredBytes: itemTransferredBytes, totalBytes: itemTotalBytes, speed: item.getCurrentBytesPerSecond() }); } if (isFunction(onTotalProgress)) { onTotalProgress({ filename: item.getFilename(), filePath: item.getSavePath(), fileSize: item.getReceivedBytes(), mimeType: item.getMimeType(), fileUrl: item.getURL(), percent: progressDownloadItems(), transferredBytes: receivedBytes, totalBytes, speed: item.getCurrentBytesPerSecond() }); } } } }); item.on("done", (_event2, state) => { completedBytes += item.getTotalBytes(); this.downloadItems.delete(item); if (showBadge && ["darwin", "linux"].includes(process.platform)) { import_electron6.app.badgeCount = activeDownloadItems(); } if (!window_.isDestroyed() && !activeDownloadItems()) { window_.setProgressBar(-1); receivedBytes = 0; completedBytes = 0; totalBytes = 0; } if (unregisterWhenDone) !window_.isDestroyed() && session2.removeListener("will-download", listener); if (state === "cancelled") { _DownloadManager.logger.info("\u4E0B\u8F7D\u53D6\u6D88"); if (isFunction(onCancel)) { onCancel({ filename: item.getFilename(), filePath: item.getSavePath(), fileSize: item.getReceivedBytes(), mimeType: item.getMimeType(), fileUrl: item.getURL() }); } } else if (state === "interrupted") { _DownloadManager.logger.info("\u4E0B\u8F7D\u4E2D\u65AD"); if (isFunction(onFail)) onFail(new Error(errorMessage)); reject(new Error(errorMessage)); } else if (state === "completed") { _DownloadManager.logger.info("\u4E0B\u8F7D\u5B8C\u6210"); const savePath = item.getSavePath(); if (process.platform === "darwin") import_electron6.app?.dock?.downloadFinished(savePath); if (openFolderWhenDone) import_electron6.shell.showItemInFolder(savePath); if (isFunction(onComplete)) { onComplete({ filename: item.getFilename(), filePath: savePath, fileSize: item.getReceivedBytes(), mimeType: item.getMimeType(), fileUrl: item.getURL() }); } resolve({ filename: item.getFilename(), filePath: savePath, fileSize: item.getReceivedBytes(), mimeType: item.getMimeType(), fileUrl: item.getURL() }); } }); if (isFunction(onStart)) { onStart({ filename: item.getFilename(), filePath: item.getSavePath(), fileSize: item.getTotalBytes(), mimeType: item.getMimeType(), fileUrl: item.getURL() }); } }; session2.on("will-download", listener); }); } /** * 下载 * @param {Electron.BrowserWindow} window_ 窗口 * @param {string} url 下载地址 * @param {DownloadOptions} options 选项 * @returns {Promise<any>} 返回值 */ async start(window_, url, options) { return new Promise((resolve, reject) => { options = { ...options, unregisterWhenDone: true }; this.registerListener(window_.webContents.session, options).then((item) => { resolve(item); }).catch((error) => { reject(error); }); window_.webContents.downloadURL(url); resolve(url); }); } /** * 暂停 * @param {string} fileUrl 下载地址 */ pause(fileUrl) { this.downloadItems.forEach((item) => { if (item.getURL() === fileUrl && !item.isPaused()) { item.pause(); } }); } /** * 恢复 * @param {string} fileUrl 下载地址 */ resume(fileUrl) { this.downloadItems.forEach((item) => { if (item.getURL() === fileUrl && item.isPaused()) { item.resume(); } }); } /** * 取消 * @param {string} fileUrl 下载地址 */ cancel(fileUrl) { this.downloadItems.forEach((item) => { if (item.getURL() === fileUrl && !["interrupted", "cancelled", "completed"].includes(item.getState())) { this.downloadItems.delete(item); item.cancel(); } }); } }; // src/main/core/EnergyManager.ts init_cjs_shims(); var import_electron7 = require("electron"); var psbId; var EnergyManager = class _EnergyManager { static instance = {}; static logger; constructor() { _EnergyManager.logger = getLogger("EnergyManager"); _EnergyManager.logger.info("\u521D\u59CB\u5316 EnergyManager \u6A21\u5757"); } static getInstance() { if (Object.keys(this.instance).length === 0) { this.instance = new _EnergyManager(); } return this.instance; } startPowerSaveBlocker() { if (psbId && import_electron7.powerSaveBlocker.isStarted(psbId)) return; psbId = import_electron7.powerSaveBlocker.start("prevent-display-sleep"); _EnergyManager.logger.info("\u542F\u52A8\u7701\u7535\u62E6\u622A\u5668"); } stopPowerSaveBlocker() { if (typeof psbId === "undefined" || !import_electron7.powerSaveBlocker.isStarted(psbId)) return; import_electron7.powerSaveBlocker.stop(psbId); _EnergyManager.logger.info("\u505C\u6B62\u7701\u7535\u62E6\u622A\u5668"); psbId = void 0; } }; // src/main/core/FileManager.ts init_cjs_shims(); var import_electron8 = require("electron"); var fs = __toESM(require("fs-extra"), 1); var import_node_child_process = require("child_process"); var path = __toESM(require("path"), 1); var FileManager = class _FileManager { static instance = {}; static ipc; static logger; constructor() { _FileManager.logger = getLogger("FileManager"); _FileManager.logger.info("\u521D\u59CB\u5316 FileManager \u6A21\u5757"); _FileManager.ipc = IpcManager.getInstance(); _FileManager.setupFileManager(); } static getInstance() { if (Object.keys(this.instance).length === 0) { this.instance = new _FileManager(); } return this.instance; } /** * 启动文件监听 */ static setupFileManager() { _FileManager.ipc.on("OPEN_PATH_SYNC" /* OPEN_PATH_SYNC */, (_event, path2) => { let bat = null; if (process.platform === "win32") { path2 = path2.replace(/\\/, "\\"); path2 = path2.replace(/\//g, "\\"); bat = (0, import_node_child_process.exec)(`start "" "${path2}"`); } if (process.platform === "darwin") { bat = (0, import_node_child_process.exec)(`open "${path2}"`, (err) => { err && import_electron8.dialog.showErrorBox("\u9519\u8BEF", "\u6253\u5F00\u6587\u4EF6\u5931\u8D25"); }); } if (!bat) return false; bat.stdout?.on("data", () => { bat.kill(); }); bat.stderr?.on("data", () => { bat.kill(); }); return true; }); _FileManager.ipc.handle("OPEN_PATH_ASYNC" /* OPEN_PATH_ASYNC */, (_event, path2) => { return import_electron8.shell.openPath(path2); }); _FileManager.ipc.on("PATH_EXISTS" /* PATH_EXISTS */, (event, path2) => { event.returnValue = fs.existsSync(path2); }); _FileManager.ipc.handle( "CLEANUP_DIRECTORY" /* CLEANUP_DIRECTORY */, (_, dir) => this.cleanupDirectory(dir) ); _FileManager.ipc.handle( "DELETE_USER_DATA" /* DELETE_USER_DATA */, (_, name) => this.deleteUserData(name) ); _FileManager.ipc.handle("SAVE_FILE" /* SAVE_FILE */, (_event, filePath, content) => { return this.saveFile(filePath, content); }); _FileManager.ipc.handle("REMOVE_FILE" /* REMOVE_FILE */, (_event, filePath) => { return this.removeFile(filePath); }); } /** * 清理目录 * @param {string} dir 目录 * @returns {Promise<boolean>} 是否清理成功 */ static cleanupDirectory = async (dir) => { if (dir) { if (fs.existsSync(dir)) { try { await fs.remove(dir); return true; } catch (error) { console.warn(`cleanupDirectory: Failed to clean directory`, error); } } } return false; }; /** * 删除用户数据 * @param {string} name 用户数据名称 * @returns {Promise<boolean>} 是否删除成功 */ static deleteUserData = async (name) => { const appData = path.join(import_electron8.app.getPath("appData"), name); console.log(`Cleanup: Deleting data dir ${appData}`); return await this.cleanupDirectory(appData); }; /** * 保存文件 * @param {string} filePath 文件路径 * @param {string} content 文件内容 * @returns {Promise<void>} 保存结果 */ static saveFile = async (filePath, content) => { try { return await fs.outputFile(filePath, content, { encoding: "utf-8" }); } catch (error) { console.log(`saveFile: Could not save ${filePath}`, error); } }; /** * 删除文件 * @param {string} filePath 文件路径 * @returns {Promise<void>} 删除结果 */ static removeFile = async (filePath) => { try { return await fs.remove(filePath); } catch (error) { console.log(`removeFile: Could not remove ${filePath}`, error); } }; }; // src/main/core/MediaManager.ts init_cjs_shims(); var import_electron9 = require("electron"); var MediaManager = class _MediaManager { static instance; static logger; static ipc; constructor() { _MediaManager.logger = getLogger("MediaManager"); _MediaManager.logger.info("\u521D\u59CB\u5316 MediaManager \u6A21\u5757"); _MediaManager.ipc = IpcManager.getInstance(); _MediaManager.setupMediaManager(); } static getInstance() { if (!_MediaManager.instance) { _MediaManager.instance = new _MediaManager(); } return _MediaManager.instance; } /** * 初始化事件处理 */ static setupMediaManager() { _MediaManager.ipc.handle("GET_MEDIA_ACCESS_STATUS" /* GET_MEDIA_ACCESS_STATUS */, (_event, args) => { return this.getMediaAccessStatus(args); }); _MediaManager.ipc.handle("ASK_FOR_MEDIA_ACCESS" /* ASK_FOR_MEDIA_ACCESS */, (_event, args) => { return this.askForMediaAccess(args); }); } /** * 获取媒体访问权限状态 * @param {MediaType} mediaType - 媒体类型 * @returns {MediaAccessStatus} - 媒体访问权限状态 */ static getMediaAccessStatus(mediaType) { return import_electron9.systemPreferences.getMediaAccessStatus(mediaType); } /** * 请求媒体访问权限(摄像头、麦克风) * macOS 需要请求权限 * @param {RequestMediaAccessType} mediaType - 媒体类型 * @returns {Promise<boolean>} - 是否请求成功 */ static askForMediaAccess(mediaType) { return import_electron9.systemPreferences.askForMediaAccess(mediaType); } }; // src/main/core/StorageManager.ts init_cjs_shims(); var import_electron10 = require("electron"); var StorageManager = class _StorageManager { static instance = {}; static logger; constructor() { _StorageManager.logger = getLogger("StorageManager"); _StorageManager.logger.info("\u521D\u59CB\u5316 StorageManager \u6A21\u5757"); _StorageManager.setupStorageManager(); } static getInstance() { if (Object.keys(this.instance).length === 0) { this.instance = new _StorageManager(); } return this.instance; } /** * 初始化事件处理 */ static setupStorageManager() { const ipcManager = IpcManager.getInstance(); ipcManager.handle("CLEAN_CACHE" /* CLEAN_CACHE */, async () => { this.logger.info("\u6E05\u7406\u7CFB\u7EDF\u7F13\u5B58"); return await import_electron10.session.defaultSession.cl