Skip to content

Commit d546e9c

Browse files
committed
feat: add jsdoc typescript types
1 parent fda23d2 commit d546e9c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1480
-211
lines changed

eslint.config.js

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
"use strict";
22

3+
// @ts-expect-error -- TODO: Update plugin version to fix
34
const js = require("@eslint/js");
5+
6+
// @ts-expect-error -- TODO: Update plugin version to fix
47
const { FlatCompat } = require("@eslint/eslintrc");
8+
9+
// @ts-expect-error -- TODO: Update plugin version to fix
510
const eslintPluginEslintPluginAll = require("eslint-plugin-eslint-plugin/configs/all");
11+
12+
// @ts-expect-error -- TODO: Update plugin version to fix
613
const eslintPluginMarkdown = require("eslint-plugin-markdown");
714
const globals = require("globals");
815

@@ -24,6 +31,8 @@ module.exports = [
2431
// Apply mocha config only to tests.
2532
...compat
2633
.extends("plugin:mocha/recommended")
34+
35+
// @ts-expect-error -- TODO: Update plugin version to fix
2736
.map((config) => ({ ...config, files: ["tests/**/*.js"] })),
2837

2938
{
@@ -43,21 +52,6 @@ module.exports = [
4352
eqeqeq: "error",
4453
"func-style": ["error", "declaration"],
4554
"guard-for-in": "error",
46-
"lines-around-comment": [
47-
"error",
48-
{
49-
beforeBlockComment: false,
50-
afterBlockComment: false,
51-
beforeLineComment: true,
52-
afterLineComment: false,
53-
allowBlockStart: true,
54-
allowBlockEnd: true,
55-
allowObjectStart: true,
56-
allowObjectEnd: true,
57-
allowArrayStart: true,
58-
allowArrayEnd: true,
59-
},
60-
],
6155
"max-depth": ["error", 5],
6256
"new-cap": ["error", { newIsCap: true, capIsNew: true }],
6357
"no-array-constructor": "error",
@@ -113,7 +107,6 @@ module.exports = [
113107
"no-throw-literal": "error",
114108
"no-trailing-spaces": "error",
115109
"no-undef": "error",
116-
"no-undefined": "error",
117110
"no-underscore-dangle": "error",
118111
"no-unexpected-multiline": "error",
119112
"no-unmodified-loop-condition": "error",
@@ -137,14 +130,6 @@ module.exports = [
137130
"spaced-comment": ["error", "always", { exceptions: ["-"] }],
138131
strict: ["error", "global"],
139132
"use-isnan": "error",
140-
"valid-jsdoc": [
141-
"error",
142-
{
143-
prefer: {
144-
return: "returns",
145-
},
146-
},
147-
],
148133
"valid-typeof": "error",
149134
yoda: ["error", "never"],
150135

index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
"use strict";
99

1010
const requireIndex = require("requireindex");
11+
12+
// @ts-expect-error -- ESM/TypeScript conversion should fix this.
1113
const pkg = require("./package.json");
1214

1315
module.exports = {

lib/rules/assert-args.js

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,14 @@ module.exports = {
3535
},
3636

3737
create: function (context) {
38+
/** @type {Array<{assertContextVar: string | null}>} */
3839
const testStack = [],
3940
sourceCode = context.getSourceCode();
4041

42+
/**
43+
* @param {import('estree').Node} argNode
44+
* @returns {import('estree').Node}
45+
*/
4146
function isPossibleMessage(argNode) {
4247
// For now, we will allow all nodes. Hoping to allow user-driven
4348
// configuration later.
@@ -48,16 +53,31 @@ module.exports = {
4853
return argNode;
4954
}
5055

56+
/**
57+
* @returns {string | null}
58+
*/
5159
function getAssertContext() {
5260
assert.ok(testStack.length);
5361

5462
return testStack[testStack.length - 1].assertContextVar;
5563
}
5664

65+
/**
66+
* @param {import('estree').Node} callExpressionNode
67+
*/
5768
function checkAssertArity(callExpressionNode) {
69+
if (callExpressionNode.type !== "CallExpression") {
70+
return;
71+
}
72+
73+
const assertContextVar = getAssertContext();
74+
if (!assertContextVar) {
75+
return;
76+
}
77+
5878
const allowedArities = utils.getAllowedArities(
5979
callExpressionNode.callee,
60-
getAssertContext(),
80+
assertContextVar,
6181
),
6282
assertArgs = callExpressionNode.arguments,
6383
lastArg = assertArgs[assertArgs.length - 1],
@@ -84,7 +104,7 @@ module.exports = {
84104
: "unexpectedArgCountNoMessage",
85105
data: {
86106
callee: sourceCode.getText(callExpressionNode.callee),
87-
argCount: assertArgs.length,
107+
argCount: assertArgs.length.toString(),
88108
},
89109
});
90110
}
@@ -97,11 +117,14 @@ module.exports = {
97117
node.arguments,
98118
),
99119
});
100-
} else if (
101-
testStack.length > 0 &&
102-
utils.isAssertion(node.callee, getAssertContext())
103-
) {
104-
checkAssertArity(node);
120+
} else if (testStack.length > 0) {
121+
const assertContext = getAssertContext();
122+
if (
123+
assertContext &&
124+
utils.isAssertion(node.callee, assertContext)
125+
) {
126+
checkAssertArity(node);
127+
}
105128
}
106129
},
107130

lib/rules/literal-compare-order.js

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,6 @@ const assert = require("node:assert"),
1515
// Rule Definition
1616
//------------------------------------------------------------------------------
1717

18-
function swapFirstTwoNodesInList(sourceCode, fixer, list) {
19-
const node0Text = sourceCode.getText(list[0]);
20-
const node1Text = sourceCode.getText(list[1]);
21-
return [
22-
fixer.replaceText(list[0], node1Text),
23-
fixer.replaceText(list[1], node0Text),
24-
];
25-
}
26-
2718
/** @type {import('eslint').Rule.RuleModule} */
2819
module.exports = {
2920
meta: {
@@ -45,6 +36,7 @@ module.exports = {
4536
},
4637

4738
create: function (context) {
39+
/** @type {Array<{assertContextVar: string | null}>} */
4840
const testStack = [],
4941
sourceCode = context.getSourceCode();
5042

@@ -54,6 +46,24 @@ module.exports = {
5446
return testStack[testStack.length - 1].assertContextVar;
5547
}
5648

49+
/**
50+
* @param {any} fixer
51+
* @param {import('estree').Node[]} list
52+
* @returns {import('eslint').Rule.Fix[]}
53+
*/
54+
function swapFirstTwoNodesInList(fixer, list) {
55+
const node0Text = sourceCode.getText(list[0]);
56+
const node1Text = sourceCode.getText(list[1]);
57+
return [
58+
fixer.replaceText(list[0], node1Text),
59+
fixer.replaceText(list[1], node0Text),
60+
];
61+
}
62+
63+
/**
64+
* @param {import('estree').Node[]} args
65+
* @param {boolean} compareActualFirst
66+
*/
5767
function checkLiteralCompareOrder(args, compareActualFirst) {
5868
if (args.length < 2) {
5969
return;
@@ -73,7 +83,7 @@ module.exports = {
7383
actual: sourceCode.getText(args[1]),
7484
},
7585
fix(fixer) {
76-
return swapFirstTwoNodesInList(sourceCode, fixer, args);
86+
return swapFirstTwoNodesInList(fixer, args);
7787
},
7888
});
7989
} else if (
@@ -89,19 +99,29 @@ module.exports = {
8999
actual: sourceCode.getText(args[1]),
90100
},
91101
fix(fixer) {
92-
return swapFirstTwoNodesInList(sourceCode, fixer, args);
102+
return swapFirstTwoNodesInList(fixer, args);
93103
},
94104
});
95105
}
96106
}
97107

108+
/**
109+
* @param {import('eslint').Rule.Node} node
110+
* @param {string | null} assertVar
111+
*/
98112
function processAssertion(node, assertVar) {
113+
if (node.type !== "CallExpression") {
114+
return;
115+
}
116+
99117
/* istanbul ignore else: correctly does nothing */
100-
if (utils.isComparativeAssertion(node.callee, assertVar)) {
101-
const compareActualFirst = utils.shouldCompareActualFirst(
102-
node.callee,
103-
assertVar,
104-
);
118+
if (
119+
!assertVar ||
120+
utils.isComparativeAssertion(node.callee, assertVar)
121+
) {
122+
const compareActualFirst =
123+
!assertVar ||
124+
utils.shouldCompareActualFirst(node.callee, assertVar);
105125
checkLiteralCompareOrder(node.arguments, compareActualFirst);
106126
}
107127
}
@@ -115,11 +135,14 @@ module.exports = {
115135
node.arguments,
116136
),
117137
});
118-
} else if (
119-
testStack.length > 0 &&
120-
utils.isAssertion(node.callee, getAssertContext())
121-
) {
122-
processAssertion(node, getAssertContext());
138+
} else if (testStack.length > 0) {
139+
const assertVar = getAssertContext();
140+
if (
141+
!assertVar ||
142+
utils.isAssertion(node.callee, assertVar)
143+
) {
144+
processAssertion(node, assertVar);
145+
}
123146
}
124147
},
125148

