UNPKG

@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
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