Skip to content

Commit ac604c8

Browse files
authored
chore: restore eslint-plugin-jsdoc rules (#185)
* chore: restore eslint-plugin-jsdoc rules * add `coverage/` to global ignores * centralize comparator typing with ComparatorMap and union key typedefs
1 parent 3d63c38 commit ac604c8

File tree

9 files changed

+37
-67
lines changed

9 files changed

+37
-67
lines changed

eslint.config.js

Lines changed: 22 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,14 @@
99

1010
import eslintConfigESLint from "eslint-config-eslint";
1111
import eslintPlugin from "eslint-plugin-eslint-plugin";
12+
import globals from "globals";
1213
import json from "./src/index.js";
1314
import { defineConfig, globalIgnores } from "eslint/config";
1415

1516
//-----------------------------------------------------------------------------
1617
// Helpers
1718
//-----------------------------------------------------------------------------
1819

19-
const eslintPluginJSDoc = eslintConfigESLint.find(
20-
config => config.plugins?.jsdoc,
21-
).plugins.jsdoc;
22-
2320
const eslintPluginRulesRecommendedConfig =
2421
eslintPlugin.configs["flat/rules-recommended"];
2522
const eslintPluginTestsRecommendedConfig =
@@ -30,54 +27,34 @@ const eslintPluginTestsRecommendedConfig =
3027
//-----------------------------------------------------------------------------
3128

3229
export default defineConfig([
33-
globalIgnores([
34-
"**/tests/fixtures/",
35-
"**/dist/",
36-
"coverage/",
37-
"src/build/",
38-
]),
39-
40-
...eslintConfigESLint.map(config => ({
41-
files: ["**/*.js"],
42-
...config,
43-
})),
44-
{
45-
plugins: { json },
46-
files: ["**/*.json", ".c8rc"],
47-
language: "json/json",
48-
extends: ["json/recommended"],
49-
},
30+
globalIgnores(["coverage/", "dist/", "src/build/"], "json/global-ignores"),
5031
{
32+
name: "json/js",
5133
files: ["**/*.js"],
34+
extends: [eslintConfigESLint],
5235
rules: {
53-
// disable rules we don't want to use from eslint-config-eslint
5436
"no-undefined": "off",
55-
56-
// TODO: re-enable eslint-plugin-jsdoc rules
57-
...Object.fromEntries(
58-
Object.keys(eslintPluginJSDoc.rules).map(name => [
59-
`jsdoc/${name}`,
60-
"off",
61-
]),
62-
),
6337
},
6438
},
6539
{
66-
files: ["**/tests/**"],
40+
name: "json/tools",
41+
files: ["tools/**/*.js"],
42+
rules: {
43+
"no-console": "off",
44+
},
45+
},
46+
{
47+
name: "json/tests",
48+
files: ["tests/**/*.js"],
49+
ignores: ["tests/rules/*.js"],
6750
languageOptions: {
6851
globals: {
69-
describe: "readonly",
70-
xdescribe: "readonly",
71-
it: "readonly",
72-
xit: "readonly",
73-
beforeEach: "readonly",
74-
afterEach: "readonly",
75-
before: "readonly",
76-
after: "readonly",
52+
...globals.mocha,
7753
},
7854
},
7955
},
8056
{
57+
name: "json/rules",
8158
files: ["src/rules/*.js"],
8259
extends: [eslintPluginRulesRecommendedConfig],
8360
rules: {
@@ -99,6 +76,7 @@ export default defineConfig([
9976
},
10077
},
10178
{
79+
name: "json/rules-tests",
10280
files: ["tests/rules/*.test.js"],
10381
extends: [eslintPluginTestsRecommendedConfig],
10482
rules: {
@@ -119,9 +97,10 @@ export default defineConfig([
11997
},
12098
},
12199
{
122-
files: ["tools/**/*.js"],
123-
rules: {
124-
"no-console": "off",
125-
},
100+
name: "json/json",
101+
plugins: { json },
102+
files: ["**/*.json", ".c8rc"],
103+
language: "json/json",
104+
extends: ["json/recommended"],
126105
},
127106
]);

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
"eslint": "^9.36.0",
9595
"eslint-config-eslint": "^13.0.0",
9696
"eslint-plugin-eslint-plugin": "^6.3.2",
97+
"globals": "^16.5.0",
9798
"lint-staged": "^15.2.7",
9899
"mdast-util-from-markdown": "^2.0.2",
99100
"mocha": "^11.3.0",

src/languages/json-language.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,8 @@ import { visitorKeys } from "@humanwhocodes/momoa";
1818
/**
1919
* @import { DocumentNode, AnyNode } from "@humanwhocodes/momoa";
2020
* @import { Language, OkParseResult, ParseResult, File } from "@eslint/core";
21-
*
2221
* @typedef {OkParseResult<DocumentNode>} JSONOkParseResult
2322
* @typedef {ParseResult<DocumentNode>} JSONParseResult
24-
*
2523
* @typedef {Object} JSONLanguageOptions
2624
* @property {boolean} [allowTrailingCommas] Whether to allow trailing commas in JSONC mode.
2725
*/

src/rules/no-duplicate-keys.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import { getKey, getRawKey } from "../util.js";
1616
/**
1717
* @import { MemberNode } from "@humanwhocodes/momoa";
1818
* @import { JSONRuleDefinition } from "../types.ts";
19-
*
2019
* @typedef {"duplicateKey"} NoDuplicateKeysMessageIds
2120
* @typedef {JSONRuleDefinition<{ MessageIds: NoDuplicateKeysMessageIds }>} NoDuplicateKeysRuleDefinition
2221
*/

src/rules/no-empty-keys.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import { getKey } from "../util.js";
1515

1616
/**
1717
* @import { JSONRuleDefinition } from "../types.ts";
18-
*
1918
* @typedef {"emptyKey"} NoEmptyKeysMessageIds
2019
* @typedef {JSONRuleDefinition<{ MessageIds: NoEmptyKeysMessageIds }>} NoEmptyKeysRuleDefinition
2120
*/

src/rules/no-unnormalized-keys.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import { getKey } from "../util.js";
1515

1616
/**
1717
* @import { JSONRuleDefinition } from "../types.ts";
18-
*
1918
* @typedef {"unnormalizedKey"} NoUnnormalizedKeysMessageIds
2019
* @typedef {{ form: string }} NoUnnormalizedKeysOptions
2120
* @typedef {JSONRuleDefinition<{ RuleOptions: [NoUnnormalizedKeysOptions], MessageIds: NoUnnormalizedKeysMessageIds }>} NoUnnormalizedKeysRuleDefinition

src/rules/no-unsafe-values.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
/**
1111
* @import { JSONRuleDefinition } from "../types.ts";
12-
*
1312
* @typedef {"unsafeNumber"|"unsafeInteger"|"unsafeZero"|"subnormal"|"loneSurrogate"} NoUnsafeValuesMessageIds
1413
* @typedef {JSONRuleDefinition<{ MessageIds: NoUnsafeValuesMessageIds }>} NoUnsafeValuesRuleDefinition
1514
*/

src/rules/sort-keys.js

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,20 @@ import { getKey, getRawKey } from "../util.js";
1818
/**
1919
* @import { JSONRuleDefinition } from "../types.ts";
2020
* @import { MemberNode } from "@humanwhocodes/momoa";
21-
*
2221
* @typedef {Object} SortOptions
23-
* @property {boolean} caseSensitive
24-
* @property {boolean} natural
25-
* @property {number} minKeys
26-
* @property {boolean} allowLineSeparatedGroups
27-
*
22+
* @property {boolean} caseSensitive Whether key comparisons are case-sensitive.
23+
* @property {boolean} natural Whether to use natural sort order instead of purely alphanumeric.
24+
* @property {number} minKeys Minimum number of keys in an object before enforcing sorting.
25+
* @property {boolean} allowLineSeparatedGroups Whether a blank line between properties starts a new group that is independently sorted.
2826
* @typedef {"sortKeys"} SortKeysMessageIds
2927
* @typedef {"asc"|"desc"} SortDirection
3028
* @typedef {[SortDirection, SortOptions]} SortKeysRuleOptions
3129
* @typedef {JSONRuleDefinition<{ RuleOptions: SortKeysRuleOptions, MessageIds: SortKeysMessageIds }>} SortKeysRuleDefinition
3230
* @typedef {(a:string,b:string) => boolean} Comparator
31+
* @typedef {"ascending"|"descending"} DirectionName
32+
* @typedef {"alphanumeric"|"natural"} SortName
33+
* @typedef {"sensitive"|"insensitive"} Sensitivity
34+
* @typedef {Record<DirectionName, Record<SortName, Record<Sensitivity, Comparator>>>} ComparatorMap
3335
*/
3436

3537
//-----------------------------------------------------------------------------
@@ -38,39 +40,30 @@ import { getKey, getRawKey } from "../util.js";
3840

3941
const hasNonWhitespace = /\S/u;
4042

43+
/** @type {ComparatorMap} */
4144
const comparators = {
4245
ascending: {
4346
alphanumeric: {
44-
/** @type {Comparator} */
4547
sensitive: (a, b) => a <= b,
46-
47-
/** @type {Comparator} */
4848
insensitive: (a, b) => a.toLowerCase() <= b.toLowerCase(),
4949
},
5050
natural: {
51-
/** @type {Comparator} */
5251
sensitive: (a, b) => naturalCompare(a, b) <= 0,
53-
54-
/** @type {Comparator} */
5552
insensitive: (a, b) =>
5653
naturalCompare(a.toLowerCase(), b.toLowerCase()) <= 0,
5754
},
5855
},
5956
descending: {
6057
alphanumeric: {
61-
/** @type {Comparator} */
6258
sensitive: (a, b) =>
6359
comparators.ascending.alphanumeric.sensitive(b, a),
6460

65-
/** @type {Comparator} */
6661
insensitive: (a, b) =>
6762
comparators.ascending.alphanumeric.insensitive(b, a),
6863
},
6964
natural: {
70-
/** @type {Comparator} */
7165
sensitive: (a, b) => comparators.ascending.natural.sensitive(b, a),
7266

73-
/** @type {Comparator} */
7467
insensitive: (a, b) =>
7568
comparators.ascending.natural.insensitive(b, a),
7669
},
@@ -140,9 +133,13 @@ const rule = {
140133
{ allowLineSeparatedGroups, caseSensitive, natural, minKeys },
141134
] = context.options;
142135

136+
/** @type {DirectionName} */
143137
const direction = directionShort === "asc" ? "ascending" : "descending";
138+
/** @type {SortName} */
144139
const sortName = natural ? "natural" : "alphanumeric";
140+
/** @type {Sensitivity} */
145141
const sensitivity = caseSensitive ? "sensitive" : "insensitive";
142+
/** @type {Comparator} */
146143
const isValidOrder = comparators[direction][sortName][sensitivity];
147144

148145
// Note that @humanwhocodes/momoa doesn't include comments in the object.members tree, so we can't just see if a member is preceded by a comment
@@ -161,7 +158,7 @@ const rule = {
161158
* Checks if two members are line-separated.
162159
* @param {MemberNode} prevMember The previous member.
163160
* @param {MemberNode} member The current member.
164-
* @return {boolean}
161+
* @returns {boolean} True if the members are separated by at least one blank line (ignoring comment-only lines).
165162
*/
166163
function isLineSeparated(prevMember, member) {
167164
// Note that there can be comments *inside* members, e.g. `{"foo: /* comment *\/ "bar"}`, but these are ignored when calculating line-separated groups

src/rules/top-level-interop.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
/**
1111
* @import { JSONRuleDefinition } from "../types.ts";
12-
*
1312
* @typedef {"topLevel"} TopLevelInteropMessageIds
1413
* @typedef {JSONRuleDefinition<{ MessageIds: TopLevelInteropMessageIds }>} TopLevelInteropRuleDefinition
1514
*/

0 commit comments

Comments
 (0)