@slidef/cli
Version:
CLI tool for converting PDF slides to web-viewable format
125 lines • 3.69 kB
JavaScript
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