@stack.thefennec.dev/telegram-export-parser
Version:
TypeScript library for parsing Telegram Desktop's data export with full type safety
312 lines • 10.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MENTION_TEXT_ENTITY_TYPES = exports.LINK_TEXT_ENTITY_TYPES = exports.CODE_TEXT_ENTITY_TYPES = exports.FORMATTED_TEXT_ENTITY_TYPES = exports.TEXT_ENTITY_TYPES = void 0;
exports.isPlainTextEntity = isPlainTextEntity;
exports.isFormattedTextEntity = isFormattedTextEntity;
exports.isSpoilerTextEntity = isSpoilerTextEntity;
exports.isCodeTextEntity = isCodeTextEntity;
exports.isLinkTextEntity = isLinkTextEntity;
exports.isMentionTextEntity = isMentionTextEntity;
exports.isCustomEmojiTextEntity = isCustomEmojiTextEntity;
exports.isQuoteTextEntity = isQuoteTextEntity;
// =====================================================
// TEXT ENTITY TYPE CONSTANTS
// =====================================================
/**
* Comprehensive constants for all Telegram text entity types.
*
* Text entities represent rich formatting, links, mentions, and special
* elements within message text. Each entity has a specific type that
* determines how it should be rendered and what additional data it contains.
*
* @example
* ```typescript
* // Check entity types
* if (entity.type === TEXT_ENTITY_TYPES.BOLD) {
* console.log('Bold text:', entity.text)
* }
*
* // Render as Markdown
* const markdown = entity.toMarkdown() // "**bold text**"
* ```
*/
exports.TEXT_ENTITY_TYPES = {
/** Unformatted plain text segment */
PLAIN: "plain",
// ===== FORMATTING ENTITIES =====
/** Bold text formatting (**text**) */
BOLD: "bold",
/** Italic text formatting (*text*) */
ITALIC: "italic",
/** Strikethrough text formatting (~~text~~) */
STRIKETHROUGH: "strikethrough",
/** Underlined text formatting */
UNDERLINE: "underline",
/** Bank card number formatting (for security) */
BANK_CARD: "bank_card",
/** Spoiler text that's initially hidden */
SPOILER: "spoiler",
// ===== CODE ENTITIES =====
/** Inline code formatting (`code`) */
CODE: "code",
/** Code block formatting with optional language */
PRE: "pre",
// ===== LINK ENTITIES =====
/** Clickable text link with custom URL */
TEXT_LINK: "text_link",
/** Auto-detected URL link */
LINK: "link",
/** Hashtag (#hashtag) */
HASHTAG: "hashtag",
/** Stock ticker/cashtag ($TICKER) */
CASHTAG: "cashtag",
/** Bot command (/command) */
BOT_COMMAND: "bot_command",
/** Email address (auto-detected) */
EMAIL: "email",
/** Phone number (auto-detected) */
PHONE: "phone",
// ===== MENTION ENTITIES =====
/** Username mention (@username) */
MENTION: "mention",
/** User mention by display name */
MENTION_NAME: "mention_name",
// ===== SPECIAL ENTITIES =====
/** Custom emoji or sticker */
CUSTOM_EMOJI: "custom_emoji",
/** Block quote formatting */
BLOCKQUOTE: "blockquote"
};
// =====================================================
// UNION TYPES
// =====================================================
// =====================================================
// TYPE GROUP CONSTANTS
// =====================================================
/**
* Array of all formatting entity types for easy iteration and validation.
* Used by type guards and processing functions.
*/
exports.FORMATTED_TEXT_ENTITY_TYPES = [
exports.TEXT_ENTITY_TYPES.BOLD,
exports.TEXT_ENTITY_TYPES.ITALIC,
exports.TEXT_ENTITY_TYPES.STRIKETHROUGH,
exports.TEXT_ENTITY_TYPES.UNDERLINE,
exports.TEXT_ENTITY_TYPES.BANK_CARD
];
/**
* Array of all code entity types for easy iteration and validation.
* Used by type guards and processing functions.
*/
exports.CODE_TEXT_ENTITY_TYPES = [
exports.TEXT_ENTITY_TYPES.CODE,
exports.TEXT_ENTITY_TYPES.PRE
];
/**
* Array of all link entity types for easy iteration and validation.
* Used by type guards and processing functions.
*/
exports.LINK_TEXT_ENTITY_TYPES = [
exports.TEXT_ENTITY_TYPES.TEXT_LINK,
exports.TEXT_ENTITY_TYPES.LINK,
exports.TEXT_ENTITY_TYPES.HASHTAG,
exports.TEXT_ENTITY_TYPES.CASHTAG,
exports.TEXT_ENTITY_TYPES.BOT_COMMAND,
exports.TEXT_ENTITY_TYPES.EMAIL,
exports.TEXT_ENTITY_TYPES.PHONE
];
/**
* Array of all mention entity types for easy iteration and validation.
* Used by type guards and processing functions.
*/
exports.MENTION_TEXT_ENTITY_TYPES = [
exports.TEXT_ENTITY_TYPES.MENTION,
exports.TEXT_ENTITY_TYPES.MENTION_NAME
];
// =====================================================
// TYPE GUARD HELPERS
// =====================================================
/**
* Helper function to check if an entity type is in a list of allowed types.
* Reduces duplication across type guard functions.
*/
function isEntityTypeIn(entityType, allowedTypes) {
return allowedTypes.includes(entityType);
}
// =====================================================
// TYPE GUARD FUNCTIONS
// =====================================================
/**
* Type guard to check if a text entity is plain text without formatting.
*
* @param entity - The text entity to check
* @returns True if the entity is plain text
*
* @example
* ```typescript
* if (isPlainTextEntity(entity)) {
* // No special processing needed, just use entity.text
* console.log(entity.text)
* }
* ```
*/
function isPlainTextEntity(entity) {
return entity.type === exports.TEXT_ENTITY_TYPES.PLAIN;
}
/**
* Type guard to check if a text entity has visual formatting.
*
* Includes bold, italic, strikethrough, underline, and bank card formatting.
*
* @param entity - The text entity to check
* @returns True if the entity has formatting
*
* @example
* ```typescript
* if (isFormattedTextEntity(entity)) {
* // Apply visual styling based on entity.type
* const styled = entity.toHTML() // <strong>text</strong>, <em>text</em>, etc.
* console.log(styled)
* }
* ```
*/
function isFormattedTextEntity(entity) {
return isEntityTypeIn(entity.type, exports.FORMATTED_TEXT_ENTITY_TYPES);
}
/**
* Type guard to check if a text entity is spoiler text.
*
* Spoiler text should be initially hidden and require user interaction to reveal.
*
* @param entity - The text entity to check
* @returns True if the entity is spoiler text
*
* @example
* ```typescript
* if (isSpoilerTextEntity(entity)) {
* // Render with spoiler styling
* console.log(`<span class="spoiler" onclick="reveal()">${entity.text}</span>`)
* }
* ```
*/
function isSpoilerTextEntity(entity) {
return entity.type === exports.TEXT_ENTITY_TYPES.SPOILER;
}
/**
* Type guard to check if a text entity contains code.
*
* Includes both inline code and code blocks with optional syntax highlighting.
*
* @param entity - The text entity to check
* @returns True if the entity contains code
*
* @example
* ```typescript
* if (isCodeTextEntity(entity)) {
* if (entity.type === 'pre' && entity.language) {
* // Apply syntax highlighting for the specified language
* console.log(`Code block in ${entity.language}: ${entity.text}`)
* } else {
* // Render as inline or plain code
* console.log(`Code: ${entity.text}`)
* }
* }
* ```
*/
function isCodeTextEntity(entity) {
return isEntityTypeIn(entity.type, exports.CODE_TEXT_ENTITY_TYPES);
}
/**
* Type guard to check if a text entity is a clickable link.
*
* Includes web links, bot commands, hashtags, contact info, and more.
*
* @param entity - The text entity to check
* @returns True if the entity is a link
*
* @example
* ```typescript
* if (isLinkTextEntity(entity)) {
* switch (entity.type) {
* case 'text_link':
* return `<a href="${entity.url}">${entity.text}</a>`
* case 'bot_command':
* return `<button onclick="executeCommand('${entity.text}')">${entity.text}</button>`
* case 'hashtag':
* return `<a href="/search?q=${encodeURIComponent(entity.text)}">${entity.text}</a>`
* default:
* return `<a href="${entity.url}">${entity.text}</a>`
* }
* }
* ```
*/
function isLinkTextEntity(entity) {
return isEntityTypeIn(entity.type, exports.LINK_TEXT_ENTITY_TYPES);
}
/**
* Type guard to check if a text entity mentions a user.
*
* Contains full user information through the mention property.
*
* @param entity - The text entity to check
* @returns True if the entity mentions a user
*
* @example
* ```typescript
* if (isMentionTextEntity(entity)) {
* const user = entity.mention
* console.log(`Mentioned user: ${user.displayName} (@${user.username})`)
*
* // Render as user profile link
* const userUrl = user.username ? `https://t.me/${user.username}` : '#'
* return `<a href="${userUrl}" class="user-mention">${entity.text}</a>`
* }
* ```
*/
function isMentionTextEntity(entity) {
return isEntityTypeIn(entity.type, exports.MENTION_TEXT_ENTITY_TYPES);
}
/**
* Type guard to check if a text entity is a custom emoji.
*
* Custom emojis have associated image files for enhanced display.
*
* @param entity - The text entity to check
* @returns True if the entity is a custom emoji
*
* @example
* ```typescript
* if (isCustomEmojiTextEntity(entity)) {
* if (entity.documentURL) {
* // Display custom emoji image
* console.log(`<img src="${entity.documentURL}" alt="${entity.text}" class="custom-emoji">`)
* } else {
* // Fallback to text representation
* console.log(entity.text)
* }
* }
* ```
*/
function isCustomEmojiTextEntity(entity) {
return entity.type === exports.TEXT_ENTITY_TYPES.CUSTOM_EMOJI;
}
/**
* Type guard to check if a text entity is a block quote.
*
* Block quotes should be rendered with special styling and may be collapsible.
*
* @param entity - The text entity to check
* @returns True if the entity is a block quote
*
* @example
* ```typescript
* if (isQuoteTextEntity(entity)) {
* const collapseClass = entity.collapsed ? 'collapsed' : 'expanded'
* console.log(`<blockquote class="${collapseClass}">${entity.text}</blockquote>`)
* }
* ```
*/
function isQuoteTextEntity(entity) {
return entity.type === exports.TEXT_ENTITY_TYPES.BLOCKQUOTE;
}
//# sourceMappingURL=text-entities.js.map