# ===================================================================== # electron-builder – Paketierung für Windows (NSIS) und macOS (DMG) # --------------------------------------------------------------------- # CODE-SIGNIERUNG IST BEWUSST DEAKTIVIERT. # Die Anwendung wird privat weitergegeben, es gibt kein Entwicklerzertifikat. # Folgen, die den Nutzenden erklärt werden müssen: # - Windows SmartScreen zeigt beim ersten Start „Windows hat Ihren PC # geschützt“ → „Weitere Informationen“ → „Trotzdem ausführen“. # - macOS Gatekeeper blockiert die App → Rechtsklick auf die App → # „Öffnen“ → im Dialog erneut „Öffnen“ (bzw. Systemeinstellungen → # Datenschutz & Sicherheit → „Dennoch öffnen“). # ===================================================================== appId: de.willerding.waffensachkunde productName: Waffensachkunde Lernsoftware copyright: © 2026 Olaf Willerding directories: output: release # Bewusst NICHT "build": die .gitignore im Projektwurzelverzeichnis # ignoriert `build/`, dort abgelegte Icons würden also nie eingecheckt. # Icons gehören nach build-resources/ (icon.ico für Windows, # icon.icns bzw. icon.png >= 512x512 für macOS). buildResources: build-resources # Nur die gebauten Bundles paketieren – die Quellen bleiben draußen. files: - out/**/* - package.json - '!**/*.map' - '!**/{.eslintrc,.editorconfig,.prettierrc}' - '!**/{test,tests,__tests__,e2e}/**' # Die C-Quellen von better-sqlite3 – die SQLite-Amalgamation und der # Aufsatz darauf. Nachgemessen 9,9 MiB (deps) plus 162 KiB (src) in jedem # Paket, die nie jemand ausführt: `npmRebuild: false` weiter unten schaltet # den Bau aus der Quelle ab, und `lib/binding.js` lädt ausschließlich eine # fertige Datei aus `prebuilds/`. Bis Fassung 0.24.1 wurden sie mitgepackt. - '!**/node_modules/better-sqlite3/{deps,src}/**' - '!**/node_modules/better-sqlite3/binding.gyp' # Der amtliche Fragenkatalog liegt außerhalb von app/ und wird als Ressource # mitgepackt. Ziel ist /resources/katalog/ – genau dort sucht # src/main/katalog.ts, wenn app.isPackaged true ist. Bewusst NICHT im # asar-Archiv: so bleiben katalog.json und die Prüfzeichen normale Dateien, # die mit fs gelesen werden können. extraResources: - from: ../content/katalog to: katalog filter: - '**/*' # Erklaerungen zu den Fragen. Eigener redaktioneller Inhalt, deshalb # getrennt vom amtlichen Katalog; src/main/erklaerungen.ts sucht die # Datei im gepackten Betrieb direkt unter /resources/. - from: ../content/erklaerungen.json to: erklaerungen.json # Glossar der Fachbegriffe (WCAG 3.1.3 und 3.1.4). - from: ../content/glossar.json to: glossar.json # Die zitierten Normtexte. Ohne sie führte „Im Gesetz nachlesen" ins Leere: # Eine vollständig offline arbeitende Software forderte zu etwas auf, das # offline gerade nicht ging. Erzeugt aus content/gesetze/index.json mit # data-pipeline/normtexte_bauen.py – und nur die zitierten Normen, denn der # Index führt die sieben Gesetze vollständig, auch katalogfremde Normen. # Gesetzestexte sind nach § 5 Abs. 1 UrhG gemeinfrei. - from: ../content/normtexte.json to: normtexte.json # Die redaktionelle Feingliederung der Kapitel II bis IV. Der amtliche # Katalog gliedert nur Kapitel I in Abschnitte; ohne diese Datei laesst sich # von 230 Fragen nur das ganze Kapitel ueben. - from: ../content/themen.json to: themen.json # Deutsche Fassung der EUPL 1.2 und die Übersicht der Fremdkomponenten. # Beide zeigt der Bereich „Über diese Software“ an; MIT, BSD und Apache # verlangen die Mitlieferung ihrer Texte. Ziel ist jeweils # /resources/ – genau dort sucht src/main/lizenzen.ts im gepackten # Betrieb. - from: ../LICENSE.de.txt to: LICENSE.de.txt - from: ../content/drittlizenzen.json to: drittlizenzen.json # Die Datenschutzerklärung, erzeugt aus docs/datenschutz.md über # tools/datenschutz_anwendung.py. Bis 0.24.2 war sie in der Anwendung # nirgends erreichbar: docs/ wird nicht mitgeliefert, und der einzige Weg # nach außen führt zur Unterstützungsseite. src/main/datenschutz.ts sucht # die Datei im gepackten Betrieb direkt unter /resources/. - from: ../content/datenschutz.json to: datenschutz.json # better-sqlite3 ist ein natives Modul und muss außerhalb des asar-Archivs # liegen, damit der Prozess die .node-Datei laden kann. asar: true asarUnpack: - '**/node_modules/better-sqlite3/**' # Kein npmRebuild nötig: better-sqlite3 >= 12 liefert N-API-Prebuilds, die # ABI-stabil sind und ohne Neubau unter Electron laufen. npmRebuild: false # ── Windows ────────────────────────────────────────────────────────── win: # Fremde Fertigteile von better-sqlite3. `lib/binding.js` setzt den # Dateinamen zur Laufzeit aus `process.platform` und `process.arch` # zusammen; unter Windows kann also nur `win32-*.node` je geladen werden. # Die fünf anderen wogen nachgemessen 11,0 MiB im Paket. Beide # Windows-Architekturen bleiben – das Ziel unten baut zwar nur x64, aber # diese Liste soll nicht stillschweigend falsch werden, wenn dort arm64 # dazukommt. files: - '!**/node_modules/better-sqlite3/prebuilds/{darwin,linux,linuxmusl}-*.node' target: - target: nsis arch: [x64] artifactName: ${productName}-${version}-Setup-${arch}.${ext} # Keine Signierung: weder Zertifikat noch Zeitstempel-Server. signAndEditExecutable: true signtoolOptions: null nsis: oneClick: false perMachine: false allowToChangeInstallationDirectory: true allowElevation: true createDesktopShortcut: true createStartMenuShortcut: true shortcutName: Waffensachkunde deleteAppDataOnUninstall: false # Deutschsprachiger Installer. installerLanguages: - de_DE language: '1031' # LCID für Deutsch (Deutschland) # ── Microsoft Store (AppX/MSIX) ────────────────────────────────────── # # WARUM DIESER WEG UND NICHT „EXE or MSI app“ # Das Partner Center bietet beides an; die einfacher aussehende Option ist # die teure. Microsoft verlangt für EXE/MSI ein Installationspaket, das von # einer anerkannten Zertifizierungsstelle signiert ist, das der Betreiber # selbst dauerhaft hostet (versionierte Adresse je Fassung) und das still # installiert — der deutschsprachige NSIS-Assistent oben wäre unzulässig. # Für MSIX übernimmt Microsoft Signierung und Auslieferung kostenlos. # Begründung samt Belegstellen: docs/store-eintrag.md, Abschnitt 10 Punkt 1. # # WARUM NICHT IM `win.target` OBEN # Ein zusätzliches Ziel dort verdoppelte die Bauzeit jedes gewöhnlichen # `dist:win`, und `e2e/gepackt.spec.ts` misst ohnehin `release/win-unpacked/` # aus dem NSIS-Bau. Das Store-Paket entsteht deshalb über einen eigenen # Aufruf: `npm run dist:store`. # # WERKZEUGE # Keine Installation nötig. `makeappx.exe` und `makepri.exe` bringt # electron-builder in seinem eigenen Werkzeugpaket mit und lädt es beim # ersten Lauf. appx: # Die drei Werte stammen wörtlich aus dem Partner Center, # Produktverwaltung → Product Identity. Erfinden geht nicht: Weichen sie # ab, lehnt der Upload das Paket ab, ohne zu sagen, welcher es war. identityName: O-W.Waffensachkunde-Lernsoftware-OW publisher: CN=54A4AD0C-C0C3-49B6-922C-7F62CBEC7197 publisherDisplayName: O-W # ACHTUNG, hier schnappt eine Falle zu: `applicationId` fällt ohne diese # Zeile auf `identityName` zurück, und electron-builder prüft ihn gegen # /^([A-Za-z][A-Za-z0-9]*)(\.[A-Za-z][A-Za-z0-9]*)*$/ — **keine # Bindestriche**, jedes Feld muss mit einem Buchstaben beginnen. Der # Identitätsname enthält drei Bindestriche und fiele durch. Deshalb steht # hier ein eigener, gültiger Wert; er ist nur programmintern und erscheint # nirgends für Nutzende. applicationId: WaffensachkundeLernsoftware displayName: Waffensachkunde Lernsoftware # Kachelfarbe. `#1f2933` ist der dunkle Grundton der Anwendung; die # Store-Kachel soll nicht heller strahlen als das Programm dahinter. backgroundColor: '#1f2933' languages: - de-DE # Untergrenze des Betriebssystems. Ohne diese Zeile setzt electron-builder # für x64 pauschal `10.0.14316.0` (AppxTarget.js) – eine Insider-Fassung # von 2016. Der Store lässt die Installation dann auf Maschinen zu, auf # denen die mitgelieferte Chromium-Fassung 150 gar nicht startet: Sie # verlangt **Windows 10 1809 (Build 17763)**, so wie es # `docs/store-eintrag.md` 8.4 auch als Systemanforderung angibt. Der # Unterschied fiele nicht beim Bauen auf, sondern beim Anwender – als # Programm, das sich installieren lässt und nicht startet. minVersion: 10.0.17763.0 # Getestet ist bislang ausschließlich unter Windows 11; die Angabe bleibt # deshalb bei der Untergrenze, statt eine Erprobung zu behaupten, die es # nicht gibt. Ein Durchlauf unter Windows 10 steht aus # (`docs/store-eintrag.md`, Abschnitt 10 Punkt 5). maxVersionTested: 10.0.17763.0 # Der Dateiname erbt sonst `win.artifactName` und hieße „…-Setup-x64.appx“. # Ein Store-Paket ist kein Setup; wer beide Dateien nebeneinander liegen # hat, soll sie am Namen unterscheiden können. artifactName: ${productName}-${version}-Store-${arch}.${ext} # ── macOS ──────────────────────────────────────────────────────────── mac: # Dieselbe Rechnung wie unter Windows, gespiegelt: Unter macOS kann nur # `darwin-*.node` geladen werden. Beide darwin-Fertigteile bleiben, denn # das Ziel unten baut arm64 **und** x64. files: - '!**/node_modules/better-sqlite3/prebuilds/{win32,linux,linuxmusl}-*.node' target: - target: dmg arch: [arm64, x64] category: public.app-category.education artifactName: ${productName}-${version}-${arch}.${ext} # `identity: null` schaltet die Signierung explizit ab. identity: null # Hardened Runtime und Notarisierung setzen eine Signierung voraus und # sind deshalb ebenfalls aus. hardenedRuntime: false gatekeeperAssess: false notarize: false dmg: artifactName: ${productName}-${version}-${arch}.${ext} contents: - x: 140 y: 200 type: file - x: 400 y: 200 type: link path: /Applications # Keine automatischen Updates – die App wird manuell verteilt. publish: null