Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

eslint-doc-generator

Package Overview
Dependencies
Maintainers
1
Versions
62
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-doc-generator - npm Package Compare versions

Comparing version 0.13.0 to 0.14.0

4

dist/lib/configs.d.ts

@@ -1,6 +0,6 @@

import type { Plugin, ConfigsToRules, ConfigEmojis } from './types.js';
import type { Plugin, ConfigsToRules, ConfigEmojis, RuleSeverity } from './types.js';
/**
* Get config names that a given rule belongs to.
*/
export declare function getConfigsForRule(ruleName: string, configsToRules: ConfigsToRules, pluginPrefix: string): string[];
export declare function getConfigsForRule(ruleName: string, configsToRules: ConfigsToRules, pluginPrefix: string, severity: Set<RuleSeverity>): string[];
/**

@@ -7,0 +7,0 @@ * Parse the options, check for errors, and set defaults.

import { EMOJI_CONFIGS } from './emojis.js';
const SEVERITY_ENABLED = new Set([2, 'error']);
/**
* Get config names that a given rule belongs to.
*/
export function getConfigsForRule(ruleName, configsToRules, pluginPrefix) {
export function getConfigsForRule(ruleName, configsToRules, pluginPrefix, severity) {
const configNames = [];

@@ -12,7 +11,7 @@ for (const configName in configsToRules) {

const isEnabled = ((typeof value === 'string' || typeof value === 'number') &&
SEVERITY_ENABLED.has(value)) ||
severity.has(value)) ||
(typeof value === 'object' &&
Array.isArray(value) &&
value.length > 0 &&
SEVERITY_ENABLED.has(value[0]));
severity.has(value[0]));
if (isEnabled) {

@@ -19,0 +18,0 @@ configNames.push(configName);

@@ -1,2 +0,2 @@

import { COLUMN_TYPE, ConfigEmojis, Plugin } from './types.js';
export declare function generateLegend(columns: Record<COLUMN_TYPE, boolean>, plugin: Plugin, configEmojis: ConfigEmojis, ignoreConfig: string[], urlConfigs?: string): string;
import { COLUMN_TYPE, ConfigEmojis, Plugin, ConfigsToRules } from './types.js';
export declare function generateLegend(columns: Record<COLUMN_TYPE, boolean>, plugin: Plugin, configsToRules: ConfigsToRules, configEmojis: ConfigEmojis, pluginPrefix: string, ignoreConfig: string[], urlConfigs?: string): string;
import { EMOJI_DEPRECATED, EMOJI_FIXABLE, EMOJI_HAS_SUGGESTIONS, EMOJI_CONFIG, EMOJI_REQUIRES_TYPE_CHECKING, EMOJI_TYPE, } from './emojis.js';
import { COLUMN_TYPE } from './types.js';
import { getConfigsForRule } from './configs.js';
import { COLUMN_TYPE, SEVERITY_ERROR, } from './types.js';
import { RULE_TYPE_MESSAGES_LEGEND, RULE_TYPES } from './rule-type.js';

@@ -9,8 +10,7 @@ /**

// Legends are included for each config. A generic config legend is also included if there are multiple configs.
[COLUMN_TYPE.CONFIGS]: ({ plugin, configEmojis, urlConfigs, ignoreConfig, }) => {
[COLUMN_TYPE.CONFIGS]: ({ plugin, configsToRules, configEmojis, pluginPrefix, urlConfigs, ignoreConfig, }) => {
/* istanbul ignore next -- this shouldn't happen */
if (!plugin.configs) {
throw new Error('Should not be attempting to display configs column when there are no configs.');
if (!plugin.configs || !plugin.rules) {
throw new Error('Should not be attempting to display configs column when there are no configs/rules.');
}
const configNames = Object.keys(plugin.configs);
// Add link to configs documentation if provided.

@@ -23,6 +23,14 @@ const configsLinkOrWord = urlConfigs

: 'configuration';
const configNamesWithoutIgnored = configNames.filter((configName) => !ignoreConfig?.includes(configName));
const ruleNames = Object.keys(plugin.rules);
const configsThatEnableAnyRule = Object.entries(configsToRules)
.filter(([configName, _config]) => ruleNames.some((ruleName) => getConfigsForRule(ruleName, configsToRules, pluginPrefix, SEVERITY_ERROR).includes(configName)))
.map(([configName, _config]) => configName);
const configNamesWithoutIgnored = configsThatEnableAnyRule.filter((configName) => !ignoreConfig?.includes(configName));
const legends = [];
if (configNamesWithoutIgnored.length > 1 ||
!configEmojis.find((configEmoji) => configNamesWithoutIgnored?.includes(configEmoji.config))?.emoji) {
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.

@@ -73,3 +81,3 @@ legends.push(`${EMOJI_CONFIG} ${configsLinkOrWord} enabled in.`);

};
export function generateLegend(columns, plugin, configEmojis, ignoreConfig, urlConfigs) {
export function generateLegend(columns, plugin, configsToRules, configEmojis, pluginPrefix, ignoreConfig, urlConfigs) {
return Object.entries(columns)

@@ -89,3 +97,5 @@ .flatMap(([columnType, enabled]) => {

plugin,
configsToRules,
configEmojis,
pluginPrefix,
urlConfigs,

@@ -92,0 +102,0 @@ ignoreConfig,

@@ -1,3 +0,3 @@

export declare const BEGIN_RULE_LIST_MARKER = "<!-- begin rules list -->";
export declare const END_RULE_LIST_MARKER = "<!-- end rules list -->";
export declare const END_RULE_HEADER_MARKER = "<!-- end rule header -->";
export declare const BEGIN_RULE_LIST_MARKER = "<!-- begin auto-generated rules list -->";
export declare const END_RULE_LIST_MARKER = "<!-- end auto-generated rules list -->";
export declare const END_RULE_HEADER_MARKER = "<!-- end auto-generated rule header -->";
// Markers so that the README rules list can be automatically updated.
export const BEGIN_RULE_LIST_MARKER = '<!-- begin rules list -->';
export const END_RULE_LIST_MARKER = '<!-- end rules list -->';
export const BEGIN_RULE_LIST_MARKER = '<!-- begin auto-generated rules list -->';
export const END_RULE_LIST_MARKER = '<!-- end auto-generated rules list -->';
// Marker so that rule doc header (title/notices) can be automatically updated.
export const END_RULE_HEADER_MARKER = '<!-- end rule header -->';
export const END_RULE_HEADER_MARKER = '<!-- end auto-generated rule header -->';

@@ -9,12 +9,9 @@ import { BEGIN_RULE_LIST_MARKER, END_RULE_LIST_MARKER } from './markers.js';

import { relative } from 'node:path';
import { COLUMN_TYPE } from './types.js';
import { COLUMN_TYPE, SEVERITY_ERROR } from './types.js';
import { markdownTable } from 'markdown-table';
import { EMOJIS_TYPE } from './rule-type.js';
function getConfigurationColumnValueForRule(rule, configsToRules, pluginPrefix, configEmojis, ignoreConfig) {
const badges = [];
const configs = getConfigsForRule(rule.name, configsToRules, pluginPrefix);
for (const configName of configs) {
if (ignoreConfig?.includes(configName)) {
// Ignore config.
continue;
}
const configsEnabled = getConfigsForRule(rule.name, configsToRules, pluginPrefix, SEVERITY_ERROR).filter((configName) => !ignoreConfig?.includes(configName));
for (const configName of configsEnabled) {
// Find the emoji for the config or otherwise use a badge that can be defined in markdown.

@@ -53,6 +50,10 @@ const emoji = configEmojis.find((configEmoji) => configEmoji.config === configName)?.emoji;

const headerStrOrFn = COLUMN_HEADER[columnType];
const ruleNames = details.map((rule) => rule.name);
const configsThatEnableAnyRule = Object.entries(configsToRules)
.filter(([configName, _config]) => ruleNames.some((ruleName) => getConfigsForRule(ruleName, configsToRules, pluginPrefix, SEVERITY_ERROR).includes(configName)))
.map(([configName, _config]) => configName);
return [
typeof headerStrOrFn === 'function'
? headerStrOrFn({
configNames: Object.keys(configsToRules),
configNames: configsThatEnableAnyRule,
configEmojis,

@@ -65,12 +66,9 @@ ignoreConfig,

});
const listSpacerRow = Array.from({ length: listHeaderRow.length }).fill(':--'); // Left-align header with colon.
return [
return markdownTable([
listHeaderRow,
listSpacerRow,
...details
.sort(({ name: a }, { name: b }) => a.localeCompare(b))
.map((rule) => buildRuleRow(columns, rule, configsToRules, pluginPrefix, configEmojis, ignoreConfig)),
]
.map((column) => [...column, ' '].join('|'))
.join('\n');
], { align: 'l' } // Left-align headers.
);
}

@@ -105,3 +103,3 @@ export async function updateRulesList(details, markdown, plugin, configsToRules, pluginPrefix, pathToReadme, pathToPlugin, configEmojis, ignoreConfig, ruleListColumns, urlConfigs) {

// New legend.
const legend = generateLegend(columns, plugin, configEmojis, ignoreConfig, urlConfigs);
const legend = generateLegend(columns, plugin, configsToRules, configEmojis, pluginPrefix, ignoreConfig, urlConfigs);
// New rule list.

@@ -108,0 +106,0 @@ const list = generateRulesListMarkdown(columns, details, configsToRules, pluginPrefix, configEmojis, ignoreConfig);

@@ -6,3 +6,3 @@ import { END_RULE_HEADER_MARKER } from './markers.js';

import { RULE_DOC_TITLE_FORMAT_DEFAULT, } from './rule-doc-title-format.js';
import { NOTICE_TYPE } from './types.js';
import { NOTICE_TYPE, SEVERITY_ERROR, SEVERITY_OFF } from './types.js';
export const NOTICE_TYPE_DEFAULT_PRESENCE_AND_ORDERING = {

@@ -24,3 +24,3 @@ // Object keys ordered in display order.

// Configs notice varies based on whether the rule is enabled in one or more configs.
[NOTICE_TYPE.CONFIGS]: ({ configsEnabled, configEmojis, urlConfigs }) => {
[NOTICE_TYPE.CONFIGS]: ({ configsEnabled, configsDisabled, configEmojis, urlConfigs, }) => {
// Add link to configs documentation if provided.

@@ -32,20 +32,47 @@ const configsLinkOrWord = urlConfigs

/* istanbul ignore next -- this shouldn't happen */
if (!configsEnabled || configsEnabled.length === 0) {
throw new Error('Should not be trying to display config notice for rule not enabled in any configs.');
if ((!configsEnabled || configsEnabled.length === 0) &&
(!configsDisabled || configsDisabled.length === 0)) {
throw new Error('Should not be trying to display config notice for rule not enabled/disabled in any configs.');
}
if (configsEnabled.length > 1) {
// Rule is enabled in multiple configs.
const configs = configsEnabled
.map((configEnabled) => {
const emoji = configEmojis.find((configEmoji) => configEmoji.config === configEnabled)?.emoji;
return `${emoji ? `${emoji} ` : ''}\`${configEnabled}\``;
})
.join(', ');
return `${EMOJI_CONFIG} This rule is enabled in the following ${configsLinkOrWord}: ${configs}.`;
// If one applicable config with an emoji, use the emoji for that config, otherwise use the general config emoji.
let emoji = '';
if (configsEnabled.length + configsDisabled.length > 1) {
emoji = EMOJI_CONFIG;
}
else {
// Rule only enabled in one config.
const emoji = configEmojis.find((configEmoji) => configEmoji.config === configsEnabled?.[0])?.emoji ?? EMOJI_CONFIG;
return `${emoji} This rule is enabled in the \`${configsEnabled?.[0]}\` ${configLinkOrWord}.`;
else if (configsEnabled.length > 0) {
emoji =
configEmojis.find((configEmoji) => configEmoji.config === configsEnabled[0])?.emoji ?? EMOJI_CONFIG;
}
else if (configsDisabled.length > 0) {
emoji =
configEmojis.find((configEmoji) => configEmoji.config === configsDisabled[0])?.emoji ?? EMOJI_CONFIG;
}
// List of configs that enable the rule.
const configsEnabledCSV = configsEnabled
.map((configEnabled) => {
const emoji = configEmojis.find((configEmoji) => configEmoji.config === configEnabled)?.emoji;
return `${emoji ? `${emoji} ` : ''}\`${configEnabled}\``;
})
.join(', ');
// List of configs that disable the rule.
const configsDisabledCSV = configsDisabled
.map((configDisabled) => {
const emoji = configEmojis.find((configEmoji) => configEmoji.config === configDisabled)?.emoji;
return `${emoji ? `${emoji} ` : ''}\`${configDisabled}\``;
})
.join(', ');
// Complete sentence for configs that enable the rule.
const SENTENCE_ENABLED = configsEnabled.length > 1
? `This rule is enabled in the following ${configsLinkOrWord}: ${configsEnabledCSV}.`
: configsEnabled.length === 1
? `This rule is enabled in the \`${configsEnabled?.[0]}\` ${configLinkOrWord}.`
: '';
// Complete sentence for configs that disable the rule.
const SENTENCE_DISABLED = configsDisabled.length > 1
? `This rule is _disabled_ in the following ${configsLinkOrWord}: ${configsDisabledCSV}.`
: configsDisabled.length === 1
? `This rule is _disabled_ in the \`${configsDisabled?.[0]}\` ${configLinkOrWord}.`
: '';
return `${emoji} ${SENTENCE_ENABLED}${SENTENCE_ENABLED && SENTENCE_DISABLED ? ' ' : '' // Space if two sentences.
}${SENTENCE_DISABLED}`;
},

@@ -74,3 +101,3 @@ // Deprecated notice has optional "replaced by" rules list.

return ruleNames
.map((ruleName) => `[${ruleName}](${ruleName}.md)`)
.map((ruleName) => `[\`${ruleName}\`](${ruleName}.md)`)
.join(', ');

@@ -81,6 +108,6 @@ }

*/
function getNoticesForRule(rule, configsEnabled, ruleDocNotices) {
function getNoticesForRule(rule, configsEnabled, configsDisabled, ruleDocNotices) {
const notices = {
// Alphabetical order.
[NOTICE_TYPE.CONFIGS]: configsEnabled.length > 0,
[NOTICE_TYPE.CONFIGS]: configsEnabled.length > 0 || configsDisabled.length > 0,
[NOTICE_TYPE.DEPRECATED]: rule.meta.deprecated || false,

@@ -117,4 +144,5 @@ // FIXABLE_AND_HAS_SUGGESTIONS potentially replaces FIXABLE and HAS_SUGGESTIONS.

}
const configsEnabled = getConfigsForRule(ruleName, configsToRules, pluginPrefix).filter((config) => !ignoreConfig?.includes(config));
const notices = getNoticesForRule(rule, configsEnabled, ruleDocNotices);
const configsEnabled = getConfigsForRule(ruleName, configsToRules, pluginPrefix, SEVERITY_ERROR).filter((configName) => !ignoreConfig?.includes(configName));
const configsDisabled = getConfigsForRule(ruleName, configsToRules, pluginPrefix, SEVERITY_OFF).filter((configName) => !ignoreConfig?.includes(configName));
const notices = getNoticesForRule(rule, configsEnabled, configsDisabled, ruleDocNotices);
let noticeType;

@@ -137,2 +165,3 @@ for (noticeType in notices) {

configsEnabled,
configsDisabled,
configEmojis,

@@ -139,0 +168,0 @@ urlConfigs,

import type { TSESLint, JSONSchema } from '@typescript-eslint/utils';
export declare type RuleModule = TSESLint.RuleModule<string, unknown[]>;
export declare type Rules = TSESLint.Linter.RulesRecord;
export declare type RuleSeverity = TSESLint.Linter.RuleLevel;
export declare type Config = TSESLint.Linter.Config;
export declare type Plugin = TSESLint.Linter.Plugin;
export declare const SEVERITY_ERROR: Set<TSESLint.Linter.RuleLevel>;
export declare const SEVERITY_OFF: Set<TSESLint.Linter.RuleLevel>;
export declare type ConfigsToRules = Record<string, Rules>;

@@ -7,0 +10,0 @@ export interface RuleDetails {

@@ -0,1 +1,4 @@

// Custom types.
export const SEVERITY_ERROR = new Set([2, 'error']);
export const SEVERITY_OFF = new Set([0, 'off']);
/**

@@ -2,0 +5,0 @@ * Rule doc notices.

{
"name": "eslint-doc-generator",
"version": "0.13.0",
"version": "0.14.0",
"description": "Automatic documentation generator for ESLint plugins and rules.",

@@ -48,2 +48,3 @@ "keywords": [

"commander": "^9.4.0",
"markdown-table": "^3.0.2",
"type-fest": "^3.0.0"

@@ -50,0 +51,0 @@ },

@@ -48,4 +48,4 @@ # eslint-doc-generator

```md
<!-- begin rules list -->
<!-- end rules list -->
<!-- begin auto-generated rules list -->
<!-- end auto-generated rules list -->
```

@@ -74,2 +74,4 @@

🎨 This rule is _disabled_ in the `stylistic` config.
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).

@@ -79,2 +81,4 @@

🔧💡 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) and manually fixable by [editor suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).
💭 This rule requires type information.

@@ -90,3 +94,3 @@

<!-- end rule header -->
<!-- end auto-generated rule header -->

@@ -109,3 +113,3 @@ Description.

<!-- begin rules list -->
<!-- begin auto-generated rules list -->

@@ -130,3 +134,3 @@ 💼 Configurations enabled in.\

<!-- end rules list -->
<!-- end auto-generated rules list -->

@@ -133,0 +137,0 @@ ...

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc