feat: jsdoc eslint

This commit is contained in:
Guz013
2023-07-19 16:39:24 -03:00
parent f540e1e7e3
commit c2b39fb0bf
13 changed files with 162 additions and 24 deletions

View File

@@ -0,0 +1,26 @@
import type { ESLint } from 'eslint';
/**
* @see {@link https://www.npmjs.org/package/eslint-plugin-jsdoc npm package}
*
* @summary JSDoc specific linting rules for ESLint.
*
* ---
* **Note:** Types in this project where overridden to be compatible with ESLint new flat
* config types. ESlint already has backwards compatibility for plugins not created in the
* new flat config.
*/
declare module 'eslint-plugin-jsdoc' {
interface jsDocESlintPlugin extends ESLint.Plugin {
configs: ESLint.Plugin['configs'] & {
recommended: ESLint.ConfigData
'recommended-error': ESLint.ConfigData
'recommended-typescript': ESLint.ConfigData
'recommended-typescript-error': ESLint.ConfigData
'recommended-typescript-flavor': ESLint.ConfigData
'recommended-typescript-flavor-error': ESLint.ConfigData
}
}
declare const plugin: jsDocESlintPlugin;
export default plugin;
}

View File

@@ -2,6 +2,7 @@ import type { ESLint, Linter } from 'eslint';
/**
* @see {@link https://www.npmjs.com/package/@typescript-eslint/eslint-plugin npm package}
*
* @summary An ESLint plugin which provides lint rules for TypeScript codebases.
*
* ---
@@ -32,6 +33,7 @@ declare module '@typescript-eslint/eslint-plugin' {
/**
* @see {@link https://www.npmjs.com/package/@typescript-eslint/parser npm package}
*
* @summary An ESLint parser which leverages TypeScript ESTree to allow for ESLint
* to lint TypeScript source code.
*

View File

@@ -1,6 +1,7 @@
/**
* Common configuration related to language features of Javascript and Typescript
*
* @type {import('../types').ESConfig}
*/
const config = {

View File

@@ -2,12 +2,13 @@ import globals from 'globals';
/**
* @param {import('../types').Config['environment']} environment
*
* Manual configuration of environments, if undefined,
* the function tries to detect the environment automatically
* @returns {import('../types').ESConfig[]}
*/
* ESLint configuration with global variables and environment
*/
export function environments(environment) {
/** @type {Record<string, Record<string, boolean>>} */
environment ||= {
node:
typeof window === 'undefined' &&

View File

@@ -1,5 +1,6 @@
/**
* Formatting rules/configuration for Javascript and Typescript
*
* @type {import('../types').ESConfig}
*/
const config = {

View File

@@ -1,4 +1,5 @@
export { default as common } from './common.js';
export { default as formatting } from './formatting.js';
export { default as jsdoc } from './jsdoc.js';
export { default as typescript } from './typescript.js';
export * from './environments.js';

View File

@@ -0,0 +1,20 @@
/**
* JSDoc rules overrides
*
* @type {import('../types').ESConfig}
*/
const config = {
files: ['**/*.js', '**/*.cjs', '**/*.mjs', '**/*.ts', '**/*.cts', '**/*.mts'],
rules: {
'jsdoc/tag-lines': ['error', 'always', {
count: 1,
applyToEndTag: false,
startLines: 1,
endLines: 0,
tags: {
param: { lines: 'never' },
},
}],
},
};
export default config;

View File

@@ -1,10 +1,20 @@
import jsdoc from 'eslint-plugin-jsdoc';
/**
* Typescript syntax-specific configuration
* Typescript specific configuration
*
* @type {import('../types').ESConfig}
*/
const config = {
files: ['**/*.ts', '**/*.cts', '**/*.mts'],
// See plugins['jsdoc'] on index.js for more info on this error
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
rules: {
// See plugins['jsdoc'] on index.js for more info on this error
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
...jsdoc.configs['recommended-typescript-error'].rules,
'@typescript-eslint/adjacent-overload-signatures': 'error',
'@typescript-eslint/array-type': 'error',
'@typescript-eslint/class-literal-property-style': 'error',

View File

@@ -1,15 +1,17 @@
import { eslintrc } from './eslintrc-compact.js';
import tsEslint from '@typescript-eslint/eslint-plugin';
import tsESlint from '@typescript-eslint/eslint-plugin';
import tsParser from '@typescript-eslint/parser';
import jsdoc from 'eslint-plugin-jsdoc';
import js from '@eslint/js';
import * as configs from './configs/index.js';
import { getTsConfigs } from './tsconfigs.js';
/**
* @param {import('./types').Config} userConfig
*
* User configuration
* @returns {Promise<import('./types').ESConfig[]>}
*/
* The complete list of configs for ESLint
*/
export async function defineConfig(userConfig) {
userConfig.strict ??= true;
@@ -38,7 +40,14 @@ export async function defineConfig(userConfig) {
{
files: ['**/*.js', '**/*.cjs', '**/*.mjs', '**/*.ts', '**/*.cts', '**/*.mts'],
plugins: {
'@typescript-eslint': tsEslint,
'@typescript-eslint': tsESlint,
/**
* @todo
* Fix eslint-plugin-jsdoc type definitions.
* _Typescript should have detected [eslint-plugin-jsdoc.d.ts](./@types/eslint-plugin-jsdoc.d.ts)._
*/
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
'jsdoc': jsdoc,
},
languageOptions: {
sourceType: 'module',
@@ -48,15 +57,21 @@ export async function defineConfig(userConfig) {
tsconfigRootDir: userConfig.rootDir,
},
},
// See plugins['jsdoc'] for more info on this error
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
rules: {
...tsEslint.configs.recommended.rules,
...tsEslint.configs['recommended-requiring-type-checking'].rules,
...tsEslint.configs['eslint-recommended'].rules,
...(userConfig.strict ? tsEslint.configs.strict.rules : null),
...tsESlint.configs.recommended.rules,
...tsESlint.configs['recommended-requiring-type-checking'].rules,
...tsESlint.configs['eslint-recommended'].rules,
...(userConfig.strict ? tsESlint.configs.strict.rules : null),
// See plugins['jsdoc'] for more info on this error
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
...jsdoc.configs['recommended-typescript-flavor-error'].rules,
},
},
configs.common,
configs.formatting,
configs.jsdoc,
configs.typescript,
...configs.environments(userConfig.environment),
...userOverrides,

View File

@@ -13,8 +13,8 @@ function exists(...path) {
}
/**
* @param {string} directory
* @returns {Promise<string[]>}
* @param {string} directory what the root directory to detect an workspace/monorepo configuration file
* @returns {Promise<string[]>} list of possible paths of packages' tsconfig.json and jsconfig.json files
*/
async function getMonorepoConfigs(directory) {
@@ -60,8 +60,8 @@ async function getMonorepoConfigs(directory) {
}
/**
* @param {string} directory
* @returns {Promise<string[]>}
* @param {string} directory what the root directory to work on
* @returns {Promise<string[]>} list of tsconfig.json and jsconfig.json file paths
*/
export async function getTsConfigs(directory) {

View File

@@ -22,7 +22,6 @@ export interface Config {
* **Note:** this does not enables CommonJS globals, if you are using
* CommonJS, use a file ending in `.cjs` or `.cts`
*
*
* @example // Detects if
* typeof window === 'undefined' &&
* typeof process !== 'undefined' &&