eslint-doc-generator
Advanced tools
Comparing version 0.3.5 to 0.4.0
@@ -29,3 +29,5 @@ import { existsSync } from 'node:fs'; | ||
const rules = {}; | ||
for (const extend of extendItems) { | ||
for (const extend of Array.isArray(extendItems) | ||
? extendItems | ||
: [extendItems]) { | ||
if (['plugin:', 'eslint:'].some((prefix) => extend.startsWith(prefix)) || | ||
@@ -32,0 +34,0 @@ !existsSync(extend)) { |
@@ -42,16 +42,31 @@ import { existsSync, readFileSync, writeFileSync } from 'node:fs'; | ||
}; | ||
if (!plugin.rules) { | ||
throw new Error('Could not find exported `rules` object in ESLint plugin.'); | ||
} | ||
// Gather details about rules. | ||
const details = Object.entries(plugin.rules) | ||
.filter((nameAndRule) => Boolean(nameAndRule[1].meta)) | ||
.map(([name, rule]) => ({ | ||
name, | ||
description: rule.meta.docs?.description, | ||
fixable: rule.meta.fixable | ||
? ['code', 'whitespace'].includes(rule.meta.fixable) | ||
: false, | ||
hasSuggestions: rule.meta.hasSuggestions ?? false, | ||
requiresTypeChecking: rule.meta.docs?.requiresTypeChecking ?? false, | ||
deprecated: rule.meta.deprecated ?? false, | ||
schema: rule.meta.schema, | ||
})); | ||
const details = Object.entries(plugin.rules).map(([name, rule]) => { | ||
return typeof rule === 'object' | ||
? // Object-style rule. | ||
{ | ||
name, | ||
description: rule.meta.docs?.description, | ||
fixable: rule.meta.fixable | ||
? ['code', 'whitespace'].includes(rule.meta.fixable) | ||
: false, | ||
hasSuggestions: rule.meta.hasSuggestions ?? false, | ||
requiresTypeChecking: rule.meta.docs?.requiresTypeChecking ?? false, | ||
deprecated: rule.meta.deprecated ?? false, | ||
schema: rule.meta.schema, | ||
} | ||
: // Deprecated function-style rule (does not support most of these features). | ||
{ | ||
name, | ||
description: undefined, | ||
fixable: false, | ||
hasSuggestions: false, | ||
requiresTypeChecking: false, | ||
deprecated: false, | ||
schema: [], // TODO: figure out how to access `schema` property that can be exported from function-style rules. | ||
}; | ||
}); | ||
// Update rule doc for each rule. | ||
@@ -58,0 +73,0 @@ for (const { name, description, schema, deprecated } of details) { |
@@ -22,5 +22,2 @@ import { join } from 'node:path'; | ||
const { default: plugin } = await importAbs(pluginEntryPoint); | ||
if (!plugin.rules) { | ||
throw new Error('Could not find exported `rules` object in ESLint plugin.'); | ||
} | ||
return plugin; | ||
@@ -27,0 +24,0 @@ } |
@@ -28,3 +28,3 @@ import { BEGIN_RULE_LIST_MARKER, END_RULE_LIST_MARKER } from './markers.js'; | ||
`[${rule.name}](docs/rules/${rule.name}.md)`, | ||
rule.description, | ||
rule.description || '', | ||
getConfigurationColumnValueForRule(rule, configsToRules, pluginPrefix), | ||
@@ -31,0 +31,0 @@ rule.fixable ? EMOJI_FIXABLE : '', |
@@ -8,2 +8,2 @@ import type { Plugin, ConfigsToRules } from './types.js'; | ||
*/ | ||
export declare function generateRuleHeaderLines(description: string, name: string, plugin: Plugin, configsToRules: ConfigsToRules, pluginPrefix: string): string; | ||
export declare function generateRuleHeaderLines(description: string | undefined, name: string, plugin: Plugin, configsToRules: ConfigsToRules, pluginPrefix: string): string; |
@@ -46,3 +46,13 @@ import { END_RULE_HEADER_MARKER } from './markers.js'; | ||
const lines = []; | ||
const rule = plugin.rules[ruleName]; | ||
const rule = plugin.rules?.[ruleName]; | ||
/* istanbul ignore next */ | ||
if (!rule) { | ||
// This is only to please TypeScript. We should always have a rule when this function is called. | ||
throw new Error('Rule not found'); | ||
} | ||
if (typeof rule !== 'object') { | ||
// We don't support the deprecated, function-style rule format as there's not much information we can extract from it. | ||
// https://eslint.org/docs/latest/developer-guide/working-with-rules-deprecated | ||
return []; | ||
} | ||
const configsEnabled = getConfigsForRule(ruleName, configsToRules, pluginPrefix); | ||
@@ -65,3 +75,5 @@ const notices = getNoticesForRule(rule, configsEnabled); | ||
// This notice should include links to the replacement rule(s) if available. | ||
const message = Array.isArray(rule.meta.replacedBy) && rule.meta.replacedBy.length > 0 | ||
const message = typeof rule === 'object' && | ||
Array.isArray(rule.meta.replacedBy) && | ||
rule.meta.replacedBy.length > 0 | ||
? `${MESSAGES[messageType]} It was replaced by ${ruleNamesToList(rule.meta.replacedBy)}.` | ||
@@ -92,5 +104,9 @@ : MESSAGES[messageType]; | ||
export function generateRuleHeaderLines(description, name, plugin, configsToRules, pluginPrefix) { | ||
const descriptionFormatted = removeTrailingPeriod(toSentenceCase(description)); | ||
const descriptionFormatted = description | ||
? removeTrailingPeriod(toSentenceCase(description)) | ||
: undefined; | ||
return [ | ||
`# ${descriptionFormatted} (\`${pluginPrefix}/${name}\`)`, | ||
descriptionFormatted | ||
? `# ${descriptionFormatted} (\`${pluginPrefix}/${name}\`)` | ||
: `# \`${pluginPrefix}/${name}\``, | ||
...getRuleNoticeLines(name, plugin, configsToRules, pluginPrefix), | ||
@@ -97,0 +113,0 @@ END_RULE_HEADER_MARKER, |
import type { TSESLint, JSONSchema } from '@typescript-eslint/utils'; | ||
export declare type RuleModule = TSESLint.RuleModule<string, unknown[]> & { | ||
meta: Required<Pick<TSESLint.RuleMetaData<string>, 'docs'>>; | ||
}; | ||
declare type RuleSeverity = 'off' | 'error' | 'warn' | 0 | 1 | 2; | ||
export declare type Rules = Record<string, RuleSeverity | [RuleSeverity, unknown]>; | ||
export declare type Config = { | ||
extends?: string[]; | ||
rules?: Rules; | ||
overrides?: { | ||
rules?: Rules; | ||
extends?: []; | ||
}[]; | ||
}; | ||
export declare type RuleModule = TSESLint.RuleModule<string, unknown[]>; | ||
export declare type Rules = TSESLint.Linter.RulesRecord; | ||
export declare type Config = TSESLint.Linter.Config; | ||
export declare type Plugin = TSESLint.Linter.Plugin; | ||
export declare type ConfigsToRules = Record<string, Rules>; | ||
export declare type Plugin = { | ||
rules: Record<string, RuleModule>; | ||
configs?: Record<string, Config>; | ||
}; | ||
export interface RuleDetails { | ||
name: string; | ||
description: string; | ||
description?: string; | ||
fixable: boolean; | ||
@@ -29,2 +16,1 @@ hasSuggestions: boolean; | ||
} | ||
export {}; |
{ | ||
"name": "eslint-doc-generator", | ||
"version": "0.3.5", | ||
"version": "0.4.0", | ||
"description": "Automatic documentation generator for ESLint plugins and rules.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
35116
625