eslint-doc-generator
Advanced tools
Comparing version 0.18.2 to 0.19.0
@@ -1,7 +0,8 @@ | ||
import type { Plugin, ConfigsToRules, ConfigEmojis, RuleSeverity, SEVERITY_TYPE } from './types.js'; | ||
import type { Plugin, ConfigsToRules, ConfigEmojis, SEVERITY_TYPE } from './types.js'; | ||
export declare function getConfigsThatSetARule(plugin: Plugin, configsToRules: ConfigsToRules, pluginPrefix: string, ignoreConfig: string[], severityType?: SEVERITY_TYPE): string[]; | ||
/** | ||
* Get config names that a given rule belongs to. | ||
* @param severity - Include configs that set the rule to this severity. Omit to allow any severity. | ||
* @param severityType - Include configs that set the rule to this severity. Omit to allow any severity. | ||
*/ | ||
export declare function getConfigsForRule(ruleName: string, configsToRules: ConfigsToRules, pluginPrefix: string, severity?: Set<RuleSeverity>): string[]; | ||
export declare function getConfigsForRule(ruleName: string, configsToRules: ConfigsToRules, pluginPrefix: string, severityType?: SEVERITY_TYPE): string[]; | ||
/** | ||
@@ -16,9 +17,7 @@ * Parse the options, check for errors, and set defaults. | ||
* @param options | ||
* @param options.severity - if present, decorate the config's emoji for the given severity level | ||
* @param options.fallback - if true and no emoji is found, choose whether to fallback to a generic config emoji or a badge | ||
* @param options.fallback - if true and no emoji is found, choose whether to fallback to a badge. | ||
* @returns the string to display for the config | ||
*/ | ||
export declare function findConfigEmoji(configEmojis: ConfigEmojis, configName: string, options?: { | ||
severity?: SEVERITY_TYPE; | ||
fallback?: 'badge' | 'emoji'; | ||
fallback?: 'badge'; | ||
}): string | undefined; |
@@ -1,7 +0,26 @@ | ||
import { EMOJI_CONFIGS, EMOJI_CONFIG, EMOJI_CONFIG_WARN, EMOJI_CONFIG_OFF, } from './emojis.js'; | ||
import { EMOJI_CONFIGS, EMOJI_CONFIG_ERROR, RESERVED_EMOJIS, } from './emojis.js'; | ||
import { SEVERITY_TYPE_TO_SET } from './types.js'; | ||
export function getConfigsThatSetARule(plugin, configsToRules, pluginPrefix, ignoreConfig, severityType) { | ||
/* istanbul ignore next -- this shouldn't happen */ | ||
if (!plugin.rules) { | ||
throw new Error('Missing rules in plugin.'); | ||
} | ||
const ruleNames = Object.keys(plugin.rules); | ||
return (Object.entries(configsToRules) | ||
.filter(([configName]) => | ||
// Only consider configs that configure at least one of the plugin's rules. | ||
ruleNames.some((ruleName) => getConfigsForRule(ruleName, configsToRules, pluginPrefix, severityType).includes(configName))) | ||
// Filter out ignored configs. | ||
.filter(([configName]) => !ignoreConfig?.includes(configName)) | ||
.map(([configName]) => configName) | ||
.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()))); | ||
} | ||
/** | ||
* Get config names that a given rule belongs to. | ||
* @param severity - Include configs that set the rule to this severity. Omit to allow any severity. | ||
* @param severityType - Include configs that set the rule to this severity. Omit to allow any severity. | ||
*/ | ||
export function getConfigsForRule(ruleName, configsToRules, pluginPrefix, severity) { | ||
export function getConfigsForRule(ruleName, configsToRules, pluginPrefix, severityType) { | ||
const severity = severityType | ||
? SEVERITY_TYPE_TO_SET[severityType] | ||
: undefined; | ||
const configNames = []; | ||
@@ -41,4 +60,4 @@ for (const configName in configsToRules) { | ||
} | ||
if (Object.keys(plugin.configs)?.length > 1 && emoji === EMOJI_CONFIG) { | ||
throw new Error(`Cannot use the general configs emoji ${EMOJI_CONFIG} for an individual config when multiple configs are present.`); | ||
if (RESERVED_EMOJIS.includes(emoji)) { | ||
throw new Error(`Cannot specify reserved emoji ${EMOJI_CONFIG_ERROR}.`); | ||
} | ||
@@ -59,9 +78,2 @@ return [{ config, emoji }]; | ||
} | ||
function emojiWithSuperscript(emoji, superscriptEmoji) { | ||
if (emoji === superscriptEmoji) { | ||
// Avoid double emoji. | ||
return emoji; | ||
} | ||
return `${emoji}<sup>${superscriptEmoji}</sup>`; | ||
} | ||
/** | ||
@@ -72,4 +84,3 @@ * Find the representation of a config to display. | ||
* @param options | ||
* @param options.severity - if present, decorate the config's emoji for the given severity level | ||
* @param options.fallback - if true and no emoji is found, choose whether to fallback to a generic config emoji or a badge | ||
* @param options.fallback - if true and no emoji is found, choose whether to fallback to a badge. | ||
* @returns the string to display for the config | ||
@@ -83,5 +94,2 @@ */ | ||
} | ||
else if (options?.fallback === 'emoji') { | ||
emoji = EMOJI_CONFIG; | ||
} | ||
else { | ||
@@ -92,10 +100,3 @@ // No fallback. | ||
} | ||
switch (options?.severity) { | ||
case 'warn': | ||
return emojiWithSuperscript(emoji, EMOJI_CONFIG_WARN); | ||
case 'off': | ||
return emojiWithSuperscript(emoji, EMOJI_CONFIG_OFF); | ||
default: | ||
return emoji; | ||
} | ||
return emoji; | ||
} |
@@ -0,1 +1,2 @@ | ||
import { SEVERITY_TYPE } from './types.js'; | ||
export declare const EMOJI_CONFIGS: { | ||
@@ -19,5 +20,8 @@ a11y: string; | ||
}; | ||
export declare const EMOJI_CONFIG = "\uD83D\uDCBC"; | ||
export declare const EMOJI_CONFIG_ERROR = "\uD83D\uDCBC"; | ||
export declare const EMOJI_CONFIG_WARN = "\u26A0\uFE0F"; | ||
export declare const EMOJI_CONFIG_OFF = "\uD83D\uDEAB"; | ||
export declare const EMOJI_CONFIG_FROM_SEVERITY: { | ||
[key in SEVERITY_TYPE]: string; | ||
}; | ||
export declare const EMOJI_FIXABLE = "\uD83D\uDD27"; | ||
@@ -28,1 +32,2 @@ export declare const EMOJI_HAS_SUGGESTIONS = "\uD83D\uDCA1"; | ||
export declare const EMOJI_DEPRECATED = "\u274C"; | ||
export declare const RESERVED_EMOJIS: string[]; |
@@ -0,1 +1,3 @@ | ||
import { SEVERITY_TYPE } from './types.js'; | ||
import { EMOJIS_TYPE } from './rule-type.js'; | ||
// Default emojis for common configs. | ||
@@ -6,3 +8,3 @@ const EMOJI_A11Y = '♿'; | ||
const EMOJI_TYPESCRIPT = '⌨️'; | ||
const EMOJI_WARNING = '⚠️'; | ||
const EMOJI_WARNING = '🚸'; | ||
export const EMOJI_CONFIGS = { | ||
@@ -27,5 +29,10 @@ a11y: EMOJI_A11Y, | ||
// General configs. | ||
export const EMOJI_CONFIG = '💼'; | ||
export const EMOJI_CONFIG_ERROR = '💼'; | ||
export const EMOJI_CONFIG_WARN = '⚠️'; | ||
export const EMOJI_CONFIG_OFF = '🚫'; | ||
export const EMOJI_CONFIG_FROM_SEVERITY = { | ||
[SEVERITY_TYPE.error]: EMOJI_CONFIG_ERROR, | ||
[SEVERITY_TYPE.warn]: EMOJI_CONFIG_WARN, | ||
[SEVERITY_TYPE.off]: EMOJI_CONFIG_OFF, | ||
}; | ||
// Fixers. | ||
@@ -41,1 +48,10 @@ export const EMOJI_FIXABLE = '🔧'; | ||
export const EMOJI_DEPRECATED = '❌'; | ||
export const RESERVED_EMOJIS = [ | ||
...Object.values(EMOJI_CONFIG_FROM_SEVERITY), | ||
...Object.values(EMOJIS_TYPE), | ||
EMOJI_FIXABLE, | ||
EMOJI_HAS_SUGGESTIONS, | ||
EMOJI_REQUIRES_TYPE_CHECKING, | ||
EMOJI_TYPE, | ||
EMOJI_DEPRECATED, | ||
]; |
@@ -1,2 +0,5 @@ | ||
import { COLUMN_TYPE, ConfigEmojis, Plugin, ConfigsToRules } from './types.js'; | ||
import { COLUMN_TYPE, ConfigEmojis, Plugin, ConfigsToRules, SEVERITY_TYPE } from './types.js'; | ||
export declare const SEVERITY_TYPE_TO_WORD: { | ||
[key in SEVERITY_TYPE]: string; | ||
}; | ||
export declare function generateLegend(columns: Record<COLUMN_TYPE, boolean>, plugin: Plugin, configsToRules: ConfigsToRules, configEmojis: ConfigEmojis, pluginPrefix: string, ignoreConfig: string[], urlConfigs?: string): string; |
@@ -1,5 +0,10 @@ | ||
import { EMOJI_DEPRECATED, EMOJI_FIXABLE, EMOJI_HAS_SUGGESTIONS, EMOJI_CONFIG, EMOJI_REQUIRES_TYPE_CHECKING, EMOJI_TYPE, } from './emojis.js'; | ||
import { getConfigsForRule, findConfigEmoji } from './configs.js'; | ||
import { COLUMN_TYPE, SEVERITY_ERROR, SEVERITY_WARN, SEVERITY_OFF, SEVERITY_TYPE, } from './types.js'; | ||
import { EMOJI_DEPRECATED, EMOJI_FIXABLE, EMOJI_HAS_SUGGESTIONS, EMOJI_REQUIRES_TYPE_CHECKING, EMOJI_TYPE, EMOJI_CONFIG_FROM_SEVERITY, } from './emojis.js'; | ||
import { findConfigEmoji, getConfigsThatSetARule } from './configs.js'; | ||
import { COLUMN_TYPE, SEVERITY_TYPE, } from './types.js'; | ||
import { RULE_TYPE_MESSAGES_LEGEND, RULE_TYPES } from './rule-type.js'; | ||
export const SEVERITY_TYPE_TO_WORD = { | ||
[SEVERITY_TYPE.error]: 'enabled', | ||
[SEVERITY_TYPE.warn]: 'set to warn', | ||
[SEVERITY_TYPE.off]: 'disabled', | ||
}; | ||
/** | ||
@@ -9,72 +14,35 @@ * An object containing the legends for each column (as a string or function to generate the string). | ||
const LEGENDS = { | ||
// Legends are included for each config. A generic config legend is also included if there are multiple configs. | ||
[COLUMN_TYPE.CONFIGS]: ({ plugin, configsToRules, configEmojis, pluginPrefix, urlConfigs, ignoreConfig, }) => { | ||
/* istanbul ignore next -- this shouldn't happen */ | ||
if (!plugin.configs || !plugin.rules) { | ||
throw new Error('Should not be attempting to display configs column when there are no configs/rules.'); | ||
} | ||
// Add link to configs documentation if provided. | ||
const configsLinkOrWord = urlConfigs | ||
? `[Configurations](${urlConfigs})` | ||
: 'Configurations'; | ||
const configLinkOrWord = urlConfigs | ||
? `[configuration](${urlConfigs})` | ||
: 'configuration'; | ||
const ruleNames = Object.keys(plugin.rules); | ||
const configNamesWithoutIgnored = Object.entries(configsToRules) | ||
.filter(([configName, _config]) => | ||
// Only consider configs that configure at least one of the plugin's rules. | ||
ruleNames.some((ruleName) => getConfigsForRule(ruleName, configsToRules, pluginPrefix).includes(configName))) | ||
// Filter out ignored configs. | ||
.filter(([configName]) => !ignoreConfig?.includes(configName)) | ||
.map(([configName]) => configName); | ||
const legends = []; | ||
if ((configNamesWithoutIgnored.length > 1 || | ||
!configEmojis.find((configEmoji) => configNamesWithoutIgnored.includes(configEmoji.config))?.emoji) && | ||
// If any configs are using the generic config emoji, then don't display the generic config legend. | ||
!configEmojis | ||
.filter(({ config }) => !ignoreConfig?.includes(config)) | ||
.some((configEmoji) => configEmoji.emoji === EMOJI_CONFIG)) { | ||
// Generic config emoji will be used if the plugin has multiple configs or the sole config has no emoji. | ||
legends.push(`${EMOJI_CONFIG} ${configsLinkOrWord} enabled in.`); | ||
} | ||
legends.push(...configNamesWithoutIgnored.flatMap((configName) => { | ||
if (!findConfigEmoji(configEmojis, configName)) { | ||
// No legend for this config as it has no emoji. | ||
return []; | ||
} | ||
let hasErrorRule = false; | ||
let hasWarnRule = false; | ||
let hasOffRule = false; | ||
for (const ruleName of ruleNames) { | ||
if (getConfigsForRule(ruleName, configsToRules, pluginPrefix, SEVERITY_ERROR).includes(configName)) { | ||
hasErrorRule = true; | ||
} | ||
if (getConfigsForRule(ruleName, configsToRules, pluginPrefix, SEVERITY_WARN).includes(configName)) { | ||
hasWarnRule = true; | ||
} | ||
if (getConfigsForRule(ruleName, configsToRules, pluginPrefix, SEVERITY_OFF).includes(configName)) { | ||
hasOffRule = true; | ||
} | ||
} | ||
const legendsForThisConfig = []; | ||
if (hasErrorRule) { | ||
legendsForThisConfig.push(`${findConfigEmoji(configEmojis, configName, { | ||
severity: SEVERITY_TYPE.error, | ||
})} Enabled in the \`${configName}\` ${configLinkOrWord}.`); | ||
} | ||
if (hasWarnRule) { | ||
legendsForThisConfig.push(`${findConfigEmoji(configEmojis, configName, { | ||
severity: SEVERITY_TYPE.warn, | ||
})} Warns in the \`${configName}\` ${configLinkOrWord}.`); | ||
} | ||
if (hasOffRule) { | ||
legendsForThisConfig.push(`${findConfigEmoji(configEmojis, configName, { | ||
severity: SEVERITY_TYPE.off, | ||
})} Disabled in the \`${configName}\` ${configLinkOrWord}.`); | ||
} | ||
return legendsForThisConfig; | ||
})); | ||
return legends; | ||
}, | ||
[COLUMN_TYPE.CONFIGS_ERROR]: ({ plugin, configsToRules, configEmojis, pluginPrefix, urlConfigs, ignoreConfig, }) => [ | ||
getLegendForConfigColumnOfSeverity({ | ||
plugin, | ||
configsToRules, | ||
configEmojis, | ||
pluginPrefix, | ||
urlConfigs, | ||
severityType: SEVERITY_TYPE.error, | ||
ignoreConfig, | ||
}), | ||
], | ||
[COLUMN_TYPE.CONFIGS_OFF]: ({ plugin, configsToRules, configEmojis, pluginPrefix, urlConfigs, ignoreConfig, }) => [ | ||
getLegendForConfigColumnOfSeverity({ | ||
plugin, | ||
configsToRules, | ||
configEmojis, | ||
pluginPrefix, | ||
urlConfigs, | ||
severityType: SEVERITY_TYPE.off, | ||
ignoreConfig, | ||
}), | ||
], | ||
[COLUMN_TYPE.CONFIGS_WARN]: ({ plugin, configsToRules, configEmojis, pluginPrefix, urlConfigs, ignoreConfig, }) => [ | ||
getLegendForConfigColumnOfSeverity({ | ||
plugin, | ||
configsToRules, | ||
configEmojis, | ||
pluginPrefix, | ||
urlConfigs, | ||
severityType: SEVERITY_TYPE.warn, | ||
ignoreConfig, | ||
}), | ||
], | ||
// Legends are included for each rule type present. | ||
@@ -110,5 +78,34 @@ [COLUMN_TYPE.TYPE]: ({ plugin }) => { | ||
}; | ||
function getLegendForConfigColumnOfSeverity({ plugin, urlConfigs, severityType, }) { | ||
/* istanbul ignore next -- this shouldn't happen */ | ||
if (!plugin.configs || !plugin.rules) { | ||
throw new Error('Should not be attempting to display configs column when there are no configs/rules.'); | ||
} | ||
// Add link to configs documentation if provided. | ||
const configsLinkOrWord = urlConfigs | ||
? `[Configurations](${urlConfigs})` | ||
: 'Configurations'; | ||
return `${EMOJI_CONFIG_FROM_SEVERITY[severityType]} ${configsLinkOrWord} ${SEVERITY_TYPE_TO_WORD[severityType]} in.`; | ||
} | ||
function getLegendsForIndividualConfigs({ plugin, configsToRules, configEmojis, pluginPrefix, urlConfigs, ignoreConfig, }) { | ||
/* istanbul ignore next -- this shouldn't happen */ | ||
if (!plugin.configs || !plugin.rules) { | ||
throw new Error('Should not be attempting to display configs column when there are no configs/rules.'); | ||
} | ||
// Add link to configs documentation if provided. | ||
const configLinkOrWord = urlConfigs | ||
? `[configuration](${urlConfigs})` | ||
: 'configuration'; | ||
const configNamesThatSetRuleToThisSeverity = getConfigsThatSetARule(plugin, configsToRules, pluginPrefix, ignoreConfig); | ||
return configNamesThatSetRuleToThisSeverity.flatMap((configName) => { | ||
const emoji = findConfigEmoji(configEmojis, configName); | ||
if (!emoji) { | ||
// No legend for this config as it has no emoji. | ||
return []; | ||
} | ||
return [`${emoji} Set in the \`${configName}\` ${configLinkOrWord}.`]; | ||
}); | ||
} | ||
export function generateLegend(columns, plugin, configsToRules, configEmojis, pluginPrefix, ignoreConfig, urlConfigs) { | ||
return Object.entries(columns) | ||
.flatMap(([columnType, enabled]) => { | ||
const legends = Object.entries(columns).flatMap(([columnType, enabled]) => { | ||
if (!enabled) { | ||
@@ -133,4 +130,17 @@ // This column is turned off. | ||
: [legendStrOrFn]; | ||
}) | ||
.join('\\\n'); // Back slash ensures these end up displayed on separate lines. | ||
}); | ||
if (legends.some((legend) => legend.includes('Configurations'))) { | ||
// Add legends for individual configs after the config column legend(s). | ||
const legendsForIndividualConfigs = getLegendsForIndividualConfigs({ | ||
plugin, | ||
configsToRules, | ||
configEmojis, | ||
pluginPrefix, | ||
urlConfigs, | ||
ignoreConfig, | ||
}); | ||
const finalConfigHeaderLegendPosition = Math.max(...Object.values(SEVERITY_TYPE_TO_WORD).map((word) => legends.findIndex((legend) => legend.includes(word)))); | ||
legends.splice(finalConfigHeaderLegendPosition + 1, 0, ...legendsForIndividualConfigs); | ||
} | ||
return legends.join('\\\n'); // Back slash ensures these end up displayed on separate lines. | ||
} |
import { COLUMN_TYPE } from './types.js'; | ||
import type { RuleDetails, ConfigsToRules, ConfigEmojis } from './types.js'; | ||
import type { RuleDetails, ConfigsToRules, Plugin } from './types.js'; | ||
export declare const COLUMN_TYPE_DEFAULT_PRESENCE_AND_ORDERING: { | ||
@@ -11,5 +11,2 @@ [key in COLUMN_TYPE]: boolean; | ||
[key in COLUMN_TYPE]: string | ((data: { | ||
configNames: string[]; | ||
configEmojis: ConfigEmojis; | ||
ignoreConfig: string[]; | ||
details: RuleDetails[]; | ||
@@ -22,2 +19,2 @@ }) => string); | ||
*/ | ||
export declare function getColumns(details: RuleDetails[], configsToRules: ConfigsToRules, ruleListColumns: COLUMN_TYPE[], ignoreConfig: string[]): Record<COLUMN_TYPE, boolean>; | ||
export declare function getColumns(plugin: Plugin, details: RuleDetails[], configsToRules: ConfigsToRules, ruleListColumns: COLUMN_TYPE[], pluginPrefix: string, ignoreConfig: string[]): Record<COLUMN_TYPE, boolean>; |
@@ -1,4 +0,5 @@ | ||
import { EMOJI_CONFIG, EMOJI_DEPRECATED, EMOJI_FIXABLE, EMOJI_HAS_SUGGESTIONS, EMOJI_REQUIRES_TYPE_CHECKING, EMOJI_TYPE, } from './emojis.js'; | ||
import { EMOJI_DEPRECATED, EMOJI_FIXABLE, EMOJI_HAS_SUGGESTIONS, EMOJI_REQUIRES_TYPE_CHECKING, EMOJI_TYPE, EMOJI_CONFIG_FROM_SEVERITY, } from './emojis.js'; | ||
import { RULE_TYPES } from './rule-type.js'; | ||
import { COLUMN_TYPE } from './types.js'; | ||
import { COLUMN_TYPE, SEVERITY_TYPE } from './types.js'; | ||
import { getConfigsThatSetARule } from './configs.js'; | ||
export const COLUMN_TYPE_DEFAULT_PRESENCE_AND_ORDERING = { | ||
@@ -9,3 +10,5 @@ // Object keys ordered in display order. | ||
[COLUMN_TYPE.DESCRIPTION]: true, | ||
[COLUMN_TYPE.CONFIGS]: true, | ||
[COLUMN_TYPE.CONFIGS_ERROR]: true, | ||
[COLUMN_TYPE.CONFIGS_WARN]: true, | ||
[COLUMN_TYPE.CONFIGS_OFF]: true, | ||
[COLUMN_TYPE.FIXABLE]: true, | ||
@@ -21,9 +24,2 @@ [COLUMN_TYPE.HAS_SUGGESTIONS]: true, | ||
export const COLUMN_HEADER = { | ||
// Use the general config emoji if there are multiple configs or the sole config doesn't have an emoji. | ||
[COLUMN_TYPE.CONFIGS]: ({ configNames, configEmojis, ignoreConfig }) => { | ||
const configNamesWithoutIgnored = configNames.filter((configName) => !ignoreConfig?.includes(configName)); | ||
return configNamesWithoutIgnored.length > 1 | ||
? EMOJI_CONFIG | ||
: configEmojis.find((configEmoji) => configNamesWithoutIgnored.includes(configEmoji.config))?.emoji ?? EMOJI_CONFIG; | ||
}, | ||
[COLUMN_TYPE.NAME]: ({ details }) => { | ||
@@ -45,2 +41,5 @@ const ruleNames = details.map((detail) => detail.name); | ||
// Simple strings. | ||
[COLUMN_TYPE.CONFIGS_ERROR]: EMOJI_CONFIG_FROM_SEVERITY[SEVERITY_TYPE.error], | ||
[COLUMN_TYPE.CONFIGS_OFF]: EMOJI_CONFIG_FROM_SEVERITY[SEVERITY_TYPE.off], | ||
[COLUMN_TYPE.CONFIGS_WARN]: EMOJI_CONFIG_FROM_SEVERITY[SEVERITY_TYPE.warn], | ||
[COLUMN_TYPE.DEPRECATED]: EMOJI_DEPRECATED, | ||
@@ -57,7 +56,8 @@ [COLUMN_TYPE.DESCRIPTION]: 'Description', | ||
*/ | ||
export function getColumns(details, configsToRules, ruleListColumns, ignoreConfig) { | ||
export function getColumns(plugin, details, configsToRules, ruleListColumns, pluginPrefix, ignoreConfig) { | ||
const columns = { | ||
// Alphabetical order. | ||
// Show the configs column if there exists a non-ignored config. | ||
[COLUMN_TYPE.CONFIGS]: Object.keys(configsToRules).some((config) => !ignoreConfig?.includes(config)), | ||
[COLUMN_TYPE.CONFIGS_ERROR]: getConfigsThatSetARule(plugin, configsToRules, pluginPrefix, ignoreConfig, SEVERITY_TYPE.error).length > 0, | ||
[COLUMN_TYPE.CONFIGS_OFF]: getConfigsThatSetARule(plugin, configsToRules, pluginPrefix, ignoreConfig, SEVERITY_TYPE.off).length > 0, | ||
[COLUMN_TYPE.CONFIGS_WARN]: getConfigsThatSetARule(plugin, configsToRules, pluginPrefix, ignoreConfig, SEVERITY_TYPE.warn).length > 0, | ||
[COLUMN_TYPE.DEPRECATED]: details.some((detail) => detail.deprecated), | ||
@@ -64,0 +64,0 @@ [COLUMN_TYPE.DESCRIPTION]: details.some((detail) => detail.description), |
@@ -9,3 +9,3 @@ import { BEGIN_RULE_LIST_MARKER, END_RULE_LIST_MARKER } from './markers.js'; | ||
import { relative } from 'node:path'; | ||
import { COLUMN_TYPE, SEVERITY_TYPE, SEVERITY_TYPE_TO_SET } from './types.js'; | ||
import { COLUMN_TYPE, SEVERITY_TYPE } from './types.js'; | ||
import { markdownTable } from 'markdown-table'; | ||
@@ -44,4 +44,3 @@ import camelCase from 'camelcase'; | ||
function getEmojisForConfigsSettingRuleToSeverity(ruleName, configsToRulesWithoutIgnored, pluginPrefix, configEmojis, severityType) { | ||
const severity = SEVERITY_TYPE_TO_SET[severityType]; | ||
const configsOfThisSeverity = getConfigsForRule(ruleName, configsToRulesWithoutIgnored, pluginPrefix, severity); | ||
const configsOfThisSeverity = getConfigsForRule(ruleName, configsToRulesWithoutIgnored, pluginPrefix, severityType); | ||
const emojis = []; | ||
@@ -51,3 +50,2 @@ for (const configName of configsOfThisSeverity) { | ||
const emoji = findConfigEmoji(configEmojis, configName, { | ||
severity: severityType, | ||
fallback: 'badge', | ||
@@ -59,16 +57,10 @@ }); | ||
} | ||
// For emojis with a superscript, add a newline first to ensure we don't end up with a linebreak between the emoji and the superscript. | ||
emojis.push(emoji.includes('<sup>') ? `<br>${emoji}` : emoji); | ||
emojis.push(emoji); | ||
} | ||
return emojis; | ||
} | ||
function getConfigurationColumnValueForRule(rule, configsToRules, pluginPrefix, configEmojis, ignoreConfig) { | ||
const emojis = []; | ||
function getConfigurationColumnValueForRule(rule, configsToRules, pluginPrefix, configEmojis, ignoreConfig, severityType) { | ||
const configsToRulesWithoutIgnored = Object.fromEntries(Object.entries(configsToRules).filter(([configName]) => !ignoreConfig?.includes(configName))); | ||
// Collect the emojis for the configs that set the rule to each severity level. | ||
emojis.push(...getEmojisForConfigsSettingRuleToSeverity(rule.name, configsToRulesWithoutIgnored, pluginPrefix, configEmojis, SEVERITY_TYPE.error), ...getEmojisForConfigsSettingRuleToSeverity(rule.name, configsToRulesWithoutIgnored, pluginPrefix, configEmojis, SEVERITY_TYPE.warn), ...getEmojisForConfigsSettingRuleToSeverity(rule.name, configsToRulesWithoutIgnored, pluginPrefix, configEmojis, SEVERITY_TYPE.off)); | ||
if (emojis.length > 0 && emojis[0].startsWith('<br>')) { | ||
emojis[0] = emojis[0].slice(4); // Avoid any leading linebreak. Linebreak only necessary after emojis and before emojis with superscripts. | ||
} | ||
return emojis.join(' '); | ||
// Collect the emojis for the configs that set the rule to this severity level. | ||
return getEmojisForConfigsSettingRuleToSeverity(rule.name, configsToRulesWithoutIgnored, pluginPrefix, configEmojis, severityType).join(' '); | ||
} | ||
@@ -78,3 +70,5 @@ function buildRuleRow(columnsEnabled, rule, configsToRules, pluginPrefix, configEmojis, ignoreConfig) { | ||
// Alphabetical order. | ||
[COLUMN_TYPE.CONFIGS]: getConfigurationColumnValueForRule(rule, configsToRules, pluginPrefix, configEmojis, ignoreConfig), | ||
[COLUMN_TYPE.CONFIGS_ERROR]: getConfigurationColumnValueForRule(rule, configsToRules, pluginPrefix, configEmojis, ignoreConfig, SEVERITY_TYPE.error), | ||
[COLUMN_TYPE.CONFIGS_OFF]: getConfigurationColumnValueForRule(rule, configsToRules, pluginPrefix, configEmojis, ignoreConfig, SEVERITY_TYPE.off), | ||
[COLUMN_TYPE.CONFIGS_WARN]: getConfigurationColumnValueForRule(rule, configsToRules, pluginPrefix, configEmojis, ignoreConfig, SEVERITY_TYPE.warn), | ||
[COLUMN_TYPE.DEPRECATED]: rule.deprecated ? EMOJI_DEPRECATED : '', | ||
@@ -103,13 +97,5 @@ [COLUMN_TYPE.DESCRIPTION]: rule.description || '', | ||
const headerStrOrFn = COLUMN_HEADER[columnType]; | ||
const configsThatSetAnyRule = Object.entries(configsToRules) | ||
.filter(([configName, config]) => Object.keys(config).some((ruleNameWithPrefix) => getConfigsForRule(ruleNameWithPrefix.replace(`${pluginPrefix}/`, ''), configsToRules, pluginPrefix).includes(configName))) | ||
.map(([configName, _config]) => configName); | ||
return [ | ||
typeof headerStrOrFn === 'function' | ||
? headerStrOrFn({ | ||
configNames: configsThatSetAnyRule, | ||
configEmojis, | ||
ignoreConfig, | ||
details, | ||
}) | ||
? headerStrOrFn({ details }) | ||
: headerStrOrFn, | ||
@@ -194,3 +180,3 @@ ]; | ||
// Determine columns to include in the rules list. | ||
const columns = getColumns(details, configsToRules, ruleListColumns, ignoreConfig); | ||
const columns = getColumns(plugin, details, configsToRules, ruleListColumns, pluginPrefix, ignoreConfig); | ||
// New legend. | ||
@@ -197,0 +183,0 @@ const legend = generateLegend(columns, plugin, configsToRules, configEmojis, pluginPrefix, ignoreConfig, urlConfigs); |
import { END_RULE_HEADER_MARKER } from './markers.js'; | ||
import { EMOJI_DEPRECATED, EMOJI_FIXABLE, EMOJI_HAS_SUGGESTIONS, EMOJI_CONFIG, EMOJI_REQUIRES_TYPE_CHECKING, } from './emojis.js'; | ||
import { EMOJI_DEPRECATED, EMOJI_FIXABLE, EMOJI_HAS_SUGGESTIONS, EMOJI_REQUIRES_TYPE_CHECKING, EMOJI_CONFIG_FROM_SEVERITY, } from './emojis.js'; | ||
import { findConfigEmoji, getConfigsForRule } from './configs.js'; | ||
import { SEVERITY_TYPE, NOTICE_TYPE, SEVERITY_ERROR, SEVERITY_OFF, SEVERITY_WARN, } from './types.js'; | ||
import { SEVERITY_TYPE, NOTICE_TYPE, } from './types.js'; | ||
import { RULE_TYPE_MESSAGES_NOTICES } from './rule-type.js'; | ||
@@ -31,3 +31,3 @@ import { RULE_DOC_TITLE_FORMAT_DEFAULT, } from './rule-doc-title-format.js'; | ||
} | ||
function configsToNoticeSentence(configs, severity, configsLinkOrWord, configLinkOrWord, configEmojis, useGenericConfigEmoji) { | ||
function configsToNoticeSentence(configs, severity, configsLinkOrWord, configLinkOrWord, configEmojis) { | ||
// Create CSV list of configs with their emojis. | ||
@@ -44,6 +44,3 @@ const csv = configs | ||
: configs.length === 1 | ||
? `This rule ${term} in the ${ | ||
// If the config's emoji isn't already being used at the front of the notice, include it here by using the CSV. | ||
// If the config's emoji IS already being used, just use the config name only here. | ||
useGenericConfigEmoji ? csv : `\`${configs?.[0]}\``} ${configLinkOrWord}.` | ||
? `This rule ${term} in the ${csv} ${configLinkOrWord}.` | ||
: undefined; | ||
@@ -57,3 +54,3 @@ return sentence; | ||
// Configs notice varies based on whether the rule is configured in one or more configs. | ||
[NOTICE_TYPE.CONFIGS]: ({ configsEnabled, configsWarn, configsDisabled, configEmojis, urlConfigs, }) => { | ||
[NOTICE_TYPE.CONFIGS]: ({ configsError, configsWarn, configsOff, configEmojis, urlConfigs, }) => { | ||
// Add link to configs documentation if provided. | ||
@@ -65,42 +62,26 @@ const configsLinkOrWord = urlConfigs | ||
/* istanbul ignore next -- this shouldn't happen */ | ||
if ((!configsEnabled || configsEnabled.length === 0) && | ||
if ((!configsError || configsError.length === 0) && | ||
(!configsWarn || configsWarn.length === 0) && | ||
(!configsDisabled || configsDisabled.length === 0)) { | ||
(!configsOff || configsOff.length === 0)) { | ||
throw new Error('Should not be trying to display config notice for rule not configured in any configs.'); | ||
} | ||
// If one applicable config with an emoji, use the emoji for that config, otherwise use the general config emoji. | ||
let emoji = ''; | ||
const useGenericConfigEmoji = configsEnabled.length + configsWarn.length + configsDisabled.length > 1; | ||
if (useGenericConfigEmoji) { | ||
emoji = EMOJI_CONFIG; | ||
// Use the emoji(s) for the severity levels this rule is set to in various configs. | ||
const emojis = []; | ||
if (configsError.length > 0) { | ||
emojis.push(EMOJI_CONFIG_FROM_SEVERITY[SEVERITY_TYPE.error]); | ||
} | ||
else if (configsEnabled.length > 0) { | ||
// @ts-expect-error -- will always be a string thanks to fallback | ||
emoji = findConfigEmoji(configEmojis, configsEnabled[0], { | ||
severity: SEVERITY_TYPE.error, | ||
fallback: 'emoji', | ||
}); | ||
if (configsWarn.length > 0) { | ||
emojis.push(EMOJI_CONFIG_FROM_SEVERITY[SEVERITY_TYPE.warn]); | ||
} | ||
else if (configsWarn.length > 0) { | ||
// @ts-expect-error -- will always be a string thanks to fallback | ||
emoji = findConfigEmoji(configEmojis, configsWarn[0], { | ||
severity: SEVERITY_TYPE.warn, | ||
fallback: 'emoji', | ||
}); | ||
if (configsOff.length > 0) { | ||
emojis.push(EMOJI_CONFIG_FROM_SEVERITY[SEVERITY_TYPE.off]); | ||
} | ||
else if (configsDisabled.length > 0) { | ||
// @ts-expect-error -- will always be a string thanks to fallback | ||
emoji = findConfigEmoji(configEmojis, configsDisabled[0], { | ||
severity: SEVERITY_TYPE.off, | ||
fallback: 'emoji', | ||
}); | ||
} | ||
const sentences = [ | ||
configsToNoticeSentence(configsEnabled, SEVERITY_TYPE.error, configsLinkOrWord, configLinkOrWord, configEmojis, useGenericConfigEmoji), | ||
configsToNoticeSentence(configsWarn, SEVERITY_TYPE.warn, configsLinkOrWord, configLinkOrWord, configEmojis, useGenericConfigEmoji), | ||
configsToNoticeSentence(configsDisabled, SEVERITY_TYPE.off, configsLinkOrWord, configLinkOrWord, configEmojis, useGenericConfigEmoji), | ||
configsToNoticeSentence(configsError, SEVERITY_TYPE.error, configsLinkOrWord, configLinkOrWord, configEmojis), | ||
configsToNoticeSentence(configsWarn, SEVERITY_TYPE.warn, configsLinkOrWord, configLinkOrWord, configEmojis), | ||
configsToNoticeSentence(configsOff, SEVERITY_TYPE.off, configsLinkOrWord, configLinkOrWord, configEmojis), | ||
] | ||
.filter(Boolean) | ||
.join(' '); | ||
return `${emoji} ${sentences}`; | ||
return `${emojis.join('')} ${sentences}`; | ||
}, | ||
@@ -135,8 +116,8 @@ // Deprecated notice has optional "replaced by" rules list. | ||
*/ | ||
function getNoticesForRule(rule, configsEnabled, configsWarn, configsDisabled, ruleDocNotices) { | ||
function getNoticesForRule(rule, configsError, configsWarn, configsOff, ruleDocNotices) { | ||
const notices = { | ||
// Alphabetical order. | ||
[NOTICE_TYPE.CONFIGS]: configsEnabled.length > 0 || | ||
[NOTICE_TYPE.CONFIGS]: configsError.length > 0 || | ||
configsWarn.length > 0 || | ||
configsDisabled.length > 0, | ||
configsOff.length > 0, | ||
[NOTICE_TYPE.DEPRECATED]: rule.meta?.deprecated || false, | ||
@@ -173,6 +154,6 @@ // FIXABLE_AND_HAS_SUGGESTIONS potentially replaces FIXABLE and HAS_SUGGESTIONS. | ||
} | ||
const configsEnabled = getConfigsForRule(ruleName, configsToRules, pluginPrefix, SEVERITY_ERROR).filter((configName) => !ignoreConfig?.includes(configName)); | ||
const configsWarn = getConfigsForRule(ruleName, configsToRules, pluginPrefix, SEVERITY_WARN).filter((configName) => !ignoreConfig?.includes(configName)); | ||
const configsDisabled = getConfigsForRule(ruleName, configsToRules, pluginPrefix, SEVERITY_OFF).filter((configName) => !ignoreConfig?.includes(configName)); | ||
const notices = getNoticesForRule(rule, configsEnabled, configsWarn, configsDisabled, ruleDocNotices); | ||
const configsError = getConfigsForRule(ruleName, configsToRules, pluginPrefix, SEVERITY_TYPE.error).filter((configName) => !ignoreConfig?.includes(configName)); | ||
const configsWarn = getConfigsForRule(ruleName, configsToRules, pluginPrefix, SEVERITY_TYPE.warn).filter((configName) => !ignoreConfig?.includes(configName)); | ||
const configsOff = getConfigsForRule(ruleName, configsToRules, pluginPrefix, SEVERITY_TYPE.off).filter((configName) => !ignoreConfig?.includes(configName)); | ||
const notices = getNoticesForRule(rule, configsError, configsWarn, configsOff, ruleDocNotices); | ||
let noticeType; | ||
@@ -194,5 +175,5 @@ for (noticeType in notices) { | ||
? ruleNoticeStrOrFn({ | ||
configsEnabled, | ||
configsError, | ||
configsWarn, | ||
configsDisabled, | ||
configsOff, | ||
configEmojis, | ||
@@ -199,0 +180,0 @@ urlConfigs, |
@@ -53,3 +53,5 @@ import type { TSESLint, JSONSchema } from '@typescript-eslint/utils'; | ||
export declare enum COLUMN_TYPE { | ||
CONFIGS = "configs", | ||
CONFIGS_ERROR = "configsError", | ||
CONFIGS_OFF = "configsOff", | ||
CONFIGS_WARN = "configsWarn", | ||
DEPRECATED = "deprecated", | ||
@@ -56,0 +58,0 @@ DESCRIPTION = "description", |
@@ -35,3 +35,5 @@ // Custom types. | ||
(function (COLUMN_TYPE) { | ||
COLUMN_TYPE["CONFIGS"] = "configs"; | ||
COLUMN_TYPE["CONFIGS_ERROR"] = "configsError"; | ||
COLUMN_TYPE["CONFIGS_OFF"] = "configsOff"; | ||
COLUMN_TYPE["CONFIGS_WARN"] = "configsWarn"; | ||
COLUMN_TYPE["DEPRECATED"] = "deprecated"; | ||
@@ -38,0 +40,0 @@ COLUMN_TYPE["DESCRIPTION"] = "description"; |
{ | ||
"name": "eslint-doc-generator", | ||
"version": "0.18.2", | ||
"version": "0.19.0", | ||
"description": "Automatic documentation generator for ESLint plugins and rules.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -89,9 +89,7 @@ # eslint-doc-generator | ||
✅ This rule is enabled in the `recommended` config. | ||
💼 This rule is enabled in the following configs: ✅ `recommended`, 🎨 `stylistic`. | ||
🎨<sup>⚠️</sup> This rule _warns_ in the `stylistic` config. | ||
⚠️ This rule _warns_ in the 🎨 `stylistic` config. | ||
🎨<sup>🚫</sup> This rule is _disabled_ in the `stylistic` config. | ||
🚫 This rule is _disabled_ in the 🎨 `stylistic` config. | ||
@@ -135,6 +133,6 @@ 🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix). | ||
💼 Configurations enabled in.\ | ||
✅ Enabled in the `recommended` configuration.\ | ||
✅<sup>⚠️</sup> Warns in the `recommended` configuration.\ | ||
✅<sup>🚫</sup> Disabled in the `recommended` configuration.\ | ||
🎨 Enabled in the `stylistic` configuration.\ | ||
⚠️ Configurations set to warn in.\ | ||
🚫 Configurations disabled in.\ | ||
✅ Set in the `recommended` configuration.\ | ||
🎨 Set in the `stylistic` configuration.\ | ||
🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\ | ||
@@ -191,3 +189,3 @@ 💡 Manually fixable by [editor suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).\ | ||
| `--rule-doc-title-format` | The format to use for rule doc titles. Defaults to `desc-parens-prefix-name`. See choices in below [table](#--rule-doc-title-format). | | ||
| `--rule-list-columns` | Ordered, comma-separated list of columns to display in rule list. Empty columns will be hidden. Choices: `configs`, `deprecated`, `description`, `fixable`, `hasSuggestions`, `name`, `requiresTypeChecking`, `type` (off by default). Default: `name,description,configs,fixable,hasSuggestions,requiresTypeChecking,deprecated`. | | ||
| `--rule-list-columns` | Ordered, comma-separated list of columns to display in rule list. Empty columns will be hidden. Choices: `configsError`, `configsOff`, `configsWarn`, `deprecated`, `description`, `fixable`, `hasSuggestions`, `name`, `requiresTypeChecking`, `type` (off by default). Default: `name,description,configsError,configsWarn,configsOff,fixable,hasSuggestions,requiresTypeChecking,deprecated`. | | ||
| `--split-by` | Rule property to split the rules list by. A separate list and header will be created for each value. Example: `meta.type`. | | ||
@@ -223,12 +221,2 @@ | `--url-configs` | Link to documentation about the ESLint configurations exported by the plugin. | | ||
### markdownlint | ||
The output of this tool should be compatible with [markdownlint](https://github.com/DavidAnson/markdownlint) which you might use to lint your markdown. However, if any of your ESLint configs disable your rules or set them to warn, you'll need to exempt some elements used for emoji superscripts from [no-inline-html](https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md033---inline-html): | ||
```json | ||
{ | ||
"no-inline-html": { "allowed_elements": ["br", "sup"] } | ||
} | ||
``` | ||
### prettier | ||
@@ -235,0 +223,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1598
89069
237