UNPKG

eslint-doc-generator

Version:

Automatic documentation generator for ESLint plugins and rules.

91 lines (90 loc) 2.82 kB
import * as nodeEmoji from 'node-emoji'; import { EMOJI_CONFIGS, RESERVED_EMOJI_SET } from './emojis.js'; const FALLBACK_EMOJIS = [ '🔴', '🟠', '🟡', '🟢', '🔵', '🟣', '🟤', '⚫', '⚪', '🟥', '🟧', '🟨', '🟩', '🟦', '🟪', '🟫', '⬛', '⬜', ]; function tokenizeConfigName(configName) { const normalized = configName .replaceAll(/([a-z])([A-Z])/gu, '$1 $2') .replaceAll(/[^a-zA-Z0-9]+/gu, ' ') .toLowerCase() .trim(); if (!normalized) { return []; } return normalized.split(/\s+/u); } function canUseEmoji(candidate, usedEmojis) { return !RESERVED_EMOJI_SET.has(candidate) && !usedEmojis.has(candidate); } function tryUseEmoji(candidate, usedEmojis) { return candidate && canUseEmoji(candidate, usedEmojis) ? candidate : undefined; } function getDefaultEmojiForConfig(configNameLower) { if (!(configNameLower in EMOJI_CONFIGS)) { return undefined; } return EMOJI_CONFIGS[configNameLower]; } function suggestEmojiLocally(configName, usedEmojis) { const configNameLower = configName.toLowerCase(); const tokens = tokenizeConfigName(configName); const exactDefault = tryUseEmoji(getDefaultEmojiForConfig(configNameLower), usedEmojis); if (exactDefault) { return exactDefault; } for (const token of tokens) { const tokenKeywordEmoji = tryUseEmoji(getDefaultEmojiForConfig(token), usedEmojis); if (tokenKeywordEmoji) { return tokenKeywordEmoji; } } for (const term of [configNameLower, ...tokens]) { const matches = nodeEmoji.search(term); for (const match of matches) { const fromSearch = tryUseEmoji(match.emoji, usedEmojis); if (fromSearch) { return fromSearch; } } } const fallback = FALLBACK_EMOJIS.find((emoji) => canUseEmoji(emoji, usedEmojis)) ?? FALLBACK_EMOJIS[0]; return fallback; } function sortCaseInsensitive(values) { return values.toSorted((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())); } export function getBuiltinEmojiSuggestions(context) { const configNames = sortCaseInsensitive(Object.keys(context.plugin.configs ?? {})); if (configNames.length === 0) { throw new Error('Could not find exported `configs` object in ESLint plugin to suggest emojis for.'); } const emojiByConfig = new Map(); const usedEmojis = new Set(); for (const configName of configNames) { const localSuggestion = suggestEmojiLocally(configName, usedEmojis); emojiByConfig.set(configName, localSuggestion); usedEmojis.add(localSuggestion); } return { configNames, emojiByConfig }; }