Skip to content

⬅️ Back to Table of Contents

📄 insertNewRuleReferences

📊 Analysis Summary

Metric Count
🔧 Functions 3
📦 Imports 8
📊 Variables & Constants 1
⚡ Async/Await Patterns 1

📚 Table of Contents

🛠️ File Location:

📂 packages/website/plugins/generated-rule-docs/insertions/insertNewRuleReferences.ts

📦 Imports

Name Source
ESLintPluginDocs @typescript-eslint/eslint-plugin/use-at-your-own-risk/rules
MdxJsxFlowElement mdast-util-mdx
schemaToTypes @typescript-eslint/rule-schema-to-typescript-types
EOL node:os
prettier prettier
RuleDocsPage ../RuleDocsPage
nodeIsHeading ../../utils/nodes
convertToPlaygroundHash ../../utils/rules

Variables & Constants

Name Type Kind Value Exported
COMPLICATED_RULE_OPTIONS Set<string> const new Set([ 'member-ordering', 'naming-convention', ])

Async/Await Patterns

Type Function Await Expressions Promise Chains
async-function insertNewRuleReferences lazyPrettierConfig, prettier.format( schemaToTypes(page.rule.meta.schema), pr... none

Functions

insertNewRuleReferences(page: RuleDocsPage): Promise<string>

Parameters:

  • page RuleDocsPage

Returns: Promise<string>

Calls:

  • page.children.findIndex
  • nodeIsHeading (from ../../utils/nodes)
  • page.spliceChildren
  • convertToPlaygroundHash (from ../../utils/rules)
  • Array.isArray
  • Object.keys
  • COMPLICATED_RULE_OPTIONS.has
  • linkToConfigsForObject
  • [ await prettier.format( schemaToTypes(page.rule.meta.schema), prettierConfig, ), await prettier.format(getRuleDefaultOptions(page), prettierConfig), ] .join(EOL) .trim

Internal Comments:

// For non-extended rules, the code snippet is placed before the first h2 (x2)
// (i.e. at the end of the initial explanation) (x2)

Code
export async function insertNewRuleReferences(
  page: RuleDocsPage,
): Promise<string> {
  // For non-extended rules, the code snippet is placed before the first h2
  // (i.e. at the end of the initial explanation)
  const firstH2Index = page.children.findIndex(
    child => nodeIsHeading(child) && child.depth === 2,
  );

  const rules = `{
    "@typescript-eslint/${page.file.stem}": "error"
  }`;

  const eslintrc = `{
  "rules": ${rules}
}`;

  const eslintConfig = `{
  rules: ${rules}
}`;

  page.spliceChildren(
    firstH2Index,
    0,
    {
      children: [
        {
          attributes: [
            {
              name: 'value',
              type: 'mdxJsxAttribute',
              value: 'Flat Config',
            },
          ],
          children: [
            {
              lang: 'js',
              meta: 'title="eslint.config.mjs"',
              type: 'code',
              value: `export default defineConfig(${eslintConfig});`,
            },
          ],
          name: 'TabItem',
          type: 'mdxJsxFlowElement',
        },
        {
          attributes: [
            {
              name: 'value',
              type: 'mdxJsxAttribute',
              value: 'Legacy Config',
            },
          ],
          children: [
            {
              lang: 'js',
              meta: 'title=".eslintrc.cjs"',
              type: 'code',
              value: `module.exports = ${eslintrc};`,
            },
          ],
          name: 'TabItem',
          type: 'mdxJsxFlowElement',
        },
      ],
      name: 'Tabs',
      type: 'mdxJsxFlowElement',
    } as MdxJsxFlowElement,
    {
      attributes: [
        {
          name: 'eslintrcHash',
          type: 'mdxJsxAttribute',
          value: convertToPlaygroundHash(eslintrc),
        },
      ],
      children: [
        {
          children: [
            {
              type: 'text',
              value: 'Try this rule in the playground ↗',
            },
          ],
          type: 'paragraph',
        },
      ],
      name: 'TryInPlayground',
      type: 'mdxJsxFlowElement',
    } as MdxJsxFlowElement,
  );

  const hasNoConfig = Array.isArray(page.rule.meta.schema)
    ? page.rule.meta.schema.length === 0
    : Object.keys(page.rule.meta.schema).length === 0;

  if (hasNoConfig) {
    page.spliceChildren(
      page.headingIndices.options + 1,
      0,
      'This rule is not configurable.',
    );
  } else if (!COMPLICATED_RULE_OPTIONS.has(page.file.stem)) {
    const prettierConfig = await lazyPrettierConfig;
    page.spliceChildren(
      page.headingIndices.options + 1,
      0,
      typeof page.rule.meta.docs.recommended === 'object'
        ? linkToConfigsForObject(page.rule.meta.docs)
        : 'This rule accepts the following options:',
      {
        lang: 'ts',
        type: 'code',
        value: [
          await prettier.format(
            schemaToTypes(page.rule.meta.schema),
            prettierConfig,
          ),
          await prettier.format(getRuleDefaultOptions(page), prettierConfig),
        ]
          .join(EOL)
          .trim(),
      } as mdast.Code,
    );
  }

  return eslintrc;
}

linkToConfigsForObject(docs: ESLintPluginDocs): string

Parameters:

  • docs ESLintPluginDocs

Returns: string

Calls:

  • [ 'This rule accepts the following options, and has more strict settings in the', (docs.requiresTypeChecking ? ['strict', 'strict-type-checked'] : ['strict']) .map(config =>${config}) .join(' and '),config${docs.requiresTypeChecking ? 's' : ''}., ].join
  • (docs.requiresTypeChecking ? ['strict', 'strict-type-checked'] : ['strict']) .map(config =>${config}) .join
Code
function linkToConfigsForObject(docs: ESLintPluginDocs): string {
  return [
    'This rule accepts the following options, and has more strict settings in the',
    (docs.requiresTypeChecking ? ['strict', 'strict-type-checked'] : ['strict'])
      .map(config => `[${config}](/users/configs#${config})`)
      .join(' and '),
    `config${docs.requiresTypeChecking ? 's' : ''}.`,
  ].join(' ');
}

getRuleDefaultOptions(page: RuleDocsPage): string

Parameters:

  • page RuleDocsPage

Returns: string

Calls:

  • JSON.stringify
  • [ ...(recommended.recommended ? [const defaultOptionsRecommended: Options = ${defaults};, '', '// These options are merged on top of the recommended defaults', ] : []),const defaultOptionsStrict: Options = ${JSON.stringify(recommended.strict)};, ].join

Internal Comments:

// Keep accepting deprecated defaultOptions for backward compatibility. (x2)
// eslint-disable-next-line @typescript-eslint/no-deprecated (x2)

Code
function getRuleDefaultOptions(page: RuleDocsPage): string {
  // Keep accepting deprecated defaultOptions for backward compatibility.
  // eslint-disable-next-line @typescript-eslint/no-deprecated
  const defaults = JSON.stringify(page.rule.defaultOptions);
  const recommended = page.rule.meta.docs.recommended;

  return typeof recommended === 'object'
    ? [
        ...(recommended.recommended
          ? [
              `const defaultOptionsRecommended: Options = ${defaults};`,
              '',
              '// These options are merged on top of the recommended defaults',
            ]
          : []),
        `const defaultOptionsStrict: Options = ${JSON.stringify(recommended.strict)};`,
      ].join('\n')
    : `const defaultOptions: Options = ${defaults};`;
}

Generated by Syntax Scribe