const { app, BrowserWindow } = require('electron'); const {randomUUID} = require("node:crypto"); const { Command } = require('commander'); const express = require('express'); const multer = require('multer'); const path = require("path"); const fs = require("fs"); function writeFile(ext,data) { let file = randomUUID() + "." + ext; fs.writeFileSync( path .resolve( __dirname, "./output/", file ), data ); return file; } /** * @param {{type,website,range,background,size}} options * @returns {Promise<[Buffer,string]>} */ async function generatePDF(options) { const win = new BrowserWindow({ webPreferences:{ contextIsolation: true, nodeIntegration: false, disableDialogs: false, webSecurity: true }, show: false, width: options.width, height: options.height }); await new Promise(ok => { win.webContents.addListener("did-finish-load",()=>{ ok() }); win.webContents.addListener("did-fail-load",()=>{ console.error("Hata oluştu") }); if(options.htmlcontent) { win.loadURL(`data:text/html;base64,${Buffer.from(options.htmlcontent).toString("base64")}`); }else{ win.loadURL(options.endpoint); } }) let result = await new Promise(result => { switch(options.type) { case "mhtml":{ win.webContents.savePage(path.resolve(__dirname, randomUUID() + ".mhtml"),"HTMLOnly"); break; } case "image":{ win.webContents.setZoomFactor(Math.max(0, Math.min(3.0, options.zoom))) win.webContents.capturePage().then(e => { let binary = e.toPNG(); result([binary, "png"]); }); break; } case "pdf":{ win.webContents.printToPDF({ printBackground: true, displayHeaderFooter: false, scale: options.scale, landscape: options.landscape, pageSize: options.pageSize, pageRanges: options.pageRanges }).then(data => { result([data, "pdf"]); }); break; } } }); win.destroy(); return result; }; app.disableDomainBlockingFor3DAPIs(); app.disableHardwareAcceleration(); app.addListener("window-all-closed",function(){ }); async function main() { await new Promise(ok => { app.whenReady().then(() => { ok() }); }); let port = express(); port.use(express.static(path.resolve(__dirname,"./output/"),{ acceptRanges: true, cacheControl: true, etag: true, lastModified: true })) port.use(express.static(path.resolve(__dirname,"./public/"),{ acceptRanges: true, cacheControl: true, etag: true, lastModified: true })) port.use(function(request, response, next){ response.header("Access-Control-Allow-Origin","*"); response.header("Access-Control-Allow-Headers","*"); response.header("Access-Control-Allow-Methods","GET, POST, OPTION"); next(); }); let memory = multer({storage: multer.memoryStorage()}).none(); port.post("/pdf", memory,async (request, response) => { let { width, height, scale, content: htmlcontent, endpoint, isLandscape, pageSize, pageRanges, output } = request.body; output = output || "content"; let [content, extension] = await generatePDF({ htmlcontent, endpoint, type: "pdf", landscape: isLandscape || false, scale: scale || 1.0, width: width || 1920, height: height || 1080, pageSize: pageSize || "A4", range: pageRanges || "" }); switch(output) { case "json":{ let image = writeFile(extension,content); response.json({ status: "success", data: image, type: "pdf" }); break; } case "json+base64":{ response.json({ status: "success", data: `data:application/pdf;base64,${content.toString("base64")}`, type: "pdf" }); break; } case "content":{ response.contentType(extension); response.end(content); break; } } }); port.post("/image", memory,async (request, response) => { let { width, height, zoom, content: htmlcontent, endpoint, output } = request.body; output = output || "content"; let [content, extension] = await generatePDF({ htmlcontent, endpoint, type: "image", zoom: zoom || 1.0, width: width || 1920, height: height || 1080 }); switch(output) { case "json":{ let image = writeFile(extension,content); response.json({ status: "success", data: image, type: "image" }); break; } case "json+base64":{ response.json({ status: "success", data: `data:image/png;base64,${content.toString("base64")}`, type: "image" }); break; } case "content":{ response.contentType(extension); response.end(content); break; } } }); port.listen(8473); } process.nextTick(main);