97 lines
2.8 KiB
JavaScript
97 lines
2.8 KiB
JavaScript
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
|
|
const loadConfig = async () => {
|
|
const configUrl = new URL("../config.local.json", import.meta.url);
|
|
try {
|
|
const raw = await readFile(configUrl, "utf-8");
|
|
return JSON.parse(raw);
|
|
} catch {
|
|
return {};
|
|
}
|
|
};
|
|
|
|
const sanitizeFileName = (value) => {
|
|
const normalized = value
|
|
.toLowerCase()
|
|
.replace(/[^a-z0-9]+/g, "-")
|
|
.replace(/^-+|-+$/g, "");
|
|
return normalized || "spiel";
|
|
};
|
|
|
|
const fetchEpicGames = async ({ accountId, accessToken }) => {
|
|
// ⚠️ Epic Games Store hat KEINE öffentliche API!
|
|
// Legendary (Python CLI) funktioniert nicht auf iOS/Web
|
|
// Lösung: Backend mit Epic OAuth oder manuelle Import-Funktion
|
|
console.warn("⚠️ Epic Games: Keine öffentliche API verfügbar");
|
|
console.log(" → Für iOS/Web: Backend mit Epic OAuth benötigt");
|
|
console.log(" → Alternative: Manuelle Library-Import-Funktion\n");
|
|
return [];
|
|
};
|
|
|
|
const buildEpicEntry = (game) => ({
|
|
id: game.id || game.catalogItemId,
|
|
title: game.title || game.displayName,
|
|
platform: "PC",
|
|
lastPlayed: game.lastPlayed || null,
|
|
playtimeHours: game.playtimeMinutes
|
|
? Math.round((game.playtimeMinutes / 60) * 10) / 10
|
|
: 0,
|
|
tags: game.categories || [],
|
|
url: game.productSlug
|
|
? `https://store.epicgames.com/en-US/p/${game.productSlug}`
|
|
: null,
|
|
});
|
|
|
|
const buildTextFile = (entry) => {
|
|
const lines = [
|
|
`Titel: ${entry.title}`,
|
|
`Epic ID: ${entry.id}`,
|
|
`Zuletzt gespielt: ${entry.lastPlayed ?? "-"}`,
|
|
`Spielzeit (h): ${entry.playtimeHours ?? 0}`,
|
|
`Store: ${entry.url ?? "-"}`,
|
|
"Quelle: epic",
|
|
];
|
|
return lines.join("\n") + "\n";
|
|
};
|
|
|
|
const writeOutputs = async (entries) => {
|
|
const dataDir = new URL("../public/data/", import.meta.url);
|
|
const textDir = new URL("../public/data/epic-text/", import.meta.url);
|
|
|
|
await mkdir(dataDir, { recursive: true });
|
|
await mkdir(textDir, { recursive: true });
|
|
|
|
const jsonPath = new URL("epic.json", dataDir);
|
|
await writeFile(jsonPath, JSON.stringify(entries, null, 2) + "\n", "utf-8");
|
|
|
|
await Promise.all(
|
|
entries.map(async (entry) => {
|
|
const fileName = `${sanitizeFileName(entry.title)}__${entry.id}.txt`;
|
|
const filePath = new URL(fileName, textDir);
|
|
await writeFile(filePath, buildTextFile(entry), "utf-8");
|
|
}),
|
|
);
|
|
};
|
|
|
|
const run = async () => {
|
|
const config = await loadConfig();
|
|
const accountId = config.epic?.accountId || process.env.EPIC_ACCOUNT_ID;
|
|
const accessToken = config.epic?.accessToken || process.env.EPIC_ACCESS_TOKEN;
|
|
|
|
if (!accountId || !accessToken) {
|
|
console.warn(
|
|
"Epic-Zugangsdaten nicht gesetzt. Erstelle leere Datei als Platzhalter.",
|
|
);
|
|
}
|
|
|
|
const games = await fetchEpicGames({ accountId, accessToken });
|
|
const entries = games.map(buildEpicEntry);
|
|
await writeOutputs(entries);
|
|
console.log(`Epic-Export fertig: ${entries.length} Spiele.`);
|
|
};
|
|
|
|
run().catch((error) => {
|
|
console.error(error);
|
|
process.exit(1);
|
|
});
|