UNPKG

@slidef/cli

Version:

CLI tool for converting PDF slides to web-viewable format

125 lines 3.69 kB
import * as fs from 'fs/promises'; import * as path from 'path'; import * as crypto from 'crypto'; /** * Save metadata to JSON file */ export async function saveMetadata(outputDir, metadata) { const metadataPath = path.join(outputDir, 'metadata.json'); await fs.writeFile(metadataPath, JSON.stringify(metadata, null, 2)); } /** * Load metadata from JSON file */ export async function loadMetadata(slideDir) { const metadataPath = path.join(slideDir, 'metadata.json'); try { const content = await fs.readFile(metadataPath, 'utf-8'); return JSON.parse(content); } catch { return null; } } /** * Get all slide directories in the slides folder */ export async function getAllSlides(slidesDir) { try { const entries = await fs.readdir(slidesDir, { withFileTypes: true }); const slides = []; for (const entry of entries) { if (entry.isDirectory()) { const metadata = await loadMetadata(path.join(slidesDir, entry.name)); if (metadata) { slides.push(metadata); } } } // Sort by createdAt date (newest first) slides.sort((a, b) => { const dateA = new Date(a.createdAt).getTime(); const dateB = new Date(b.createdAt).getTime(); return dateB - dateA; }); return slides; } catch { return []; } } /** * Load all slides from the slides directory (alias for getAllSlides) */ export async function loadSlides(slidesDir) { return getAllSlides(slidesDir); } /** * Save slide index */ export async function saveSlideIndex(outputDir, slides) { const index = { slides, updatedAt: new Date().toISOString(), }; const indexPath = path.join(outputDir, 'slides-index.json'); await fs.writeFile(indexPath, JSON.stringify(index, null, 2)); } /** * Check if file exists */ export async function fileExists(filePath) { try { await fs.access(filePath); return true; } catch { return false; } } /** * Get filename without extension */ export function getBaseName(filePath) { return path.basename(filePath, path.extname(filePath)); } /** * Calculate SHA256 hash of a file */ export async function calculateFileHash(filePath) { const fileBuffer = await fs.readFile(filePath); const hashSum = crypto.createHash('sha256'); hashSum.update(fileBuffer); return hashSum.digest('hex'); } /** * Normalize filename to be filesystem-safe * - Converts to lowercase * - Replaces spaces with hyphens * - Normalizes Unicode characters (NFD -> NFC) * - Removes special characters except alphanumeric, hyphen, and underscore */ export function normalizeFilename(name) { return name .normalize('NFC') // Unicode normalization .toLowerCase() .replace(/\s+/g, '-') // Replace spaces with hyphens .replace(/[^\w\-가-힣ぁ-んァ-ヶ一-龯]/g, '') // Keep alphanumeric, hyphen, and CJK characters .replace(/\-+/g, '-') // Replace multiple hyphens with single hyphen .replace(/^\-+|\-+$/g, ''); // Remove leading/trailing hyphens } /** * Generate a unique slide name by appending count if name exists */ export async function generateUniqueSlideName(slidesDir, baseName) { const normalized = normalizeFilename(baseName); let slideName = normalized; let count = 1; // Check if directory exists while (await fileExists(path.join(slidesDir, slideName))) { slideName = `${normalized}-${count}`; count++; } return slideName; } //# sourceMappingURL=file.js.map