281 lines
8.6 KiB
JavaScript
281 lines
8.6 KiB
JavaScript
import {
|
|
resolveNotebookPath
|
|
} from "./chunk-ER4KPD22.js";
|
|
import {
|
|
asyncHandler,
|
|
createApiModule,
|
|
defineApiModule,
|
|
defineEndpoints,
|
|
successResponse
|
|
} from "./chunk-74TMTGBG.js";
|
|
|
|
// shared/modules/remote/api.ts
|
|
var REMOTE_ENDPOINTS = defineEndpoints({
|
|
getConfig: { path: "/config", method: "GET" },
|
|
saveConfig: { path: "/config", method: "POST" },
|
|
getScreenshot: { path: "/screenshot", method: "GET" },
|
|
saveScreenshot: { path: "/screenshot", method: "POST" },
|
|
getData: { path: "/data", method: "GET" },
|
|
saveData: { path: "/data", method: "POST" }
|
|
});
|
|
|
|
// shared/modules/remote/index.ts
|
|
var REMOTE_MODULE = defineApiModule({
|
|
id: "remote",
|
|
name: "\u8FDC\u7A0B",
|
|
basePath: "/remote",
|
|
order: 25,
|
|
version: "1.0.0",
|
|
endpoints: REMOTE_ENDPOINTS
|
|
});
|
|
|
|
// api/modules/remote/service.ts
|
|
import fs from "fs/promises";
|
|
import path from "path";
|
|
var REMOTE_DIR = "remote";
|
|
var RemoteService = class {
|
|
constructor(deps = {}) {
|
|
this.deps = deps;
|
|
}
|
|
getRemoteDir() {
|
|
const { fullPath } = resolveNotebookPath(REMOTE_DIR);
|
|
return { relPath: REMOTE_DIR, fullPath };
|
|
}
|
|
getDeviceDir(deviceName) {
|
|
const safeName = this.sanitizeFileName(deviceName);
|
|
const { fullPath } = resolveNotebookPath(path.join(REMOTE_DIR, safeName));
|
|
return { relPath: path.join(REMOTE_DIR, safeName), fullPath };
|
|
}
|
|
sanitizeFileName(name) {
|
|
return name.replace(/[<>:"/\\|?*]/g, "_").trim() || "unnamed";
|
|
}
|
|
getDeviceConfigPath(deviceName) {
|
|
const { fullPath } = this.getDeviceDir(deviceName);
|
|
return path.join(fullPath, "config.json");
|
|
}
|
|
getDeviceScreenshotPath(deviceName) {
|
|
const { fullPath } = this.getDeviceDir(deviceName);
|
|
return path.join(fullPath, "screenshot.png");
|
|
}
|
|
getDeviceDataPath(deviceName) {
|
|
const { fullPath } = this.getDeviceDir(deviceName);
|
|
return path.join(fullPath, "data.json");
|
|
}
|
|
async ensureDir(dirPath) {
|
|
await fs.mkdir(dirPath, { recursive: true });
|
|
}
|
|
async getDeviceNames() {
|
|
const { fullPath } = this.getRemoteDir();
|
|
try {
|
|
const entries = await fs.readdir(fullPath, { withFileTypes: true });
|
|
const dirs = entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
return dirs;
|
|
} catch {
|
|
return [];
|
|
}
|
|
}
|
|
async getConfig() {
|
|
const deviceNames = await this.getDeviceNames();
|
|
const devices = await Promise.all(
|
|
deviceNames.map(async (name) => {
|
|
try {
|
|
const configPath = this.getDeviceConfigPath(name);
|
|
const content = await fs.readFile(configPath, "utf-8");
|
|
const deviceConfig = JSON.parse(content);
|
|
return {
|
|
id: deviceConfig.id || name,
|
|
deviceName: name,
|
|
serverHost: deviceConfig.serverHost || "",
|
|
desktopPort: deviceConfig.desktopPort || 3e3,
|
|
gitPort: deviceConfig.gitPort || 3001,
|
|
openCodePort: deviceConfig.openCodePort || 3002,
|
|
fileTransferPort: deviceConfig.fileTransferPort || 3003,
|
|
password: deviceConfig.password || ""
|
|
};
|
|
} catch {
|
|
return {
|
|
id: name,
|
|
deviceName: name,
|
|
serverHost: "",
|
|
desktopPort: 3e3,
|
|
gitPort: 3001,
|
|
openCodePort: 3002,
|
|
fileTransferPort: 3003,
|
|
password: ""
|
|
};
|
|
}
|
|
})
|
|
);
|
|
return { devices };
|
|
}
|
|
async saveConfig(config) {
|
|
const { fullPath: remoteDirFullPath } = this.getRemoteDir();
|
|
await this.ensureDir(remoteDirFullPath);
|
|
const existingDevices = await this.getDeviceNames();
|
|
const newDeviceNames = config.devices.map((d) => this.sanitizeFileName(d.deviceName));
|
|
for (const oldDevice of existingDevices) {
|
|
if (!newDeviceNames.includes(oldDevice)) {
|
|
try {
|
|
const oldDir = path.join(remoteDirFullPath, oldDevice);
|
|
await fs.rm(oldDir, { recursive: true, force: true });
|
|
} catch {
|
|
}
|
|
}
|
|
}
|
|
for (const device of config.devices) {
|
|
const deviceDir = this.getDeviceDir(device.deviceName);
|
|
await this.ensureDir(deviceDir.fullPath);
|
|
const deviceConfigPath = this.getDeviceConfigPath(device.deviceName);
|
|
const deviceConfig = {
|
|
id: device.id,
|
|
serverHost: device.serverHost,
|
|
desktopPort: device.desktopPort,
|
|
gitPort: device.gitPort,
|
|
openCodePort: device.openCodePort,
|
|
fileTransferPort: device.fileTransferPort,
|
|
password: device.password || ""
|
|
};
|
|
await fs.writeFile(deviceConfigPath, JSON.stringify(deviceConfig, null, 2), "utf-8");
|
|
}
|
|
}
|
|
async getScreenshot(deviceName) {
|
|
if (!deviceName) {
|
|
return null;
|
|
}
|
|
const screenshotPath = this.getDeviceScreenshotPath(deviceName);
|
|
try {
|
|
return await fs.readFile(screenshotPath);
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
async saveScreenshot(dataUrl, deviceName) {
|
|
console.log("[RemoteService] saveScreenshot:", { deviceName, dataUrlLength: dataUrl?.length });
|
|
if (!deviceName || deviceName.trim() === "") {
|
|
console.warn("[RemoteService] saveScreenshot skipped: no deviceName");
|
|
return;
|
|
}
|
|
const deviceDir = this.getDeviceDir(deviceName);
|
|
await this.ensureDir(deviceDir.fullPath);
|
|
const base64Data = dataUrl.replace(/^data:image\/png;base64,/, "");
|
|
const buffer = Buffer.from(base64Data, "base64");
|
|
const screenshotPath = this.getDeviceScreenshotPath(deviceName);
|
|
await fs.writeFile(screenshotPath, buffer);
|
|
}
|
|
async getData(deviceName) {
|
|
if (!deviceName || deviceName.trim() === "") {
|
|
return null;
|
|
}
|
|
const dataPath = this.getDeviceDataPath(deviceName);
|
|
try {
|
|
const content = await fs.readFile(dataPath, "utf-8");
|
|
return JSON.parse(content);
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
async saveData(data, deviceName) {
|
|
if (!deviceName || deviceName.trim() === "") {
|
|
console.warn("[RemoteService] saveData skipped: no deviceName");
|
|
return;
|
|
}
|
|
const deviceDir = this.getDeviceDir(deviceName);
|
|
await this.ensureDir(deviceDir.fullPath);
|
|
const dataPath = this.getDeviceDataPath(deviceName);
|
|
await fs.writeFile(dataPath, JSON.stringify(data, null, 2), "utf-8");
|
|
}
|
|
};
|
|
var createRemoteService = (deps) => {
|
|
return new RemoteService(deps);
|
|
};
|
|
|
|
// api/modules/remote/routes.ts
|
|
import express from "express";
|
|
var createRemoteRoutes = (deps) => {
|
|
const router = express.Router();
|
|
const { remoteService: remoteService2 } = deps;
|
|
router.get(
|
|
"/config",
|
|
asyncHandler(async (req, res) => {
|
|
const config = await remoteService2.getConfig();
|
|
successResponse(res, config);
|
|
})
|
|
);
|
|
router.post(
|
|
"/config",
|
|
asyncHandler(async (req, res) => {
|
|
const config = req.body;
|
|
await remoteService2.saveConfig(config);
|
|
successResponse(res, null);
|
|
})
|
|
);
|
|
router.get(
|
|
"/screenshot",
|
|
asyncHandler(async (req, res) => {
|
|
const deviceName = req.query.device;
|
|
const buffer = await remoteService2.getScreenshot(deviceName);
|
|
if (!buffer) {
|
|
return successResponse(res, "");
|
|
}
|
|
const base64 = `data:image/png;base64,${buffer.toString("base64")}`;
|
|
successResponse(res, base64);
|
|
})
|
|
);
|
|
router.post(
|
|
"/screenshot",
|
|
asyncHandler(async (req, res) => {
|
|
const { dataUrl, deviceName } = req.body;
|
|
console.log("[Remote] saveScreenshot called:", { deviceName, hasDataUrl: !!dataUrl });
|
|
await remoteService2.saveScreenshot(dataUrl, deviceName);
|
|
successResponse(res, null);
|
|
})
|
|
);
|
|
router.get(
|
|
"/data",
|
|
asyncHandler(async (req, res) => {
|
|
const deviceName = req.query.device;
|
|
const data = await remoteService2.getData(deviceName);
|
|
successResponse(res, data);
|
|
})
|
|
);
|
|
router.post(
|
|
"/data",
|
|
asyncHandler(async (req, res) => {
|
|
const { deviceName, lastConnected } = req.body;
|
|
const data = {};
|
|
if (lastConnected !== void 0) {
|
|
data.lastConnected = lastConnected;
|
|
}
|
|
await remoteService2.saveData(data, deviceName);
|
|
successResponse(res, null);
|
|
})
|
|
);
|
|
return router;
|
|
};
|
|
var remoteService = new RemoteService();
|
|
var routes_default = createRemoteRoutes({ remoteService });
|
|
|
|
// api/modules/remote/index.ts
|
|
var createRemoteModule = () => {
|
|
return createApiModule(REMOTE_MODULE, {
|
|
routes: (container) => {
|
|
const remoteService2 = container.getSync("remoteService");
|
|
return createRemoteRoutes({ remoteService: remoteService2 });
|
|
},
|
|
lifecycle: {
|
|
onLoad: (container) => {
|
|
container.register("remoteService", () => new RemoteService());
|
|
}
|
|
}
|
|
});
|
|
};
|
|
var remote_default = createRemoteModule;
|
|
|
|
export {
|
|
RemoteService,
|
|
createRemoteService,
|
|
createRemoteRoutes,
|
|
createRemoteModule,
|
|
remote_default
|
|
};
|