@fdm-monster/server
Version:
FDM Monster is a bulk OctoPrint, Klipper, PrusaLink and BambuLab manager to set up, configure and monitor 3D printers. Our aim is to provide neat overview over your farm.
378 lines (377 loc) • 15.7 kB
JavaScript
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
import { __decorateMetadata } from "../_virtual/_@oxc-project_runtime@0.129.0/helpers/decorateMetadata.js";
import { __decorate } from "../_virtual/_@oxc-project_runtime@0.129.0/helpers/decorate.js";
import { InternalServerException } from "../exceptions/runtime.exceptions.js";
import { validateInput, validateMiddleware } from "../handlers/validators.js";
import { defaultHttpProtocol } from "../utils/url.utils.js";
import { normalizeUrl } from "../utils/normalize-url.js";
import { AppConstants } from "../server.constants.js";
import { ROLES } from "../constants/authorization.constants.js";
import { generateCorrelationToken } from "../utils/correlation-token.util.js";
import { authenticate, authorizeRoles } from "../middleware/authenticate.js";
import { FloorStore } from "../state/floor.store.js";
import { PrinterCache } from "../state/printer.cache.js";
import { printerResolveMiddleware } from "../middleware/printer.js";
import { getScopedPrinter } from "../middleware/printer-resolver.js";
import { feedRateSchema, flowRateSchema, testPrinterApiSchema, updatePrinterDisabledReasonSchema, updatePrinterEnabledSchema } from "./validation/printer-controller.validation.js";
import { PrinterSocketStore } from "../state/printer-socket.store.js";
import { TestPrinterSocketStore } from "../state/test-printer-socket.store.js";
import { PrinterEventsCache } from "../state/printer-events.cache.js";
import { FailedDependencyException } from "../exceptions/failed-dependency.exception.js";
import { PrinterApiFactory } from "../services/printer-api.factory.js";
import { DELETE, GET, PATCH, POST, before, route } from "awilix-express";
import { AxiosError } from "axios";
//#region src/controllers/printer.controller.ts
var printer_controller_exports = /* @__PURE__ */ __exportAll({ PrinterController: () => PrinterController });
var _ref, _ref2, _ref3, _ref4, _ref5, _ref6, _PrinterController;
let PrinterController = _PrinterController = class PrinterController {
logger;
constructor(loggerFactory, printerApiFactory, printerSocketStore, testPrinterSocketStore, printerService, printerCache, printerEventsCache, printerApi, floorStore) {
this.printerApiFactory = printerApiFactory;
this.printerSocketStore = printerSocketStore;
this.testPrinterSocketStore = testPrinterSocketStore;
this.printerService = printerService;
this.printerCache = printerCache;
this.printerEventsCache = printerEventsCache;
this.printerApi = printerApi;
this.floorStore = floorStore;
this.logger = loggerFactory(_PrinterController.name);
}
async list(req, res) {
res.send(await this.printerCache.listCachedPrinters(true));
}
async create(req, res) {
const newPrinter = req.body;
if (req.query.forceSave !== "true") await this.testPrintApiConnection(newPrinter);
const createdPrinter = await this.printerService.create(newPrinter);
res.send(await this.printerCache.getCachedPrinterOrThrowAsync(createdPrinter.id));
}
async createBatch(req, res) {
const importResult = await this.printerService.batchImport(req.body);
res.send(importResult);
}
async getPrinter(req, res) {
const { currentPrinterId } = getScopedPrinter(req);
res.send(await this.printerCache.getCachedPrinterOrThrowAsync(currentPrinterId));
}
async getPrinterSocketInfo(req, res) {
const { currentPrinterId } = getScopedPrinter(req);
res.send(await this.printerEventsCache.getPrinterSocketEvents(currentPrinterId));
}
async update(req, res) {
const forceSave = req.query.forceSave === "true";
const { currentPrinterId } = getScopedPrinter(req);
const updatedPrinter = req.body;
if (!forceSave) await this.testPrintApiConnection(updatedPrinter);
await this.printerService.update(currentPrinterId, updatedPrinter);
res.send(await this.printerCache.getCachedPrinterOrThrowAsync(currentPrinterId));
}
async delete(req, res) {
const { currentPrinterId } = getScopedPrinter(req);
await this.printerService.delete(currentPrinterId);
await this.floorStore.removePrinterFromAnyFloor(currentPrinterId);
res.send();
}
async updateEnabled(req, res) {
const { currentPrinterId } = getScopedPrinter(req);
const data = await validateMiddleware(req, updatePrinterEnabledSchema);
await this.printerService.updateEnabled(currentPrinterId, data.enabled);
res.send({});
}
async updatePrinterDisabledReason(req, res) {
const { currentPrinterId } = getScopedPrinter(req);
const data = await validateMiddleware(req, updatePrinterDisabledReasonSchema);
await this.printerService.updateDisabledReason(currentPrinterId, data.disabledReason);
res.send({});
}
async refreshPrinterSocket(req, res) {
const { currentPrinterId } = getScopedPrinter(req);
this.printerSocketStore.reconnectPrinterAdapter(currentPrinterId);
await this.printerEventsCache.deletePrinterSocketEvents(currentPrinterId);
res.send({});
}
async testConnection(req, res) {
if (req.body.printerURL?.length) req.body.printerURL = normalizeUrl(req.body.printerURL, { defaultProtocol: defaultHttpProtocol });
const newPrinter = await validateMiddleware(req, testPrinterApiSchema);
const printerCorrelationToken = generateCorrelationToken();
this.logger.log(`Testing printer with correlation token ${printerCorrelationToken}`);
try {
await this.testPrinterSocketStore.setupTestPrinter(printerCorrelationToken, newPrinter);
} catch (e) {
res.send({
correlationToken: printerCorrelationToken,
failure: true,
error: e.toString()
});
return;
}
res.send({ correlationToken: printerCorrelationToken });
}
async getPrinterLoginDetails(req, res) {
const { printerLogin } = getScopedPrinter(req);
res.send(printerLogin);
}
/**
* Sends gcode according to https://docs.octoprint.org/en/master/api/printer.html#send-an-arbitrary-command-to-the-printer
*/
async sendEmergencyM112(req, res) {
const { printerApi } = getScopedPrinter(req);
await printerApi.quickStop();
res.send();
}
async sendSerialConnectCommand(req, res) {
await this.printerApi.connect();
res.send({});
}
async sendSerialDisconnectCommand(req, res) {
await this.printerApi.disconnect();
res.send({});
}
async movePrintHead(req, res) {
await this.printerApi.movePrintHead(req.body);
res.send({});
}
async homeAxes(req, res) {
await this.printerApi.homeAxes(req.body);
res.send({});
}
async pausePrint(req, res) {
await this.printerApi.pausePrint();
res.send({});
}
async resumePrint(req, res) {
await this.printerApi.resumePrint();
res.send({});
}
async cancelPrint(req, res) {
await this.printerApi.cancelPrint();
res.send({});
}
async restartServer(req, res) {
await this.printerApi.restartServer();
res.send();
}
async setFeedRate(req, res) {
const { currentPrinterId } = getScopedPrinter(req);
const data = await validateMiddleware(req, feedRateSchema);
await this.printerService.updateFeedRate(currentPrinterId, data.feedRate);
res.send({});
}
async setFlowRate(req, res) {
const { currentPrinterId } = getScopedPrinter(req);
const data = await validateMiddleware(req, flowRateSchema);
await this.printerService.updateFlowRate(currentPrinterId, data.flowRate);
res.send({});
}
async testPrintApiConnection(inputLoginDto) {
await validateInput(inputLoginDto, testPrinterApiSchema);
this.logger.debug(`Testing API connection for printer type: ${inputLoginDto.printerType}`, inputLoginDto);
try {
await this.printerApiFactory.getScopedPrinter(inputLoginDto).validateConnection();
this.logger.debug("Connection validation completed successfully");
} catch (e) {
this.logger.log("Printer connection validation failed");
this.logger.debug(`Error details: ${e}`);
if (e instanceof AxiosError) {
this.logger.debug(e.message + " " + e.status + " " + e.response?.status);
switch (e.response?.status) {
case 404: break;
case 401:
case 403: throw new FailedDependencyException("Authentication failed", e.response?.status);
case 0:
case 502:
case 503: throw new FailedDependencyException("Printer service unreachable", e.response?.status);
default: if (e.response?.status) throw new FailedDependencyException(`Reaching Printer service failed with status (code ${e.code})`, e.response?.status);
else throw new FailedDependencyException(`Reaching Printer service failed without status (code ${e.code})`);
}
}
throw new InternalServerException(`Could not call Printer service, internal problem`, e.stack);
}
}
};
__decorate([
GET(),
route("/"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "list", null);
__decorate([
POST(),
route("/"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "create", null);
__decorate([
POST(),
route("/batch"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "createBatch", null);
__decorate([
GET(),
route("/:id"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "getPrinter", null);
__decorate([
GET(),
route("/:id/socket"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "getPrinterSocketInfo", null);
__decorate([
PATCH(),
route("/:id"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "update", null);
__decorate([
DELETE(),
route("/:id"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "delete", null);
__decorate([
PATCH(),
route("/:id/enabled"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "updateEnabled", null);
__decorate([
PATCH(),
route("/:id/disabled-reason"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "updatePrinterDisabledReason", null);
__decorate([
POST(),
route("/:id/refresh-socket"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "refreshPrinterSocket", null);
__decorate([
POST(),
route("/test-connection"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "testConnection", null);
__decorate([
GET(),
route("/:id/login-details"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "getPrinterLoginDetails", null);
__decorate([
POST(),
route("/:id/send-emergency-m112"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "sendEmergencyM112", null);
__decorate([
POST(),
route("/:id/serial-connect"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "sendSerialConnectCommand", null);
__decorate([
POST(),
route("/:id/serial-disconnect"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "sendSerialDisconnectCommand", null);
__decorate([
POST(),
route("/:id/jog"),
route("/:id/move"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "movePrintHead", null);
__decorate([
POST(),
route("/:id/home"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "homeAxes", null);
__decorate([
POST(),
route("/:id/job/pause"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "pausePrint", null);
__decorate([
POST(),
route("/:id/job/resume"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "resumePrint", null);
__decorate([
POST(),
route("/:id/job/stop"),
route("/:id/job/cancel"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "cancelPrint", null);
__decorate([
POST(),
route("/:id/octoprint/server/restart"),
route("/:id/server/restart"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "restartServer", null);
__decorate([
PATCH(),
route("/:id/feed-rate"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "setFeedRate", null);
__decorate([
PATCH(),
route("/:id/flow-rate"),
__decorateMetadata("design:type", Function),
__decorateMetadata("design:paramtypes", [Object, Object]),
__decorateMetadata("design:returntype", Promise)
], PrinterController.prototype, "setFlowRate", null);
PrinterController = _PrinterController = __decorate([
route(AppConstants.apiRoute + "/printer"),
before([
authenticate(),
authorizeRoles([ROLES.OPERATOR, ROLES.ADMIN]),
printerResolveMiddleware()
]),
__decorateMetadata("design:paramtypes", [
Object,
typeof (_ref = typeof PrinterApiFactory !== "undefined" && PrinterApiFactory) === "function" ? _ref : Object,
typeof (_ref2 = typeof PrinterSocketStore !== "undefined" && PrinterSocketStore) === "function" ? _ref2 : Object,
typeof (_ref3 = typeof TestPrinterSocketStore !== "undefined" && TestPrinterSocketStore) === "function" ? _ref3 : Object,
Object,
typeof (_ref4 = typeof PrinterCache !== "undefined" && PrinterCache) === "function" ? _ref4 : Object,
typeof (_ref5 = typeof PrinterEventsCache !== "undefined" && PrinterEventsCache) === "function" ? _ref5 : Object,
Object,
typeof (_ref6 = typeof FloorStore !== "undefined" && FloorStore) === "function" ? _ref6 : Object
])
], PrinterController);
//#endregion
export { PrinterController, printer_controller_exports };
//# sourceMappingURL=printer.controller.js.map