Skip to content

Commit 9f3390c

Browse files
committed
Lint and prettier
1 parent 52d4bd9 commit 9f3390c

22 files changed

+310
-66
lines changed

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
.prettierignore
55
LICENSE
66
yarn.lock
7+
dist

package.json

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
"@types/eslint-scope": "^3.7.0",
3737
"@types/eslint-visitor-keys": "^1.0.0",
3838
"@types/jest": "^26.0.23",
39+
"@typescript-eslint/eslint-plugin": "^4.26.0",
40+
"@typescript-eslint/parser": "^4.26.0",
3941
"eslint": "^7.3.1",
4042
"eslint-plugin-eslint-plugin": "^3.0.0",
4143
"husky": "^6.0.0",
@@ -53,15 +55,22 @@
5355
},
5456
"extends": [
5557
"eslint:recommended",
56-
"plugin:eslint-plugin/recommended"
58+
"plugin:eslint-plugin/recommended",
59+
"plugin:@typescript-eslint/recommended"
5760
],
58-
"parserOptions": {
59-
"ecmaVersion": 2015
60-
},
61+
"parser": "@typescript-eslint/parser",
6162
"plugins": [
62-
"eslint-plugin"
63-
]
63+
"eslint-plugin",
64+
"@typescript-eslint"
65+
],
66+
"rules": {
67+
"@typescript-eslint/explicit-module-boundary-types": "off",
68+
"@typescript-eslint/no-explicit-any": "off"
69+
}
6470
},
71+
"eslintIgnore": [
72+
"dist"
73+
],
6574
"husky": {
6675
"hooks": {
6776
"pre-commit": "pretty-quick --staged"

src/rules/__tests__/makeRuleTester.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import type { Rule } from "eslint";
22
import { RuleTester } from "eslint";
33

4-
type ValidCase = string | { code: string, options?: any[] };
5-
type InvalidCase = string | { code: string, options?: any[], errors: any[] };
6-
type Config = { valid: ValidCase[], invalid: InvalidCase[] };
4+
type ValidCase = string | { code: string; options?: any[] };
5+
type InvalidCase = string | { code: string; options?: any[]; errors: any[] };
6+
type Config = { valid: ValidCase[]; invalid: InvalidCase[] };
77

88
const filename = "test.vue";
99
const makeTemplate = (code: string) => `<template>${code}</template>`;

src/rules/alt-text.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ import {
1313
makeDocsURL
1414
} from "../utils";
1515

16-
const ruleByElement: { [key: string]: ((context: Rule.RuleContext, node: AST.VElement) => void) } = {
16+
type ElementRule = (context: Rule.RuleContext, node: AST.VElement) => void;
17+
type RuleByElement = { [key: string]: ElementRule };
18+
19+
const ruleByElement: RuleByElement = {
1720
img(context, node) {
1821
const altAttribute = getElementAttribute(node, "alt");
1922

src/rules/aria-props.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ const rule: Rule.RuleModule = {
2222
const name = getAttributeName(node);
2323
const lowered = name && name.toLowerCase();
2424

25-
if (lowered && lowered.startsWith("aria-") && !aria.has(lowered as any)) {
25+
if (
26+
lowered &&
27+
lowered.startsWith("aria-") &&
28+
!aria.has(lowered as any)
29+
) {
2630
context.report({
2731
node: node as any,
2832
messageId: "default",

src/rules/aria-unsupported-elements.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ const rule: Rule.RuleModule = {
2828
const name = getAttributeName(attribute);
2929

3030
if (name && (aria.has(name as any) || name === "role")) {
31-
context.report({ node: node as any, messageId: "default", data: { name } });
31+
context.report({
32+
node: node as any,
33+
messageId: "default",
34+
data: { name }
35+
});
3236
}
3337
});
3438
}

src/rules/click-events-have-key-events.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
} from "../utils";
1515

1616
// Why can I not import this like normal? Unclear.
17+
// eslint-disable-next-line @typescript-eslint/no-var-requires
1718
const vueEslintParser = require("vue-eslint-parser");
1819

1920
function isHtmlElementNode(node: AST.VElement) {

src/rules/form-control-has-label.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ import {
1010
makeDocsURL
1111
} from "../utils";
1212

13-
function isLabelElement(node: AST.VElement | AST.VDocumentFragment | AST.VText | AST.VExpressionContainer) {
13+
function isLabelElement(
14+
node:
15+
| AST.VElement
16+
| AST.VDocumentFragment
17+
| AST.VText
18+
| AST.VExpressionContainer
19+
) {
1420
return node.type === "VElement" && getElementType(node) === "label";
1521
}
1622

@@ -21,7 +27,7 @@ function hasLabelElement(node: AST.VElement): boolean {
2127
[parent, ...parent.children].some(isLabelElement) ||
2228
(parent && parent.type === "VElement" && hasLabelElement(parent))
2329
);
24-
};
30+
}
2531

2632
const rule: Rule.RuleModule = {
2733
meta: {
@@ -46,7 +52,9 @@ const rule: Rule.RuleModule = {
4652

4753
if (
4854
!type ||
49-
["hidden", "button", "image", "submit", "reset"].includes(type as any)
55+
["hidden", "button", "image", "submit", "reset"].includes(
56+
type as any
57+
)
5058
) {
5159
return;
5260
}

src/rules/interactive-supports-focus.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,10 @@ const interactiveHandlers = [
5454
function isDisabledElement(node: AST.VElement) {
5555
return (
5656
getElementAttributeValue(node, "disabled") ||
57-
(getElementAttributeValue(node, "aria-disabled") || "").toString() === "true"
57+
(getElementAttributeValue(node, "aria-disabled") || "").toString() ===
58+
"true"
5859
);
59-
};
60+
}
6061

6162
function isInteractiveRole(value: any): value is string {
6263
if (typeof value !== "string") {
@@ -66,7 +67,9 @@ function isInteractiveRole(value: any): value is string {
6667
return value
6768
.toLowerCase()
6869
.split(" ")
69-
.some((role) => roles.has(role as any) && interactiveRoles.includes(role as any));
70+
.some(
71+
(role) => roles.has(role as any) && interactiveRoles.includes(role as any)
72+
);
7073
}
7174

7275
function hasTabIndex(node: AST.VElement) {
@@ -142,10 +145,18 @@ const rule: InteractiveSupportsFocus = {
142145

143146
if (tabbable.includes(role)) {
144147
// Always tabbable, tabIndex = 0
145-
context.report({ node: node as any, messageId: "tabbable", data: { role } });
148+
context.report({
149+
node: node as any,
150+
messageId: "tabbable",
151+
data: { role }
152+
});
146153
} else {
147154
// Focusable, tabIndex = -1 or 0
148-
context.report({ node: node as any, messageId: "focusable", data: { role } });
155+
context.report({
156+
node: node as any,
157+
messageId: "focusable",
158+
data: { role }
159+
});
149160
}
150161
}
151162
}

src/rules/label-has-for.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,12 @@ import {
1111
} from "../utils";
1212

1313
type Association = "nesting" | "id";
14-
type Required = (
14+
type Required =
1515
| Association
16-
| { some: Association[], every: undefined }
17-
| { some: undefined, every: Association[] }
18-
);
16+
| { some: Association[]; every: undefined }
17+
| { some: undefined; every: Association[] };
1918

20-
type Options = { allowChildren: boolean, controlComponents: string[] };
19+
type Options = { allowChildren: boolean; controlComponents: string[] };
2120

2221
const controlTypes = ["input", "meter", "progress", "select", "textarea"];
2322

@@ -54,7 +53,11 @@ function validate(node: AST.VElement, rule: Association, options: Options) {
5453
}
5554
}
5655

57-
function isValidLabel(node: AST.VElement, required: Required, options: Options) {
56+
function isValidLabel(
57+
node: AST.VElement,
58+
required: Required,
59+
options: Options
60+
) {
5861
if (typeof required === "string") {
5962
return validate(node, required, options);
6063
}

src/rules/media-has-caption.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ import {
1111
makeKebabCase
1212
} from "../utils";
1313

14-
function isCaptionsTrackElement(node: AST.VElement | AST.VExpressionContainer | AST.VText) {
15-
const kind = node.type === "VElement" && getElementAttributeValue(node, "kind");
14+
function isCaptionsTrackElement(
15+
node: AST.VElement | AST.VExpressionContainer | AST.VText
16+
) {
17+
const kind =
18+
node.type === "VElement" && getElementAttributeValue(node, "kind");
1619

1720
return kind && typeof kind === "string" && kind.toLowerCase() === "captions";
1821
}

src/rules/no-distracting-elements.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ const rule: Rule.RuleModule = {
3838
const elementType = getElementType(node);
3939

4040
if (elements.map(makeKebabCase).includes(elementType)) {
41-
context.report({ node: node as any, messageId: "default", data: { elementType } });
41+
context.report({
42+
node: node as any,
43+
messageId: "default",
44+
data: { elementType }
45+
});
4246
}
4347
}
4448
});

src/rules/role-has-required-aria-props.ts

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ function hasAttributes(node: AST.VElement, names: string[]) {
1414
return names.every((name) => getElementAttribute(node, name) !== null);
1515
}
1616

17+
function isAriaRoleDefinitionKey(role: any): role is ARIARoleDefintionKey {
18+
return roles.has(role);
19+
}
20+
1721
const rule: Rule.RuleModule = {
1822
meta: {
1923
docs: {
@@ -40,23 +44,20 @@ const rule: Rule.RuleModule = {
4044
.toLowerCase()
4145
.split(" ")
4246
.forEach((role) => {
43-
if (!roles.has(role as any)) {
44-
return;
45-
}
46-
47-
const requiredAttributes = Object.keys(
48-
roles.get(role as ARIARoleDefintionKey)!.requiredProps
49-
);
47+
if (isAriaRoleDefinitionKey(role)) {
48+
const roleDefinition = roles.get(role) as any;
49+
const requiredProps = Object.keys(roleDefinition.requiredProps);
5050

51-
if (!hasAttributes(node, requiredAttributes)) {
52-
context.report({
53-
node: node as any,
54-
messageId: "default",
55-
data: {
56-
role: role.toLowerCase(),
57-
attributes: requiredAttributes.join(", ").toLowerCase()
58-
}
59-
});
51+
if (requiredProps && !hasAttributes(node, requiredProps)) {
52+
context.report({
53+
node: node as any,
54+
messageId: "default",
55+
data: {
56+
role: role.toLowerCase(),
57+
attributes: requiredProps.join(", ").toLowerCase()
58+
}
59+
});
60+
}
6061
}
6162
});
6263
}

src/utils/defineTemplateBodyVisitor.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ import type { Rule } from "eslint";
22
import type { AST } from "vue-eslint-parser";
33

44
interface TemplateListener extends Rule.NodeListener {
5-
VAttribute?: ((node: AST.VAttribute) => void);
6-
VElement?: ((node: AST.VElement) => void);
7-
VText?: ((node: AST.VText) => void);
5+
VAttribute?: (node: AST.VAttribute) => void;
6+
VElement?: (node: AST.VElement) => void;
7+
VText?: (node: AST.VText) => void;
88
}
99

1010
// Taken directly from eslint-plugin-vue
11-
function defineTemplateBodyVisitor(context: Rule.RuleContext, templateVisitor: TemplateListener, scriptVisitor?: Rule.RuleListener) {
11+
function defineTemplateBodyVisitor(
12+
context: Rule.RuleContext,
13+
templateVisitor: TemplateListener,
14+
scriptVisitor?: Rule.RuleListener
15+
) {
1216
if (context.parserServices.defineTemplateBodyVisitor === null) {
1317
context.report({
1418
loc: { line: 1, column: 0 },

src/utils/getAttributeName.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ function getAttributeName(node: AST.VAttribute | AST.VDirective) {
66
}
77

88
const { key } = node;
9-
if (key.name.name === "bind" && key.argument && key.argument.type === "VIdentifier") {
9+
if (
10+
key.name.name === "bind" &&
11+
key.argument &&
12+
key.argument.type === "VIdentifier"
13+
) {
1014
return key.argument.name;
1115
}
1216

src/utils/getLiteralAttributeValue.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ import type { AST } from "vue-eslint-parser";
22

33
function getLiteralAttributeValue(node: AST.VElement, name: string) {
44
for (const attribute of node.startTag.attributes) {
5-
if (!attribute.directive && attribute.key.name === name && attribute.value) {
5+
if (
6+
!attribute.directive &&
7+
attribute.key.name === name &&
8+
attribute.value
9+
) {
610
return attribute.value.value;
711
}
812

src/utils/hasAccessibleChild.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import type { AST } from "vue-eslint-parser";
33
import getElementType from "./getElementType";
44
import isHiddenFromScreenReader from "./isHiddenFromScreenReader";
55

6-
function hasAccessibleChild(node: AST.VElement, accessibleChildTypes: string[] = []): boolean {
6+
function hasAccessibleChild(
7+
node: AST.VElement,
8+
accessibleChildTypes: string[] = []
9+
): boolean {
710
return node.children.some((child) => {
811
switch (child.type) {
912
case "VText":

src/utils/hasOnDirective.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@ function hasOnDirective(node: AST.VElement, name: string) {
1010
attribute.key.argument.name === name &&
1111
attribute.value &&
1212
attribute.value.expression &&
13-
(
14-
attribute.value.expression.type === "Identifier" ||
15-
!!(attribute.value.expression as any).body
16-
)
13+
(attribute.value.expression.type === "Identifier" ||
14+
!!(attribute.value.expression as any).body)
1715
);
1816
});
1917
}

src/utils/isAriaHidden.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ function isAriaHidden(node: AST.VDocumentFragment | AST.VElement): boolean {
88
}
99

1010
return isHiddenFromScreenReader(node) || isAriaHidden(node.parent);
11-
};
11+
}
1212

1313
export default isAriaHidden;

src/utils/isAttribute.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ function isAttribute(node: AST.VAttribute | AST.VDirective, name: string) {
88
return (
99
node.key.name.name === "bind" &&
1010
node.key.argument &&
11-
(node.key.argument.type === "VIdentifier" && node.key.argument.name === name)
11+
node.key.argument.type === "VIdentifier" &&
12+
node.key.argument.name === name
1213
);
1314
}
1415

src/utils/matchesElementRole.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import type { ARIARoleRelationConcept } from "aria-query";
44
import getElementType from "./getElementType";
55
import getElementAttributeValue from "./getElementAttributeValue";
66

7-
function matchesElementRole(node: AST.VElement, elementRole: ARIARoleRelationConcept) {
7+
function matchesElementRole(
8+
node: AST.VElement,
9+
elementRole: ARIARoleRelationConcept
10+
) {
811
const { name, attributes } = elementRole;
912
if (name !== getElementType(node)) {
1013
return false;

0 commit comments

Comments
 (0)