code icon Code

Save Flashcard Deck

Create a new deck or add cards to an existing deck from session data

Source Code

import { readFileSync, writeFileSync, existsSync } from "fs";

const [newCardsPath, decksPath] = process.argv.slice(2);

try {
  // Read the new cards from session
  const newCardsData = JSON.parse(readFileSync(newCardsPath, "utf-8"));
  const { deckName, sourceDescription, cards } = newCardsData;

  if (!deckName || !cards || !Array.isArray(cards) || cards.length === 0) {
    console.log(
      JSON.stringify({
        success: false,
        error: "Invalid new cards data: missing deckName or cards array",
      })
    );
    process.exit(1);
  }

  // Load existing decks or initialize empty
  let decksData = { decks: {} };
  if (existsSync(decksPath)) {
    try {
      decksData = JSON.parse(readFileSync(decksPath, "utf-8"));
    } catch {
      // File exists but is invalid JSON, start fresh
      decksData = { decks: {} };
    }
  }

  // Generate deck slug from name
  const slug = deckName
    .toLowerCase()
    .replace(/[^a-z0-9\s-]/g, "")
    .replace(/\s+/g, "-")
    .replace(/-+/g, "-")
    .trim();

  const today = new Date().toISOString().split("T")[0];

  // Prepare cards with SRS metadata
  const preparedCards = cards.map((card, index) => ({
    id: `card-${Date.now()}-${index}`,
    front: card.front,
    back: card.back,
    created: today,
    lastReviewed: null,
    nextReview: today, // Due immediately for first review
    interval: 1,
    correctCount: 0,
    incorrectCount: 0,
  }));

  // Check if deck already exists
  if (decksData.decks[slug]) {
    // Add cards to existing deck
    const existingCount = decksData.decks[slug].cards.length;
    decksData.decks[slug].cards.push(...preparedCards);
    console.log(
      JSON.stringify({
        success: true,
        action: "updated",
        deckName: deckName,
        slug: slug,
        cardsAdded: preparedCards.length,
        totalCards: decksData.decks[slug].cards.length,
        message: `Added ${preparedCards.length} cards to existing deck "${deckName}" (now ${decksData.decks[slug].cards.length} total cards)`,
      })
    );
  } else {
    // Create new deck
    decksData.decks[slug] = {
      name: deckName,
      created: today,
      sourceDescription: sourceDescription || "",
      cards: preparedCards,
    };
    console.log(
      JSON.stringify({
        success: true,
        action: "created",
        deckName: deckName,
        slug: slug,
        cardCount: preparedCards.length,
        message: `Created deck "${deckName}" with ${preparedCards.length} cards`,
      })
    );
  }

  // Save updated decks
  writeFileSync(decksPath, JSON.stringify(decksData, null, 2));
} catch (error) {
  console.log(
    JSON.stringify({
      success: false,
      error: `Failed to save deck: ${error.message}`,
    })
  );
  process.exit(1);
}