/* ===================================================================== Verträglichkeitsprüfung: multer und node-cron Aufruf: node test-pakete.mjs (im Verzeichnis server-internal) WARUM ÜBERHAUPT Beide sind Hauptversionssprünge. Die Veröffentlichungshinweise nennen nur je eine Änderung — bei multer die Node-Mindestfassung, bei node-cron die Umstellung auf TypeScript. Das klingt harmlos, sagt aber nichts darüber, ob UNSER Code weiterläuft: Bei einer TypeScript-Umstellung ändert sich häufig die Art des Standard-Exports. "import cron from 'node-cron'" kann danach ein Objekt liefern, das die erwartete Funktion gar nicht hat — und das fällt erst beim Start auf, nicht bei der Installation. Deshalb werden hier genau die Aufrufe nachgebildet, die in server-internal/index.js stehen. Nicht irgendwelche, sondern diese. Vor der Umstellung am 26.08.2026 in einem eigenen Verzeichnis gegen multer 2.2.0 und node-cron 4.6.0 geprüft: 15 von 15 bestanden. Die Datei bleibt, damit dieselbe Prüfung nach jedem künftigen Sprung wiederholbar ist — die Frage "läuft unser Code damit noch?" stellt sich bei jedem Hauptversionswechsel neu. ===================================================================== */ import multer from "multer"; import cron from "node-cron"; import fs from "fs"; import path from "path"; let ok = 0, fehl = 0; const pruefe = (name, gut, info) => { if (gut) { ok++; console.log(" ok " + name + (info ? " -> " + info : "")); } else { fehl++; console.log(" FEHL " + name + (info ? " -> " + info : "")); } }; console.log("1. MULTER — die Aufrufe aus index.js"); pruefe("Standard-Export ist aufrufbar", typeof multer === "function", typeof multer); pruefe("multer.diskStorage vorhanden", typeof multer.diskStorage === "function"); pruefe("multer.MulterError vorhanden", typeof multer.MulterError === "function"); /* Genau die Form aus index.js: diskStorage mit destination/filename, dazu limits und fileFilter. */ const ziel = path.join(process.cwd(), "probe-ablage"); fs.mkdirSync(ziel, { recursive: true }); let hochlader = null; try { hochlader = multer({ storage: multer.diskStorage({ destination: (req, datei, weiter) => weiter(null, ziel), filename: (req, datei, weiter) => weiter(null, "probe.png"), }), limits: { fileSize: 5 * 1024 * 1024, files: 1 }, fileFilter: (req, datei, weiter) => { if (!/^image\/(png|jpe?g|webp)$/.test(datei.mimetype)) { return weiter(new Error("Nur Bilder.")); } weiter(null, true); }, }); pruefe("multer({ storage, limits, fileFilter }) baut", !!hochlader); } catch (e) { pruefe("multer({ storage, limits, fileFilter }) baut", false, e.message); } pruefe("upload.single() liefert eine Middleware", hochlader && typeof hochlader.single("bild") === "function"); pruefe("upload.array() liefert eine Middleware", hochlader && typeof hochlader.array("bilder", 5) === "function"); pruefe("upload.fields() liefert eine Middleware", hochlader && typeof hochlader.fields([{ name: "a" }]) === "function"); /* Die Fehlerbehandlung in index.js prüft auf "err instanceof multer.MulterError" und liest err.code. Wenn sich dort etwas geändert hätte, würde jede Größenüberschreitung als unbekannter Serverfehler enden statt als saubere Meldung an den Benutzer. */ try { const f = new multer.MulterError("LIMIT_FILE_SIZE", "bild"); pruefe("MulterError trägt weiterhin einen code", f.code === "LIMIT_FILE_SIZE", f.code); pruefe("und ist ein echter Fehler", f instanceof Error); } catch (e) { pruefe("MulterError lässt sich erzeugen", false, e.message); } console.log("\n2. NODE-CRON — der Aufruf aus index.js"); pruefe("Standard-Export vorhanden", !!cron, typeof cron); pruefe("cron.schedule ist eine Funktion", typeof cron.schedule === "function", typeof cron.schedule); pruefe("cron.validate ist eine Funktion", typeof cron.validate === "function"); /* Genau der Ausdruck aus index.js. */ pruefe('Ausdruck "* * * * *" gilt als gültig', cron.validate("* * * * *") === true); let lief = 0; let aufgabe = null; try { aufgabe = cron.schedule("* * * * *", () => { lief++; }); pruefe("cron.schedule() legt eine Aufgabe an", !!aufgabe); /* In 3.x hiess die Methode stop(). Faellt sie weg, laeuft der Zeitgeber beim Herunterfahren weiter. */ pruefe("die Aufgabe lässt sich stoppen", typeof aufgabe.stop === "function", typeof aufgabe.stop); } catch (e) { pruefe("cron.schedule() legt eine Aufgabe an", false, e.message); } if (aufgabe && typeof aufgabe.stop === "function") aufgabe.stop(); /* Aufräumen */ try { fs.rmSync(ziel, { recursive: true, force: true }); } catch {} console.log(`\n===== ${ok} bestanden, ${fehl} fehlgeschlagen =====`); process.exit(fehl ? 1 : 0);