lib/rules/no-arrow-tests.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,38 @@ module.exports = {
4242
// Fixer adapted from https://github.com/lo1tuma/eslint-plugin-mocha (MIT)
4343
const sourceCode = context.getSourceCode();
4444

45+
/**
46+
* @param {number} start
47+
* @param {number} end
48+
* @returns {string}
49+
*/
4550
function extractSourceTextByRange(start, end) {
4651
return sourceCode.text.slice(start, end).trim();
4752
}
4853

54+
/**
55+
* @param {import('estree').FunctionExpression|import('estree').ArrowFunctionExpression} fn
56+
* @returns {string}
57+
*/
4958
function formatFunctionHead(fn) {
59+
if (
60+
fn.type !== "FunctionExpression" &&
61+
fn.type !== "ArrowFunctionExpression"
62+
) {
63+
return "";
64+
}
5065
const arrow = sourceCode.getTokenBefore(fn.body);
66+
if (!arrow) {
67+
return "";
68+
}
5169
const beforeArrowToken = sourceCode.getTokenBefore(arrow);
70+
if (!beforeArrowToken) {
71+
return "";
72+
}
5273
let firstToken = sourceCode.getFirstToken(fn);
74+
if (!firstToken) {
75+
return "";
76+
}
5377

5478
let functionKeyword = "function";
5579
let params = extractSourceTextByRange(
@@ -68,6 +92,14 @@ module.exports = {
6892
firstToken = sourceCode.getTokenAfter(firstToken);
6993
}
7094

95+
if (!firstToken) {
96+
return "";
97+
}
98+
99+
if (!fn.body.range) {
100+
return "";
101+
}
102+
71103
const beforeArrowComment = extractSourceTextByRange(
72104
beforeArrowToken.range[1],
73105
arrow.range[0],
@@ -84,7 +116,20 @@ module.exports = {
84116
return `${functionKeyword}${paramsFullText} `;
85117
}
86118

119+
/**
120+
* @param {any} fixer
121+
* @param {import('estree').Node} fn
122+
*/
87123
function fixArrowFunction(fixer, fn) {
124+
if (
125+
fn.type !== "FunctionExpression" &&
126+
fn.type !== "ArrowFunctionExpression"
127+
) {
128+
return null;
129+
}
130+
if (!fn.range || !fn.body.range) {
131+
return null;
132+
}
88133
if (fn.body.type === "BlockStatement") {
89134
// When it((...) => { ... }),
90135
// simply replace '(...) => ' with 'function () '
@@ -104,6 +149,9 @@ module.exports = {
104149
);
105150
}
106151

152+
/**
153+
* @param {import('estree').Node} fn
154+
*/
107155
function checkCallback(fn) {
108156
if (fn && fn.type === "ArrowFunctionExpression") {
109157
context.report({
@@ -114,6 +162,10 @@ module.exports = {
114162
}
115163
}
116164

165+
/**
166+
* @param {import('eslint').Rule.Node} propertyNode
167+
* @returns {boolean}
168+
*/
117169
function isPropertyInModule(propertyNode) {
118170
return (
119171
propertyNode &&
@@ -125,8 +177,13 @@ module.exports = {
125177
);
126178
}
127179

180+
/**
181+
* @param {import('eslint').Rule.Node} propertyNode
182+
* @returns {boolean}
183+
*/
128184
function isModuleProperty(propertyNode) {
129185
return (
186+
propertyNode.type === "Property" &&
130187
isPropertyInModule(propertyNode) &&
131188
utils.isModuleHookPropertyKey(propertyNode.key)
132189
);

0 commit comments

Comments
 (0)