UNPKG

node-emojis

Version:

Modern, tree-shakeable emoji library for Node.js with TypeScript, search, skin tones, and aliases 🎉

184 lines 6.13 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SKIN_TONE_CAPABLE_EMOJIS = exports.SKIN_TONE_MODIFIERS = void 0; exports.applySkinTone = applySkinTone; exports.supportsSkinTone = supportsSkinTone; exports.getAllSkinToneVariations = getAllSkinToneVariations; exports.removeSkinTone = removeSkinTone; const skin_tones_json_1 = __importDefault(require("../../data/skin-tones.json")); const emojis_json_1 = __importDefault(require("../../data/emojis.json")); const aliases_json_1 = __importDefault(require("../../data/aliases.json")); const SKIN_TONE_ALIASES = { '1': 'light', '2': 'medium-light', '3': 'medium', '4': 'medium-dark', '5': 'dark' }; /** * Apply a skin tone modifier to an emoji * * This function removes any existing skin tone modifiers before applying the new one. * Supports both named tones ('light', 'medium-dark') and numeric aliases ('1', '4'). * * @param emoji - The emoji character to modify (e.g., '👋' or '👋🏻') * @param tone - The skin tone to apply (name or numeric alias) * @returns The emoji with the specified skin tone modifier applied * @throws {Error} If the tone parameter is invalid * * @example * ```typescript * // Apply skin tone by name * applySkinTone('👋', 'dark') * // Returns: '👋🏿' * * // Apply skin tone by numeric alias * applySkinTone('👋', '3') * // Returns: '👋🏽' (medium) * * // Replace existing skin tone * applySkinTone('👋🏻', 'dark') * // Returns: '👋🏿' * ``` */ function applySkinTone(emoji, tone) { const modifier = typeof tone === 'string' && tone in SKIN_TONE_ALIASES ? skin_tones_json_1.default.modifiers[SKIN_TONE_ALIASES[tone]] : skin_tones_json_1.default.modifiers[tone]; if (!modifier) { throw new Error(`Invalid skin tone: ${tone}`); } // Remove any existing skin tone modifiers and variation selectors const baseEmoji = removeSkinTone(emoji); return baseEmoji + modifier; } /** * Check if an emoji supports skin tone variations * * Works with both emoji names and emoji characters. Also checks aliases. * * @param nameOrEmoji - Either an emoji name (e.g., 'wave') or emoji character (e.g., '👋') * @returns true if the emoji supports skin tone modifiers, false otherwise * * @example * ```typescript * // Check by name * supportsSkinTone('wave') * // Returns: true * * // Check by emoji character * supportsSkinTone('👋') * // Returns: true * * // Check by alias * supportsSkinTone('hand_wave') * // Returns: true * * // Non-human emojis don't support skin tones * supportsSkinTone('fire') * // Returns: false * ``` */ function supportsSkinTone(nameOrEmoji) { // Check if it's an emoji character or a name const emojiName = emojis_json_1.default[nameOrEmoji] ? nameOrEmoji : getNameFromEmoji(nameOrEmoji); if (!emojiName) return false; // Check if it's in the capable list if (skin_tones_json_1.default.capable.includes(emojiName)) return true; // Check aliases const primaryName = getPrimaryName(emojiName); return skin_tones_json_1.default.capable.includes(primaryName); } /** * Get all skin tone variations of an emoji * * Returns an object with all possible skin tone variations including the default (no modifier). * * @param emoji - The emoji character to get variations for * @returns Object mapping tone names to emoji variations * * @example * ```typescript * getAllSkinToneVariations('👋') * // Returns: { * // default: '👋', * // light: '👋🏻', * // 'medium-light': '👋🏼', * // medium: '👋🏽', * // 'medium-dark': '👋🏾', * // dark: '👋🏿' * // } * * // Works with emojis that already have skin tone * getAllSkinToneVariations('👋🏻') * // Returns same as above (strips existing tone first) * ``` */ function getAllSkinToneVariations(emoji) { const baseEmoji = removeSkinTone(emoji); return { default: baseEmoji, light: applySkinTone(baseEmoji, 'light'), 'medium-light': applySkinTone(baseEmoji, 'medium-light'), medium: applySkinTone(baseEmoji, 'medium'), 'medium-dark': applySkinTone(baseEmoji, 'medium-dark'), dark: applySkinTone(baseEmoji, 'dark') }; } /** * Remove skin tone modifier from an emoji * * Strips all skin tone modifiers and variation selectors to return the base emoji. * Safe to use on emojis without skin tones. * * @param emoji - The emoji character to remove skin tone from * @returns The base emoji without any skin tone modifiers * * @example * ```typescript * // Remove skin tone * removeSkinTone('👋🏿') * // Returns: '👋' * * // Multiple skin tones (family emojis) * removeSkinTone('👨🏻‍👩🏾‍👧🏽') * // Returns: '👨‍👩‍👧' * * // No skin tone - returns unchanged * removeSkinTone('🔥') * // Returns: '🔥' * ``` */ function removeSkinTone(emoji) { // Remove all skin tone modifiers let result = emoji; Object.values(skin_tones_json_1.default.modifiers).forEach(modifier => { result = result.replace(new RegExp(modifier, 'g'), ''); }); // Also remove variation selectors result = result.replace(/[\u{FE0F}\u{200D}]/gu, ''); return result; } // Helper functions function getNameFromEmoji(emoji) { const entry = Object.entries(emojis_json_1.default).find(([_, e]) => e === emoji); return entry ? entry[0] : null; } function getPrimaryName(name) { // Check if this name is already primary if (aliases_json_1.default[name]) { return name; } // Find if this is an alias const entry = Object.entries(aliases_json_1.default).find(([_, aliasList]) => aliasList.includes(name)); return entry ? entry[0] : name; } // Export constants exports.SKIN_TONE_MODIFIERS = skin_tones_json_1.default.modifiers; exports.SKIN_TONE_CAPABLE_EMOJIS = skin_tones_json_1.default.capable; //# sourceMappingURL=index.js.map