You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

45 lines
1.6 KiB

  1. // Bootstrap "stato di fabbrica" automatico all'avvio.
  2. //
  3. // Se all'avvio del server NON ci sono card in data/cards.txt (file mancante o `[]`)
  4. // E esiste factory/preset.zip, il preset viene estratto sopra a data/.
  5. // È quello che permette a una macchina appena clonata/distribuita di partire con
  6. // lo stato standard senza interventi manuali.
  7. import { readFile, access } from 'node:fs/promises';
  8. import path from 'node:path';
  9. import { restoreFromZipFile } from './restore-zip';
  10. const PROJECT_ROOT = process.cwd();
  11. const CARDS_FILE = path.join(PROJECT_ROOT, 'data', 'cards.txt');
  12. const PRESET_PATH = path.join(PROJECT_ROOT, 'factory', 'preset.zip');
  13. async function hasCards(): Promise<boolean> {
  14. try {
  15. const raw = await readFile(CARDS_FILE, 'utf-8');
  16. const parsed = JSON.parse(raw || '[]');
  17. return Array.isArray(parsed) && parsed.length > 0;
  18. } catch {
  19. return false;
  20. }
  21. }
  22. export async function bootstrapFromFactoryPresetIfEmpty(): Promise<void> {
  23. // Niente preset di fabbrica → niente da fare, sezione opzionale.
  24. try {
  25. await access(PRESET_PATH);
  26. } catch {
  27. return;
  28. }
  29. // Stato non vuoto → l'admin ha già contenuti, non sovrascriviamo.
  30. if (await hasCards()) return;
  31. console.log('[bootstrap] No cards found; restoring factory preset from factory/preset.zip');
  32. const result = await restoreFromZipFile(PRESET_PATH);
  33. if (result.ok) {
  34. console.log(`[bootstrap] Restored ${result.cards} cards, ${result.portals} portals from factory preset`);
  35. } else {
  36. console.warn(`[bootstrap] Factory restore failed: ${result.error}${result.detail ? ` (${result.detail})` : ''}`);
  37. }
  38. }