1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
| import {
| abgleichMisserfolg,
| alsIsoDatum,
| dateinameAusUrl,
| dateiVorhanden,
| ersetzeDateiSicher,
| inhaltBeanstanden,
| type Abgleichauftrag,
| type Bezugsquelle,
| type QuellenAbgleich,
| } from './basis';
|
| /** Direkter Download-Link: lädt die Datei, erkennt Änderungen über ETag/Last-Modified. */
| export class DirektLinkQuelle implements Bezugsquelle {
| async gleicheAb(auftrag: Abgleichauftrag): Promise<QuellenAbgleich> {
| try {
| const antwort = await fetch(auftrag.wert, { redirect: 'follow' });
| if (!antwort.ok) {
| return abgleichMisserfolg(auftrag.aktuelleVersion, `Server nicht erreichbar (HTTP ${antwort.status}).`);
| }
| const kennung = antwort.headers.get('etag') ?? antwort.headers.get('last-modified') ?? '';
| const veroeffentlichtAm = alsIsoDatum(antwort.headers.get('last-modified'));
| const dateiname = dateinameAusUrl(auftrag.wert);
| if (kennung && kennung === auftrag.aktuelleVersion && dateiVorhanden(auftrag.zielordner, dateiname)) {
| return { erfolg: true, geaendert: false, version: kennung, dateiname, meldung: 'Bereits aktuell.', veroeffentlichtAm };
| }
|
| const inhalt = Buffer.from(await antwort.arrayBuffer());
| const beanstandung = inhaltBeanstanden(inhalt, dateiname, antwort.headers.get('content-type'), auftrag.vorherigeGroesse);
| if (beanstandung) {
| return abgleichMisserfolg(auftrag.aktuelleVersion, beanstandung);
| }
|
| ersetzeDateiSicher(auftrag.zielordner, dateiname, inhalt);
| return { erfolg: true, geaendert: true, version: kennung || new Date().toISOString(), dateiname, meldung: 'Aktualisiert.', veroeffentlichtAm };
| } catch (fehler) {
| return abgleichMisserfolg(auftrag.aktuelleVersion, `Download fehlgeschlagen: ${fehler instanceof Error ? fehler.message : String(fehler)}`);
| }
| }
| }
|
|