anki-mcp-http
Version: 
Model Context Protocol server for Anki - enables AI assistants to interact with your Anki flashcards
153 lines • 4.66 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.cleanHtml = cleanHtml;
exports.extractCardContent = extractCardContent;
exports.getCardType = getCardType;
exports.getNoteType = getNoteType;
exports.getRatingDescription = getRatingDescription;
exports.createSuccessResponse = createSuccessResponse;
exports.createErrorResponse = createErrorResponse;
exports.formatInterval = formatInterval;
exports.parseDeckStats = parseDeckStats;
const anki_types_1 = require("../types/anki.types");
const anki_connect_client_1 = require("../clients/anki-connect.client");
function cleanHtml(html) {
    return html
        .replace(/<[^>]*>/g, '')
        .replace(/ /g, ' ')
        .replace(/&/g, '&')
        .replace(/</g, '<')
        .replace(/>/g, '>')
        .replace(/"/g, '"')
        .replace(/'/g, "'")
        .replace(/\n\s*\n/g, '\n')
        .trim();
}
function extractCardContent(fields) {
    let front = '';
    let back = '';
    if (!fields) {
        return { front, back };
    }
    const frontFieldNames = ['Front', '正面', 'Question', 'Text'];
    const backFieldNames = ['Back', '背面', 'Answer', 'Extra', 'Back Extra'];
    for (const fieldName of frontFieldNames) {
        if (fields[fieldName]) {
            front = fields[fieldName].value;
            break;
        }
    }
    for (const fieldName of backFieldNames) {
        if (fields[fieldName]) {
            back = fields[fieldName].value;
            break;
        }
    }
    if (!front && !back) {
        const fieldEntries = Object.entries(fields)
            .sort((a, b) => a[1].order - b[1].order);
        if (fieldEntries.length > 0) {
            front = fieldEntries[0][1].value;
        }
        if (fieldEntries.length > 1) {
            back = fieldEntries[1][1].value;
        }
    }
    return {
        front: cleanHtml(front),
        back: cleanHtml(back)
    };
}
function getCardType(type) {
    switch (type) {
        case anki_types_1.CardType.New: return 'new';
        case anki_types_1.CardType.Learning: return 'learning';
        case anki_types_1.CardType.Review: return 'review';
        case anki_types_1.CardType.Relearning: return 'relearning';
        default: return 'unknown';
    }
}
function getNoteType(modelName) {
    const lowerName = modelName.toLowerCase();
    if (lowerName.includes('basic')) {
        if (lowerName.includes('reverse')) {
            return 'Basic (and reversed card)';
        }
        return 'Basic';
    }
    if (lowerName.includes('cloze')) {
        return 'Cloze';
    }
    return 'Custom';
}
function getRatingDescription(rating) {
    switch (rating) {
        case anki_types_1.CardRating.Again:
            return 'Again (failed to recall)';
        case anki_types_1.CardRating.Hard:
            return 'Hard (recalled with difficulty)';
        case anki_types_1.CardRating.Good:
            return 'Good (recalled with some effort)';
        case anki_types_1.CardRating.Easy:
            return 'Easy (recalled instantly)';
        default:
            return 'Unknown';
    }
}
function createSuccessResponse(data) {
    return {
        content: [
            {
                type: 'text',
                text: JSON.stringify(data, null, 2),
            },
        ],
    };
}
function createErrorResponse(error, context) {
    const errorData = {
        success: false,
        error: error instanceof Error ? error.message : 'Unknown error occurred',
    };
    if (error instanceof anki_connect_client_1.AnkiConnectError) {
        if (error.action) {
            errorData.action = error.action;
        }
    }
    if (context) {
        Object.assign(errorData, context);
    }
    return {
        content: [
            {
                type: 'text',
                text: JSON.stringify(errorData, null, 2),
            },
        ],
        isError: true,
    };
}
function formatInterval(days) {
    if (days < 1) {
        const hours = Math.round(days * 24);
        return `${hours} hour${hours !== 1 ? 's' : ''}`;
    }
    if (days < 30) {
        return `${Math.round(days)} day${days !== 1 ? 's' : ''}`;
    }
    if (days < 365) {
        const months = Math.round(days / 30);
        return `${months} month${months !== 1 ? 's' : ''}`;
    }
    const years = Math.round(days / 365 * 10) / 10;
    return `${years} year${years !== 1 ? 's' : ''}`;
}
function parseDeckStats(stats) {
    return {
        new_count: stats.new_count || 0,
        learn_count: stats.lrn_count || 0,
        review_count: stats.rev_count || 0,
        total_cards: stats.total || 0,
    };
}
//# sourceMappingURL=anki.utils.js.map