eslint-doc-generator
Advanced tools
Comparing version 0.10.0 to 0.11.0
@@ -7,2 +7,3 @@ import { Command, Argument, Option } from 'commander'; | ||
import { RULE_DOC_TITLE_FORMAT_DEFAULT, RULE_DOC_TITLE_FORMATS, } from './rule-doc-title-format.js'; | ||
import { COLUMN_TYPE, COLUMN_TYPE_DEFAULT_ORDERING, } from './rule-list-columns.js'; | ||
const __dirname = dirname(fileURLToPath(import.meta.url)); | ||
@@ -35,2 +36,3 @@ function getCurrentPackageVersion() { | ||
.default(RULE_DOC_TITLE_FORMAT_DEFAULT)) | ||
.option('--rule-list-columns <columns>', `(optional) Ordered, comma-separated list of columns to display in rule list. Empty columns will be hidden. (choices: "${Object.values(COLUMN_TYPE).join('", "')}")`, COLUMN_TYPE_DEFAULT_ORDERING.join(',')) | ||
.option('--url-configs <url>', '(optional) Link to documentation about the ESLint configurations exported by the plugin.') | ||
@@ -46,2 +48,3 @@ .action(async function (path, options) { | ||
ruleDocTitleFormat: options.ruleDocTitleFormat, | ||
ruleListColumns: options.ruleListColumns, | ||
urlConfigs: options.urlConfigs, | ||
@@ -48,0 +51,0 @@ }); |
import type { Plugin, ConfigsToRules, ConfigEmojis } from './types.js'; | ||
export declare function hasAnyConfigs(configsToRules: ConfigsToRules): boolean; | ||
/** | ||
@@ -4,0 +3,0 @@ * Get config names that a given rule belongs to. |
import { EMOJI_CONFIG_RECOMMENDED } from './emojis.js'; | ||
export function hasAnyConfigs(configsToRules) { | ||
return Object.keys(configsToRules).length > 0; | ||
} | ||
const SEVERITY_ENABLED = new Set([2, 'error']); | ||
@@ -6,0 +3,0 @@ /** |
@@ -10,3 +10,4 @@ import { RuleDocTitleFormat } from './rule-doc-title-format.js'; | ||
ruleDocTitleFormat?: RuleDocTitleFormat; | ||
ruleListColumns?: string; | ||
urlConfigs?: string; | ||
}): Promise<void>; |
@@ -11,2 +11,3 @@ import { existsSync, readFileSync, writeFileSync } from 'node:fs'; | ||
import { parseConfigEmojiOptions } from './configs.js'; | ||
import { parseRuleListColumnsOption } from './rule-list-columns.js'; | ||
/** | ||
@@ -80,2 +81,3 @@ * Ensure a rule doc contains (or doesn't contain) some particular content. | ||
const ignoreConfig = options?.ignoreConfig ?? []; | ||
const ruleListColumns = parseRuleListColumnsOption(options?.ruleListColumns); | ||
// Update rule doc for each rule. | ||
@@ -122,3 +124,3 @@ for (const { name, description, schema } of details) { | ||
const readmeContents = readFileSync(pathToReadme, 'utf8'); | ||
const readmeContentsNew = await updateRulesList(details, readmeContents, plugin, configsToRules, pluginPrefix, pathToReadme, path, configEmojis, ignoreConfig, options?.urlConfigs); | ||
const readmeContentsNew = await updateRulesList(details, readmeContents, plugin, configsToRules, pluginPrefix, pathToReadme, path, configEmojis, ignoreConfig, ruleListColumns, options?.urlConfigs); | ||
if (options?.check) { | ||
@@ -125,0 +127,0 @@ if (readmeContentsNew !== readmeContents) { |
@@ -8,5 +8,6 @@ import type { RuleDetails, ConfigsToRules, ConfigEmojis } from './types.js'; | ||
HAS_SUGGESTIONS = "hasSuggestions", | ||
NAME = "rules", | ||
NAME = "name", | ||
REQUIRES_TYPE_CHECKING = "requiresTypeChecking" | ||
} | ||
export declare const COLUMN_TYPE_DEFAULT_ORDERING: COLUMN_TYPE[]; | ||
/** | ||
@@ -26,10 +27,6 @@ * An object containing the column header for each column (as a string or function to generate the string). | ||
*/ | ||
export declare function getColumns(details: RuleDetails[], configsToRules: ConfigsToRules, ignoreConfig: string[]): { | ||
configs: boolean; | ||
deprecated: boolean; | ||
description: boolean; | ||
fixable: boolean; | ||
hasSuggestions: boolean; | ||
rules: boolean; | ||
requiresTypeChecking: boolean; | ||
}; | ||
export declare function getColumns(details: RuleDetails[], configsToRules: ConfigsToRules, ruleListColumns: COLUMN_TYPE[], ignoreConfig: string[]): Record<COLUMN_TYPE, boolean>; | ||
/** | ||
* Parse the option, check for errors, and set defaults. | ||
*/ | ||
export declare function parseRuleListColumnsOption(ruleListColumns: string | undefined): COLUMN_TYPE[]; |
@@ -9,5 +9,14 @@ import { EMOJI_CONFIGS, EMOJI_DEPRECATED, EMOJI_FIXABLE, EMOJI_HAS_SUGGESTIONS, EMOJI_REQUIRES_TYPE_CHECKING, } from './emojis.js'; | ||
COLUMN_TYPE["HAS_SUGGESTIONS"] = "hasSuggestions"; | ||
COLUMN_TYPE["NAME"] = "rules"; | ||
COLUMN_TYPE["NAME"] = "name"; | ||
COLUMN_TYPE["REQUIRES_TYPE_CHECKING"] = "requiresTypeChecking"; | ||
})(COLUMN_TYPE || (COLUMN_TYPE = {})); | ||
export const COLUMN_TYPE_DEFAULT_ORDERING = [ | ||
COLUMN_TYPE.NAME, | ||
COLUMN_TYPE.DESCRIPTION, | ||
COLUMN_TYPE.CONFIGS, | ||
COLUMN_TYPE.FIXABLE, | ||
COLUMN_TYPE.HAS_SUGGESTIONS, | ||
COLUMN_TYPE.REQUIRES_TYPE_CHECKING, | ||
COLUMN_TYPE.DEPRECATED, | ||
]; | ||
/** | ||
@@ -36,15 +45,36 @@ * An object containing the column header for each column (as a string or function to generate the string). | ||
*/ | ||
export function getColumns(details, configsToRules, ignoreConfig) { | ||
export function getColumns(details, configsToRules, ruleListColumns, ignoreConfig) { | ||
const columns = { | ||
// Object keys in display order. | ||
[COLUMN_TYPE.NAME]: true, | ||
[COLUMN_TYPE.DESCRIPTION]: details.some((detail) => detail.description), | ||
// 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.DEPRECATED]: details.some((detail) => detail.deprecated), | ||
[COLUMN_TYPE.DESCRIPTION]: details.some((detail) => detail.description), | ||
[COLUMN_TYPE.FIXABLE]: details.some((detail) => detail.fixable), | ||
[COLUMN_TYPE.HAS_SUGGESTIONS]: details.some((detail) => detail.hasSuggestions), | ||
[COLUMN_TYPE.NAME]: true, | ||
[COLUMN_TYPE.REQUIRES_TYPE_CHECKING]: details.some((detail) => detail.requiresTypeChecking), | ||
[COLUMN_TYPE.DEPRECATED]: details.some((detail) => detail.deprecated), | ||
}; | ||
return columns; | ||
// Recreate object using the ordering and presence of columns specified in ruleListColumns. | ||
return Object.fromEntries(ruleListColumns.map((column) => [column, columns[column]])); | ||
} | ||
/** | ||
* Parse the option, check for errors, and set defaults. | ||
*/ | ||
export function parseRuleListColumnsOption(ruleListColumns) { | ||
const values = ruleListColumns ? ruleListColumns.split(',') : []; | ||
const COLUMN_TYPE_VALUES = new Set(Object.values(COLUMN_TYPE).map(String)); | ||
// Check for invalid. | ||
const invalid = values.find((val) => !COLUMN_TYPE_VALUES.has(val)); | ||
if (invalid) { | ||
throw new Error(`Invalid ruleListColumns option: ${invalid}`); | ||
} | ||
if (values.length !== new Set(values).size) { | ||
throw new Error('Duplicate value detected in ruleListColumns option.'); | ||
} | ||
if (values.length === 0) { | ||
// Use default columns and ordering. | ||
values.push(...COLUMN_TYPE_DEFAULT_ORDERING); | ||
} | ||
return values; | ||
} |
@@ -0,2 +1,3 @@ | ||
import { COLUMN_TYPE } from './rule-list-columns.js'; | ||
import type { Plugin, RuleDetails, ConfigsToRules, ConfigEmojis } from './types.js'; | ||
export declare function updateRulesList(details: RuleDetails[], markdown: string, plugin: Plugin, configsToRules: ConfigsToRules, pluginPrefix: string, pathToReadme: string, pathToPlugin: string, configEmojis: ConfigEmojis, ignoreConfig: string[], urlConfigs?: string): Promise<string>; | ||
export declare function updateRulesList(details: RuleDetails[], markdown: string, plugin: Plugin, configsToRules: ConfigsToRules, pluginPrefix: string, pathToReadme: string, pathToPlugin: string, configEmojis: ConfigEmojis, ignoreConfig: string[], ruleListColumns: COLUMN_TYPE[], urlConfigs?: string): Promise<string>; |
import { BEGIN_RULE_LIST_MARKER, END_RULE_LIST_MARKER } from './markers.js'; | ||
import { EMOJI_DEPRECATED, EMOJI_FIXABLE, EMOJI_HAS_SUGGESTIONS, EMOJI_REQUIRES_TYPE_CHECKING, } from './emojis.js'; | ||
import { getConfigsForRule, hasAnyConfigs } from './configs.js'; | ||
import { getConfigsForRule } from './configs.js'; | ||
import { COLUMN_TYPE, getColumns, COLUMN_HEADER } from './rule-list-columns.js'; | ||
@@ -23,31 +23,23 @@ import { findSectionHeader, format } from './markdown.js'; | ||
} | ||
function buildRuleRow(columnsEnabled, rule, configsToRules, pluginPrefix, includeTypesColumn, configEmojis, ignoreConfig) { | ||
const columns = []; | ||
if (columnsEnabled[COLUMN_TYPE.NAME]) { | ||
columns.push(`[${rule.name}](docs/rules/${rule.name}.md)`); | ||
} | ||
if (columnsEnabled[COLUMN_TYPE.DESCRIPTION]) { | ||
columns.push(rule.description || ''); | ||
} | ||
if (columnsEnabled[COLUMN_TYPE.CONFIGS] && hasAnyConfigs(configsToRules)) { | ||
columns.push(getConfigurationColumnValueForRule(rule, configsToRules, pluginPrefix, configEmojis, ignoreConfig)); | ||
} | ||
if (columnsEnabled[COLUMN_TYPE.FIXABLE]) { | ||
columns.push(rule.fixable ? EMOJI_FIXABLE : ''); | ||
} | ||
if (columnsEnabled[COLUMN_TYPE.HAS_SUGGESTIONS]) { | ||
columns.push(rule.hasSuggestions ? EMOJI_HAS_SUGGESTIONS : ''); | ||
} | ||
if (columnsEnabled[COLUMN_TYPE.REQUIRES_TYPE_CHECKING] && | ||
includeTypesColumn) { | ||
columns.push(rule.requiresTypeChecking ? EMOJI_REQUIRES_TYPE_CHECKING : ''); | ||
} | ||
if (columnsEnabled[COLUMN_TYPE.DEPRECATED] && rule.deprecated) { | ||
columns.push(EMOJI_DEPRECATED); | ||
} | ||
return columns; | ||
function buildRuleRow(columnsEnabled, rule, configsToRules, pluginPrefix, configEmojis, ignoreConfig) { | ||
const columns = { | ||
// Alphabetical order. | ||
[COLUMN_TYPE.CONFIGS]: getConfigurationColumnValueForRule(rule, configsToRules, pluginPrefix, configEmojis, ignoreConfig), | ||
[COLUMN_TYPE.DEPRECATED]: rule.deprecated ? EMOJI_DEPRECATED : '', | ||
[COLUMN_TYPE.DESCRIPTION]: rule.description || '', | ||
[COLUMN_TYPE.FIXABLE]: rule.fixable ? EMOJI_FIXABLE : '', | ||
[COLUMN_TYPE.HAS_SUGGESTIONS]: rule.hasSuggestions | ||
? EMOJI_HAS_SUGGESTIONS | ||
: '', | ||
[COLUMN_TYPE.NAME]: `[${rule.name}](docs/rules/${rule.name}.md)`, | ||
[COLUMN_TYPE.REQUIRES_TYPE_CHECKING]: rule.requiresTypeChecking | ||
? EMOJI_REQUIRES_TYPE_CHECKING | ||
: '', | ||
}; | ||
// List columns using the ordering and presence of columns specified in columnsEnabled. | ||
return Object.keys(columnsEnabled).flatMap((column) => columnsEnabled[column] | ||
? [columns[column]] | ||
: []); | ||
} | ||
function generateRulesListMarkdown(columns, details, configsToRules, pluginPrefix, configEmojis, ignoreConfig) { | ||
// Since such rules are rare, we'll only include the types column if at least one rule requires type checking. | ||
const includeTypesColumn = details.some((detail) => detail.requiresTypeChecking); | ||
const listHeaderRow = Object.entries(columns).flatMap(([columnType, enabled]) => { | ||
@@ -74,3 +66,3 @@ if (!enabled) { | ||
.sort(({ name: a }, { name: b }) => a.localeCompare(b)) | ||
.map((rule) => buildRuleRow(columns, rule, configsToRules, pluginPrefix, includeTypesColumn, configEmojis, ignoreConfig)), | ||
.map((rule) => buildRuleRow(columns, rule, configsToRules, pluginPrefix, configEmojis, ignoreConfig)), | ||
] | ||
@@ -80,3 +72,3 @@ .map((column) => [...column, ' '].join('|')) | ||
} | ||
export async function updateRulesList(details, markdown, plugin, configsToRules, pluginPrefix, pathToReadme, pathToPlugin, configEmojis, ignoreConfig, urlConfigs) { | ||
export async function updateRulesList(details, markdown, plugin, configsToRules, pluginPrefix, pathToReadme, pathToPlugin, configEmojis, ignoreConfig, ruleListColumns, urlConfigs) { | ||
let listStartIndex = markdown.indexOf(BEGIN_RULE_LIST_MARKER); | ||
@@ -107,3 +99,3 @@ let listEndIndex = markdown.indexOf(END_RULE_LIST_MARKER); | ||
// Determine columns to include in the rules list. | ||
const columns = getColumns(details, configsToRules, ignoreConfig); | ||
const columns = getColumns(details, configsToRules, ruleListColumns, ignoreConfig); | ||
// New legend. | ||
@@ -110,0 +102,0 @@ const legend = generateLegend(columns, plugin, configEmojis, ignoreConfig, urlConfigs); |
{ | ||
"name": "eslint-doc-generator", | ||
"version": "0.10.0", | ||
"version": "0.11.0", | ||
"description": "Automatic documentation generator for ESLint plugins and rules.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -70,2 +70,4 @@ # eslint-doc-generator | ||
💭 This rule requires type information. | ||
❌ This rule is deprecated. It was replaced by [prefer-bar](prefer-bar.md). | ||
@@ -141,2 +143,3 @@ | ||
| `--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`. Default: `name,description,configs,fixable,hasSuggestions,requiresTypeChecking,deprecated`. | | ||
| `--url-configs` | Link to documentation about the ESLint configurations exported by the plugin. | | ||
@@ -143,0 +146,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
56461
1000
166