chore: remove electron-dist from git
This commit is contained in:
@@ -19,3 +19,4 @@ legacy/
|
||||
|
||||
# Brainstorming artifacts
|
||||
.superpowers/
|
||||
electron-dist/
|
||||
|
||||
@@ -1,591 +0,0 @@
|
||||
import { app, screen, safeStorage, ipcMain, BrowserWindow, nativeTheme, dialog, nativeImage } from "electron";
|
||||
import { join } from "path";
|
||||
import { readFileSync, writeFile } from "fs";
|
||||
import Store from "electron-store";
|
||||
import Redis from "ioredis";
|
||||
import __cjs_mod__ from "node:module";
|
||||
const __filename = import.meta.filename;
|
||||
const __dirname = import.meta.dirname;
|
||||
const require2 = __cjs_mod__.createRequire(import.meta.url);
|
||||
const STATE_FILE = join(app.getPath("userData"), "jrdm-win-state.json");
|
||||
const MIN_WIDTH = 900;
|
||||
const MIN_HEIGHT = 600;
|
||||
const DEFAULT_WIDTH = 1200;
|
||||
const DEFAULT_HEIGHT = 800;
|
||||
function parseJson(str) {
|
||||
try {
|
||||
return JSON.parse(str);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
function getLastState() {
|
||||
try {
|
||||
const raw = readFileSync(STATE_FILE, "utf-8");
|
||||
const state = parseJson(raw);
|
||||
if (state) {
|
||||
const display = screen.getPrimaryDisplay().workArea;
|
||||
if (state.x != null && (state.x < 0 || state.x > display.width - 100)) {
|
||||
state.x = null;
|
||||
state.y = null;
|
||||
}
|
||||
if (state.y != null && (state.y < 0 || state.y > display.height - 100)) {
|
||||
state.x = null;
|
||||
state.y = null;
|
||||
}
|
||||
state.width = Math.max(state.width || DEFAULT_WIDTH, MIN_WIDTH);
|
||||
state.height = Math.max(state.height || DEFAULT_HEIGHT, MIN_HEIGHT);
|
||||
return state;
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
return { x: null, y: null, width: DEFAULT_WIDTH, height: DEFAULT_HEIGHT, maximized: false };
|
||||
}
|
||||
function saveState(win) {
|
||||
const bounds = win.getBounds();
|
||||
const state = { ...bounds, maximized: win.isMaximized() };
|
||||
writeFile(STATE_FILE, JSON.stringify(state), "utf-8", () => {
|
||||
});
|
||||
}
|
||||
function restoreAndTrack(win) {
|
||||
const lastState = getLastState();
|
||||
if (lastState.x != null && lastState.y != null) {
|
||||
win.setBounds({ x: lastState.x, y: lastState.y, width: lastState.width, height: lastState.height });
|
||||
}
|
||||
if (lastState.maximized) {
|
||||
win.maximize();
|
||||
}
|
||||
win.on("close", () => saveState(win));
|
||||
}
|
||||
const store = new Store({
|
||||
name: "jrdm-config",
|
||||
defaults: {
|
||||
connections: [],
|
||||
settings: {
|
||||
theme: "system",
|
||||
locale: "en",
|
||||
fontSize: 13,
|
||||
scanCount: 500
|
||||
}
|
||||
}
|
||||
});
|
||||
function encrypt(text) {
|
||||
if (!safeStorage.isEncryptionAvailable()) {
|
||||
return Buffer.from(text).toString("base64");
|
||||
}
|
||||
return safeStorage.encryptString(text).toString("base64");
|
||||
}
|
||||
function decrypt(encoded) {
|
||||
if (!safeStorage.isEncryptionAvailable()) {
|
||||
return Buffer.from(encoded, "base64").toString("utf-8");
|
||||
}
|
||||
return safeStorage.decryptString(Buffer.from(encoded, "base64"));
|
||||
}
|
||||
const clients = /* @__PURE__ */ new Map();
|
||||
function buildRedisOptions(opts) {
|
||||
const options = {
|
||||
host: opts.host,
|
||||
port: opts.port,
|
||||
username: opts.username || void 0,
|
||||
password: opts.password || void 0,
|
||||
stringNumbers: true,
|
||||
enableReadyCheck: true,
|
||||
family: 0,
|
||||
connectTimeout: 1e4,
|
||||
retryStrategy(times) {
|
||||
if (times > 3) return null;
|
||||
return Math.min(times * 200, 1e3);
|
||||
},
|
||||
maxRetriesPerRequest: 3
|
||||
};
|
||||
if (opts.tls) {
|
||||
options.tls = {
|
||||
rejectUnauthorized: false,
|
||||
checkServerIdentity: () => void 0
|
||||
};
|
||||
}
|
||||
return options;
|
||||
}
|
||||
function getClient(id) {
|
||||
return clients.get(id);
|
||||
}
|
||||
function isClientConnected(id) {
|
||||
const client = clients.get(id);
|
||||
return client?.status === "ready";
|
||||
}
|
||||
async function connect(id, opts) {
|
||||
if (clients.has(id)) {
|
||||
await disconnect(id);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
const redis = new Redis(buildRedisOptions(opts));
|
||||
redis.once("ready", () => {
|
||||
clients.set(id, redis);
|
||||
resolve();
|
||||
});
|
||||
redis.once("error", (err) => {
|
||||
redis.disconnect();
|
||||
reject(err);
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (!clients.has(id)) {
|
||||
redis.disconnect();
|
||||
reject(new Error("连接超时,请检查主机和端口"));
|
||||
}
|
||||
}, 12e3);
|
||||
});
|
||||
}
|
||||
async function disconnect(id) {
|
||||
const client = clients.get(id);
|
||||
if (client) {
|
||||
client.disconnect();
|
||||
clients.delete(id);
|
||||
}
|
||||
}
|
||||
async function getKeyType(id, key) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.type(key);
|
||||
}
|
||||
async function getKeyTTL(id, key) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.ttl(key);
|
||||
}
|
||||
async function deleteKey(id, key) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
await client.del(key);
|
||||
}
|
||||
async function setKeyTTL(id, key, ttl) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
if (ttl < 0) {
|
||||
await client.persist(key);
|
||||
} else {
|
||||
await client.expire(key, ttl);
|
||||
}
|
||||
}
|
||||
async function renameKey(id, oldKey, newKey) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
await client.rename(oldKey, newKey);
|
||||
}
|
||||
async function existsKey(id, key) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return await client.exists(key) === 1;
|
||||
}
|
||||
async function batchDelete(id, keys) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
if (keys.length === 0) return 0;
|
||||
const pipeline = client.pipeline();
|
||||
for (const key of keys) {
|
||||
pipeline.del(key);
|
||||
}
|
||||
const results = await pipeline.exec();
|
||||
return results?.filter(([err]) => !err).length ?? 0;
|
||||
}
|
||||
async function memoryUsage(id, key) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.memory("USAGE", key);
|
||||
}
|
||||
async function scanKeys(id, cursor, pattern, count) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
const [nextCursor, keys] = await client.scan(cursor, "MATCH", pattern, "COUNT", count);
|
||||
return { cursor: nextCursor, keys };
|
||||
}
|
||||
async function getStringValue(id, key) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.get(key);
|
||||
}
|
||||
async function setStringValue(id, key, value) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
await client.set(key, value);
|
||||
}
|
||||
async function getHashFields(id, key, cursor, count) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
const [nextCursor, raw] = await client.hscan(key, cursor, "COUNT", count);
|
||||
const fields = [];
|
||||
for (let i = 0; i < raw.length; i += 2) {
|
||||
fields.push([raw[i], raw[i + 1]]);
|
||||
}
|
||||
return { cursor: nextCursor, fields };
|
||||
}
|
||||
async function setHashField(id, key, field, value) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
await client.hset(key, field, value);
|
||||
}
|
||||
async function deleteHashField(id, key, field) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
await client.hdel(key, field);
|
||||
}
|
||||
async function listRange(id, key, start, stop) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.lrange(key, start, stop);
|
||||
}
|
||||
async function listLength(id, key) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.llen(key);
|
||||
}
|
||||
async function listPush(id, key, ...values) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.rpush(key, ...values);
|
||||
}
|
||||
async function listSet(id, key, index, value) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
await client.lset(key, index, value);
|
||||
}
|
||||
async function listRemove(id, key, count, value) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.lrem(key, count, value);
|
||||
}
|
||||
async function setMembers(id, key) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.smembers(key);
|
||||
}
|
||||
async function setSize(id, key) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.scard(key);
|
||||
}
|
||||
async function setAdd(id, key, ...members) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.sadd(key, ...members);
|
||||
}
|
||||
async function setRemove(id, key, ...members) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.srem(key, ...members);
|
||||
}
|
||||
async function zsetRange(id, key, start, stop, withScores) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
if (withScores) return client.zrange(key, start, stop, "WITHSCORES");
|
||||
return client.zrange(key, start, stop);
|
||||
}
|
||||
async function zsetSize(id, key) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.zcard(key);
|
||||
}
|
||||
async function zsetAdd(id, key, score, member) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.zadd(key, score, member);
|
||||
}
|
||||
async function zsetRemove(id, key, ...members) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.zrem(key, ...members);
|
||||
}
|
||||
async function streamInfo(id, key) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.xinfo("STREAM", key);
|
||||
}
|
||||
async function streamRange(id, key, start, end, count) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.xrange(key, start, end, "COUNT", count);
|
||||
}
|
||||
async function streamAdd(id, key, streamId, fieldValues) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.xadd(key, streamId, ...fieldValues);
|
||||
}
|
||||
async function streamTrim(id, key, maxLen) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.xtrim(key, "MAXLEN", maxLen);
|
||||
}
|
||||
async function streamDel(id, key, ...ids) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.xdel(key, ...ids);
|
||||
}
|
||||
async function execute(id, command, args) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.call(command, ...args);
|
||||
}
|
||||
async function getServerInfo(id) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.info();
|
||||
}
|
||||
async function selectDb(id, db) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
await client.select(db);
|
||||
}
|
||||
async function dbSize(id) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.dbsize();
|
||||
}
|
||||
async function ping(id) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.ping();
|
||||
}
|
||||
async function slowLogGet(id, count) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.slowlog("GET", count);
|
||||
}
|
||||
async function slowLogLen(id) {
|
||||
const client = getClient(id);
|
||||
if (!client) throw new Error(`Client ${id} not found`);
|
||||
return client.slowlog("LEN");
|
||||
}
|
||||
function registerIpcHandlers() {
|
||||
ipcMain.on("window:minimize", () => BrowserWindow.getFocusedWindow()?.minimize());
|
||||
ipcMain.on("window:maximize", () => {
|
||||
const win = BrowserWindow.getFocusedWindow();
|
||||
if (win) win.isMaximized() ? win.unmaximize() : win.maximize();
|
||||
});
|
||||
ipcMain.on("window:close", () => BrowserWindow.getFocusedWindow()?.close());
|
||||
ipcMain.handle("theme:get", () => nativeTheme.shouldUseDarkColors);
|
||||
ipcMain.on("theme:set", (_e, theme) => {
|
||||
nativeTheme.themeSource = theme;
|
||||
});
|
||||
ipcMain.handle("dialog:openFile", async (_e, options) => {
|
||||
const win = BrowserWindow.getFocusedWindow();
|
||||
if (!win) return null;
|
||||
const result = await dialog.showOpenDialog(win, options);
|
||||
if (result.canceled || result.filePaths.length === 0) return null;
|
||||
const fs = await import("fs");
|
||||
try {
|
||||
return { path: result.filePaths[0], content: fs.readFileSync(result.filePaths[0], "utf-8") };
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
ipcMain.handle("credential:encrypt", (_e, text) => encrypt(text));
|
||||
ipcMain.handle("credential:decrypt", (_e, encoded) => decrypt(encoded));
|
||||
ipcMain.handle("storage:getConnections", () => store.get("connections", []));
|
||||
ipcMain.handle("storage:saveConnection", (_e, conn) => {
|
||||
const connections = store.get("connections", []);
|
||||
const idx = connections.findIndex((c) => c.id === conn.id);
|
||||
if (idx >= 0) connections[idx] = conn;
|
||||
else connections.push(conn);
|
||||
store.set("connections", connections);
|
||||
return connections;
|
||||
});
|
||||
ipcMain.handle("storage:deleteConnection", (_e, id) => {
|
||||
const connections = store.get("connections", []).filter((c) => c.id !== id);
|
||||
store.set("connections", connections);
|
||||
return connections;
|
||||
});
|
||||
ipcMain.handle("storage:reorderConnections", (_e, ids) => {
|
||||
const connections = store.get("connections", []);
|
||||
const reordered = ids.map((id, i) => {
|
||||
const conn = connections.find((c) => c.id === id);
|
||||
conn.order = i;
|
||||
return conn;
|
||||
});
|
||||
store.set("connections", reordered);
|
||||
return reordered;
|
||||
});
|
||||
ipcMain.handle("storage:getSettings", () => store.get("settings"));
|
||||
ipcMain.handle("storage:saveSettings", (_e, settings) => {
|
||||
store.set("settings", settings);
|
||||
});
|
||||
ipcMain.handle("redis:connect", async (_e, id, opts) => {
|
||||
try {
|
||||
await connect(id, opts);
|
||||
return { success: true };
|
||||
} catch (err) {
|
||||
return { success: false, error: err.message };
|
||||
}
|
||||
});
|
||||
ipcMain.handle("redis:disconnect", async (_e, id) => {
|
||||
await disconnect(id);
|
||||
});
|
||||
ipcMain.handle("redis:ping", async (_e, id) => {
|
||||
return ping(id);
|
||||
});
|
||||
ipcMain.handle("redis:isConnected", (_e, id) => {
|
||||
return isClientConnected(id);
|
||||
});
|
||||
ipcMain.handle("redis:execute", async (_e, id, command, args) => {
|
||||
return execute(id, command, args);
|
||||
});
|
||||
ipcMain.handle("redis:getInfo", async (_e, id) => {
|
||||
return getServerInfo(id);
|
||||
});
|
||||
ipcMain.handle("redis:selectDb", async (_e, id, db) => {
|
||||
await selectDb(id, db);
|
||||
});
|
||||
ipcMain.handle("redis:dbSize", async (_e, id) => {
|
||||
return dbSize(id);
|
||||
});
|
||||
ipcMain.handle("redis:slowLogGet", async (_e, id, count) => {
|
||||
return slowLogGet(id, count);
|
||||
});
|
||||
ipcMain.handle("redis:slowLogLen", async (_e, id) => {
|
||||
return slowLogLen(id);
|
||||
});
|
||||
ipcMain.handle("redis:scanKeys", async (_e, id, cursor, pattern, count) => {
|
||||
return scanKeys(id, cursor, pattern, count);
|
||||
});
|
||||
ipcMain.handle("redis:getKeyType", async (_e, id, key) => {
|
||||
return getKeyType(id, key);
|
||||
});
|
||||
ipcMain.handle("redis:getKeyTTL", async (_e, id, key) => {
|
||||
return getKeyTTL(id, key);
|
||||
});
|
||||
ipcMain.handle("redis:setTTL", async (_e, id, key, ttl) => {
|
||||
await setKeyTTL(id, key, ttl);
|
||||
});
|
||||
ipcMain.handle("redis:deleteKey", async (_e, id, key) => {
|
||||
await deleteKey(id, key);
|
||||
});
|
||||
ipcMain.handle("redis:renameKey", async (_e, id, oldKey, newKey) => {
|
||||
await renameKey(id, oldKey, newKey);
|
||||
});
|
||||
ipcMain.handle("redis:existsKey", async (_e, id, key) => {
|
||||
return existsKey(id, key);
|
||||
});
|
||||
ipcMain.handle("redis:batchDelete", async (_e, id, keys) => {
|
||||
return batchDelete(id, keys);
|
||||
});
|
||||
ipcMain.handle("redis:memoryUsage", async (_e, id, key) => {
|
||||
return memoryUsage(id, key);
|
||||
});
|
||||
ipcMain.handle("redis:getString", async (_e, id, key) => {
|
||||
return getStringValue(id, key);
|
||||
});
|
||||
ipcMain.handle("redis:setString", async (_e, id, key, value) => {
|
||||
await setStringValue(id, key, value);
|
||||
});
|
||||
ipcMain.handle("redis:hashScan", async (_e, id, key, cursor, count) => {
|
||||
return getHashFields(id, key, cursor, count);
|
||||
});
|
||||
ipcMain.handle("redis:hashSet", async (_e, id, key, field, value) => {
|
||||
await setHashField(id, key, field, value);
|
||||
});
|
||||
ipcMain.handle("redis:hashDel", async (_e, id, key, field) => {
|
||||
await deleteHashField(id, key, field);
|
||||
});
|
||||
ipcMain.handle("redis:listRange", async (_e, id, key, start, stop) => {
|
||||
return listRange(id, key, start, stop);
|
||||
});
|
||||
ipcMain.handle("redis:listLength", async (_e, id, key) => {
|
||||
return listLength(id, key);
|
||||
});
|
||||
ipcMain.handle("redis:listPush", async (_e, id, key, values) => {
|
||||
return listPush(id, key, ...values);
|
||||
});
|
||||
ipcMain.handle("redis:listSet", async (_e, id, key, index, value) => {
|
||||
await listSet(id, key, index, value);
|
||||
});
|
||||
ipcMain.handle("redis:listRemove", async (_e, id, key, count, value) => {
|
||||
return listRemove(id, key, count, value);
|
||||
});
|
||||
ipcMain.handle("redis:setMembers", async (_e, id, key) => {
|
||||
return setMembers(id, key);
|
||||
});
|
||||
ipcMain.handle("redis:setSize", async (_e, id, key) => {
|
||||
return setSize(id, key);
|
||||
});
|
||||
ipcMain.handle("redis:setAdd", async (_e, id, key, members) => {
|
||||
return setAdd(id, key, ...members);
|
||||
});
|
||||
ipcMain.handle("redis:setRemove", async (_e, id, key, members) => {
|
||||
return setRemove(id, key, ...members);
|
||||
});
|
||||
ipcMain.handle("redis:zsetRange", async (_e, id, key, start, stop, withScores) => {
|
||||
return zsetRange(id, key, start, stop, withScores);
|
||||
});
|
||||
ipcMain.handle("redis:zsetSize", async (_e, id, key) => {
|
||||
return zsetSize(id, key);
|
||||
});
|
||||
ipcMain.handle("redis:zsetAdd", async (_e, id, key, score, member) => {
|
||||
return zsetAdd(id, key, score, member);
|
||||
});
|
||||
ipcMain.handle("redis:zsetRemove", async (_e, id, key, members) => {
|
||||
return zsetRemove(id, key, ...members);
|
||||
});
|
||||
ipcMain.handle("redis:streamInfo", async (_e, id, key) => {
|
||||
return streamInfo(id, key);
|
||||
});
|
||||
ipcMain.handle("redis:streamRange", async (_e, id, key, start, end, count) => {
|
||||
return streamRange(id, key, start, end, count);
|
||||
});
|
||||
ipcMain.handle("redis:streamAdd", async (_e, id, key, streamId, fieldValues) => {
|
||||
return streamAdd(id, key, streamId, fieldValues);
|
||||
});
|
||||
ipcMain.handle("redis:streamTrim", async (_e, id, key, maxLen) => {
|
||||
return streamTrim(id, key, maxLen);
|
||||
});
|
||||
ipcMain.handle("redis:streamDel", async (_e, id, key, ids) => {
|
||||
return streamDel(id, key, ...ids);
|
||||
});
|
||||
}
|
||||
let mainWindow = null;
|
||||
function getIconPath() {
|
||||
return join(__dirname, "../../build/icons/icon_256.png");
|
||||
}
|
||||
function createWindow() {
|
||||
const iconPath = getIconPath();
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1200,
|
||||
height: 800,
|
||||
minWidth: 900,
|
||||
minHeight: 600,
|
||||
title: "JRedisDesktop",
|
||||
icon: nativeImage.createFromPath(iconPath),
|
||||
backgroundColor: nativeTheme.shouldUseDarkColors ? "#0f0f1a" : "#f8fafc",
|
||||
webPreferences: {
|
||||
preload: join(__dirname, "../preload/index.mjs"),
|
||||
contextIsolation: true,
|
||||
nodeIntegration: false,
|
||||
sandbox: false
|
||||
},
|
||||
frame: false,
|
||||
titleBarStyle: "hidden"
|
||||
});
|
||||
if (process.platform === "linux" && mainWindow) {
|
||||
mainWindow.setIcon(nativeImage.createFromPath(iconPath));
|
||||
}
|
||||
restoreAndTrack(mainWindow);
|
||||
if (process.env.ELECTRON_RENDERER_URL) {
|
||||
mainWindow.loadURL(process.env.ELECTRON_RENDERER_URL);
|
||||
mainWindow.webContents.openDevTools();
|
||||
} else {
|
||||
mainWindow.loadFile(join(__dirname, "../renderer/index.html"));
|
||||
}
|
||||
mainWindow.on("closed", () => {
|
||||
mainWindow = null;
|
||||
});
|
||||
nativeTheme.on("updated", () => {
|
||||
mainWindow?.webContents.send("theme:os-updated", nativeTheme.shouldUseDarkColors);
|
||||
});
|
||||
}
|
||||
app.whenReady().then(() => {
|
||||
registerIpcHandlers();
|
||||
createWindow();
|
||||
});
|
||||
app.on("window-all-closed", () => {
|
||||
app.quit();
|
||||
});
|
||||
app.on("activate", () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) createWindow();
|
||||
});
|
||||
@@ -1,82 +0,0 @@
|
||||
import { contextBridge, ipcRenderer } from "electron";
|
||||
const electronAPI = {
|
||||
window: {
|
||||
minimize: () => ipcRenderer.send("window:minimize"),
|
||||
maximize: () => ipcRenderer.send("window:maximize"),
|
||||
close: () => ipcRenderer.send("window:close")
|
||||
},
|
||||
theme: {
|
||||
get: () => ipcRenderer.invoke("theme:get"),
|
||||
set: (theme) => ipcRenderer.send("theme:set", theme),
|
||||
onOsUpdated: (callback) => {
|
||||
ipcRenderer.on("theme:os-updated", (_e, isDark) => callback(isDark));
|
||||
}
|
||||
},
|
||||
dialog: {
|
||||
openFile: (options) => ipcRenderer.invoke("dialog:openFile", options)
|
||||
},
|
||||
credential: {
|
||||
encrypt: (text) => ipcRenderer.invoke("credential:encrypt", text),
|
||||
decrypt: (encoded) => ipcRenderer.invoke("credential:decrypt", encoded)
|
||||
},
|
||||
storage: {
|
||||
getConnections: () => ipcRenderer.invoke("storage:getConnections"),
|
||||
saveConnection: (conn) => ipcRenderer.invoke("storage:saveConnection", conn),
|
||||
deleteConnection: (id) => ipcRenderer.invoke("storage:deleteConnection", id),
|
||||
reorderConnections: (ids) => ipcRenderer.invoke("storage:reorderConnections", ids),
|
||||
getSettings: () => ipcRenderer.invoke("storage:getSettings"),
|
||||
saveSettings: (settings) => ipcRenderer.invoke("storage:saveSettings", settings)
|
||||
},
|
||||
redis: {
|
||||
connect: (id, opts) => ipcRenderer.invoke("redis:connect", id, opts),
|
||||
disconnect: (id) => ipcRenderer.invoke("redis:disconnect", id),
|
||||
execute: (id, command, args) => ipcRenderer.invoke("redis:execute", id, command, args),
|
||||
getInfo: (id) => ipcRenderer.invoke("redis:getInfo", id),
|
||||
scanKeys: (id, cursor, pattern, count) => ipcRenderer.invoke("redis:scanKeys", id, cursor, pattern, count),
|
||||
getKeyType: (id, key) => ipcRenderer.invoke("redis:getKeyType", id, key),
|
||||
getKeyTTL: (id, key) => ipcRenderer.invoke("redis:getKeyTTL", id, key),
|
||||
getString: (id, key) => ipcRenderer.invoke("redis:getString", id, key),
|
||||
setString: (id, key, value) => ipcRenderer.invoke("redis:setString", id, key, value),
|
||||
deleteKey: (id, key) => ipcRenderer.invoke("redis:deleteKey", id, key),
|
||||
hashScan: (id, key, cursor, count) => ipcRenderer.invoke("redis:hashScan", id, key, cursor, count),
|
||||
hashSet: (id, key, field, value) => ipcRenderer.invoke("redis:hashSet", id, key, field, value),
|
||||
hashDel: (id, key, field) => ipcRenderer.invoke("redis:hashDel", id, key, field),
|
||||
setTTL: (id, key, ttl) => ipcRenderer.invoke("redis:setTTL", id, key, ttl),
|
||||
selectDb: (id, db) => ipcRenderer.invoke("redis:selectDb", id, db),
|
||||
dbSize: (id) => ipcRenderer.invoke("redis:dbSize", id),
|
||||
// List
|
||||
listRange: (id, key, start, stop) => ipcRenderer.invoke("redis:listRange", id, key, start, stop),
|
||||
listLength: (id, key) => ipcRenderer.invoke("redis:listLength", id, key),
|
||||
listPush: (id, key, values) => ipcRenderer.invoke("redis:listPush", id, key, values),
|
||||
listSet: (id, key, index, value) => ipcRenderer.invoke("redis:listSet", id, key, index, value),
|
||||
listRemove: (id, key, count, value) => ipcRenderer.invoke("redis:listRemove", id, key, count, value),
|
||||
// Set
|
||||
setMembers: (id, key) => ipcRenderer.invoke("redis:setMembers", id, key),
|
||||
setSize: (id, key) => ipcRenderer.invoke("redis:setSize", id, key),
|
||||
setAdd: (id, key, members) => ipcRenderer.invoke("redis:setAdd", id, key, members),
|
||||
setRemove: (id, key, members) => ipcRenderer.invoke("redis:setRemove", id, key, members),
|
||||
// Sorted set
|
||||
zsetRange: (id, key, start, stop, withScores) => ipcRenderer.invoke("redis:zsetRange", id, key, start, stop, withScores),
|
||||
zsetSize: (id, key) => ipcRenderer.invoke("redis:zsetSize", id, key),
|
||||
zsetAdd: (id, key, score, member) => ipcRenderer.invoke("redis:zsetAdd", id, key, score, member),
|
||||
zsetRemove: (id, key, members) => ipcRenderer.invoke("redis:zsetRemove", id, key, members),
|
||||
// Slow log
|
||||
slowLogGet: (id, count) => ipcRenderer.invoke("redis:slowLogGet", id, count),
|
||||
slowLogLen: (id) => ipcRenderer.invoke("redis:slowLogLen", id),
|
||||
// Memory
|
||||
memoryUsage: (id, key) => ipcRenderer.invoke("redis:memoryUsage", id, key),
|
||||
batchDelete: (id, keys) => ipcRenderer.invoke("redis:batchDelete", id, keys),
|
||||
// Stream
|
||||
streamInfo: (id, key) => ipcRenderer.invoke("redis:streamInfo", id, key),
|
||||
streamRange: (id, key, start, end, count) => ipcRenderer.invoke("redis:streamRange", id, key, start, end, count),
|
||||
streamAdd: (id, key, streamId, fieldValues) => ipcRenderer.invoke("redis:streamAdd", id, key, streamId, fieldValues),
|
||||
streamTrim: (id, key, maxLen) => ipcRenderer.invoke("redis:streamTrim", id, key, maxLen),
|
||||
streamDel: (id, key, ids) => ipcRenderer.invoke("redis:streamDel", id, key, ids),
|
||||
// Key ops
|
||||
renameKey: (id, oldKey, newKey) => ipcRenderer.invoke("redis:renameKey", id, oldKey, newKey),
|
||||
existsKey: (id, key) => ipcRenderer.invoke("redis:existsKey", id, key),
|
||||
ping: (id) => ipcRenderer.invoke("redis:ping", id),
|
||||
isConnected: (id) => ipcRenderer.invoke("redis:isConnected", id)
|
||||
}
|
||||
};
|
||||
contextBridge.exposeInMainWorld("electronAPI", electronAPI);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -1,13 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>JRedisDesktop</title>
|
||||
<script type="module" crossorigin src="./assets/index-DZjCwPfE.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-Czrh6LTB.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user