Require JSDoc Hierarchy
Require JSDoc summary lines to follow the hierarchy chain derived from the file path and method name.
Summary
The require-jsdoc-hierarchy rule reports any JSDoc summary line on a supported declaration that does not match the expected hierarchy string.
The expected hierarchy is built from the file path segments after the first matching anchor directory (default: src), with each segment title-cased and separated by -. Functions, variables, test suites, and class methods add their declaration identity after the path identity.
Repeated path prefixes inside long declaration names are collapsed. For example, LIB_REGEX_PATTERN_DIGITS in src/lib/regex.ts becomes Lib - Regex - Pattern Digits.. When the complete declaration name matches the final path segment, it remains as a separate declaration level: Details() in src/theme/Details/index.tsx becomes Theme - Details - Details..
Known abbreviations (e.g., api to API, eslint to ESLint) are applied automatically. Path segments named index are always dropped (e.g. src/cli/index.ts yields CLI.), in addition to any stripDirectories entries.
Files that hold <script> tags (astro, md, markdown, html, htm, vue, svelte) are skipped, because processor-based ESLint plugins extract each <script> block into a virtual file whose name embeds a non-deterministic batch counter, so the expected hierarchy can never converge. A Logger.warn notice reports each skip; set warnSkippedScripts to false to silence it.
Why Use This Rule?
- Ensures every JSDoc summary line is consistent and predictable across the codebase.
- Makes it possible to locate a class or method in the file tree by reading its JSDoc summary.
- Eliminates subjective or inconsistent summary text by deriving it mechanically from the file path.
Examples
For a declaration whose name matches its containing path, both identities remain visible:
// File: src/theme/Details/index.tsx
/**
* Theme - Details - Details.
*
* @since UNRELEASED
*/
export default function Details() {
// ...
}
Configuration
Options
warning
ignoreFiles is an escape hatch for files where this rule genuinely does not apply. It is not intended for routine use.
| Option | Type | Default | Description |
|---|---|---|---|
anchorDirectories | string[] | ['src'] | Directory names that serve as path anchors. |
ignoreFiles | string[] | [] | File names to skip. Supports a leading-* suffix (*.test.ts), an exact path, or a trailing path segment; ** globs are not supported. |
knownNames | Record<string, string> | {} | Custom brand/abbreviation mappings for prettifying. |
stripDirectories | string[] | ['types'] | Directory names to filter out from path parts. |
warnSkippedScripts | boolean | true | Emit a Logger.warn notice when a file holding a <script> tag is skipped. Set to false to silence the notice. |
Autofix
This rule provides automatic fixes. Run ESLint with the --fix flag:
npx eslint --fix . --rule '@cbnventures/nova/require-jsdoc-hierarchy: error'
Troubleshooting
- Warning fires even though the summary looks correct — Check for extra or missing spaces around
-separators, and verify that known abbreviations match exactly (e.g.,APInotApi,ESLintnotEslint). - File is not under any anchor directory — The rule tries each
anchorDirectoriesentry in order. If none match, it falls back to using the filename stem as the path hierarchy base. Asidebarsdeclaration insidebars.ts, for example, becomesSidebars - Sidebars.because the path and declaration remain separate identities. - Constructor summary looks off — Constructors are checked like any other method, with
Constructorappended as the final segment (e.g.CLI - Utility - Changelog - Constructor.). - Error says to rename a directory — If the first path segment after the anchor directory begins with a digit (e.g.
src/2fa/...), the rule reportsinvalidIdentifierPrefixand asks you to rename the directory to start with a letter, because the segment would produce an invalid TypeScript identifier prefix. The normal hierarchy check is skipped for that file until renamed. - Exported type aliases may add sub-segments — For
export typedeclarations the rule accepts any summary that begins with the file's hierarchy prefix and ends with a period (e.g.Logger - Debug.is allowed under aLogger.path), so related types can live in one file under sub-section names. - Notice fires for a component with a
<script>— Files holding<script>tags (astro,md,markdown,html,htm,vue,svelte) are skipped because their extracted virtual filenames are non-deterministic. TheLogger.warnnotice is informational, not an error. SetwarnSkippedScriptstofalseto silence it.