@flint.fyi/jsx 0.0.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +20 -0
- package/lib/index.js +1 -2
- package/lib/plugin.d.ts +309 -1
- package/lib/plugin.js +12 -6
- package/lib/rules/accessKeys.d.ts +8 -1
- package/lib/rules/accessKeys.js +2 -3
- package/lib/rules/altTexts.d.ts +8 -1
- package/lib/rules/altTexts.js +6 -16
- package/lib/rules/anchorAmbiguousText.d.ts +8 -1
- package/lib/rules/anchorAmbiguousText.js +2 -5
- package/lib/rules/anchorContent.d.ts +8 -1
- package/lib/rules/anchorContent.js +2 -3
- package/lib/rules/anchorValidity.d.ts +8 -1
- package/lib/rules/anchorValidity.js +4 -5
- package/lib/rules/ariaActiveDescendantTabIndex.d.ts +8 -1
- package/lib/rules/ariaActiveDescendantTabIndex.js +4 -7
- package/lib/rules/ariaHiddenFocusables.d.ts +8 -1
- package/lib/rules/ariaHiddenFocusables.js +7 -9
- package/lib/rules/ariaPropTypes.d.ts +8 -1
- package/lib/rules/ariaPropTypes.js +6 -9
- package/lib/rules/ariaProps.d.ts +8 -1
- package/lib/rules/ariaProps.js +2 -3
- package/lib/rules/ariaRoleValidity.d.ts +8 -1
- package/lib/rules/ariaRoleValidity.js +3 -4
- package/lib/rules/ariaUnsupportedElements.d.ts +8 -1
- package/lib/rules/ariaUnsupportedElements.js +2 -3
- package/lib/rules/autoFocusProps.d.ts +8 -1
- package/lib/rules/autoFocusProps.js +4 -6
- package/lib/rules/autocomplete.d.ts +8 -1
- package/lib/rules/autocomplete.js +3 -4
- package/lib/rules/booleanValues.d.ts +8 -1
- package/lib/rules/booleanValues.js +2 -3
- package/lib/rules/bracedStatements.d.ts +8 -1
- package/lib/rules/bracedStatements.js +1 -2
- package/lib/rules/buttonTypes.d.ts +8 -1
- package/lib/rules/buttonTypes.js +3 -4
- package/lib/rules/childrenProps.d.ts +8 -1
- package/lib/rules/childrenProps.js +1 -2
- package/lib/rules/clickEventKeyEvents.d.ts +8 -1
- package/lib/rules/clickEventKeyEvents.js +2 -3
- package/lib/rules/commentTextNodes.d.ts +8 -1
- package/lib/rules/commentTextNodes.js +2 -3
- package/lib/rules/distractingElements.d.ts +8 -1
- package/lib/rules/distractingElements.js +2 -3
- package/lib/rules/elementChildrenValidity.d.ts +8 -1
- package/lib/rules/elementChildrenValidity.js +1 -2
- package/lib/rules/headingContents.d.ts +8 -1
- package/lib/rules/headingContents.js +5 -6
- package/lib/rules/htmlLangs.d.ts +8 -1
- package/lib/rules/htmlLangs.js +2 -3
- package/lib/rules/iframeTitles.d.ts +8 -1
- package/lib/rules/iframeTitles.js +3 -4
- package/lib/rules/interactiveElementRoles.d.ts +8 -1
- package/lib/rules/interactiveElementRoles.js +3 -4
- package/lib/rules/interactiveElementsFocusable.d.ts +8 -1
- package/lib/rules/interactiveElementsFocusable.js +7 -8
- package/lib/rules/labelAssociatedControls.d.ts +8 -1
- package/lib/rules/labelAssociatedControls.js +6 -7
- package/lib/rules/langValidity.d.ts +8 -1
- package/lib/rules/langValidity.js +1 -2
- package/lib/rules/mediaCaptions.d.ts +8 -1
- package/lib/rules/mediaCaptions.js +12 -13
- package/lib/rules/mouseEventKeyEvents.d.ts +8 -1
- package/lib/rules/mouseEventKeyEvents.js +2 -3
- package/lib/rules/nonInteractiveElementInteractions.d.ts +8 -1
- package/lib/rules/nonInteractiveElementInteractions.js +3 -4
- package/lib/rules/nonInteractiveElementRoles.d.ts +8 -1
- package/lib/rules/nonInteractiveElementRoles.js +3 -4
- package/lib/rules/nonInteractiveElementTabIndexes.d.ts +8 -1
- package/lib/rules/nonInteractiveElementTabIndexes.js +7 -8
- package/lib/rules/propDuplicates.d.ts +8 -1
- package/lib/rules/propDuplicates.js +2 -3
- package/lib/rules/roleRedundancies.d.ts +8 -1
- package/lib/rules/roleRedundancies.js +3 -4
- package/lib/rules/roleRequiredAriaProps.d.ts +8 -1
- package/lib/rules/roleRequiredAriaProps.js +3 -4
- package/lib/rules/roleSupportedAriaProps.d.ts +8 -1
- package/lib/rules/roleSupportedAriaProps.js +3 -4
- package/lib/rules/roleTags.d.ts +8 -1
- package/lib/rules/roleTags.js +2 -3
- package/lib/rules/ruleCreator.js +1 -2
- package/lib/rules/scopeProps.d.ts +8 -1
- package/lib/rules/scopeProps.js +2 -3
- package/lib/rules/staticElementInteractions.d.ts +8 -1
- package/lib/rules/staticElementInteractions.js +2 -3
- package/lib/rules/svgTitles.d.ts +8 -1
- package/lib/rules/svgTitles.js +5 -6
- package/lib/rules/tabIndexPositiveValues.d.ts +8 -1
- package/lib/rules/tabIndexPositiveValues.js +4 -5
- package/lib/rules/unescapedEntities.d.ts +8 -1
- package/lib/rules/unescapedEntities.js +1 -2
- package/lib/rules/unnecessaryFragments.d.ts +8 -1
- package/lib/rules/unnecessaryFragments.js +3 -4
- package/package.json +46 -51
- package/lib/jsx.d.ts +0 -8
- package/lib/jsx.js +0 -100
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { ruleCreator } from "./ruleCreator.js";
|
|
2
2
|
import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
|
|
3
3
|
import { SyntaxKind } from "typescript";
|
|
4
|
-
|
|
5
4
|
//#region src/rules/anchorValidity.ts
|
|
6
5
|
var anchorValidity_default = ruleCreator.createRule(typescriptLanguage, {
|
|
7
6
|
about: {
|
|
8
7
|
description: "Reports invalid usage of anchor elements.",
|
|
9
8
|
id: "anchorValidity",
|
|
10
|
-
presets: ["logical"]
|
|
9
|
+
presets: ["logical", "logicalStrict"]
|
|
11
10
|
},
|
|
12
11
|
messages: {
|
|
13
12
|
invalidHref: {
|
|
@@ -41,8 +40,8 @@ var anchorValidity_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
41
40
|
setup(context) {
|
|
42
41
|
function getHrefValue(attributes) {
|
|
43
42
|
const hrefProperty = attributes.properties.find((property) => property.kind === SyntaxKind.JsxAttribute && property.name.kind === SyntaxKind.Identifier && property.name.text === "href");
|
|
44
|
-
if (
|
|
45
|
-
if (hrefProperty.initializer
|
|
43
|
+
if (hrefProperty?.kind !== SyntaxKind.JsxAttribute) return;
|
|
44
|
+
if (hrefProperty.initializer?.kind === SyntaxKind.StringLiteral) return hrefProperty.initializer.text;
|
|
46
45
|
return "";
|
|
47
46
|
}
|
|
48
47
|
function hasOnClick(attributes) {
|
|
@@ -74,7 +73,7 @@ var anchorValidity_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
74
73
|
} };
|
|
75
74
|
}
|
|
76
75
|
});
|
|
77
|
-
|
|
78
76
|
//#endregion
|
|
79
77
|
export { anchorValidity_default as default };
|
|
78
|
+
|
|
80
79
|
//# sourceMappingURL=anchorValidity.js.map
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
declare const _default: import("@flint.fyi/core").Rule<
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports elements with aria-activedescendant without tabIndex.";
|
|
3
|
+
readonly id: "ariaActiveDescendantTabIndex";
|
|
4
|
+
readonly presets: ["logical", "logicalStrict"];
|
|
5
|
+
} & {
|
|
6
|
+
presets?: ("logical" | "logicalStrict" | "stylistic")[];
|
|
7
|
+
url: string;
|
|
8
|
+
}, object, object, "missingTabIndex", import("@flint.fyi/core").AnyOptionalSchema>;
|
|
2
9
|
export default _default;
|
|
3
10
|
//# sourceMappingURL=ariaActiveDescendantTabIndex.d.ts.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ruleCreator } from "./ruleCreator.js";
|
|
2
2
|
import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
|
|
3
3
|
import { SyntaxKind } from "typescript";
|
|
4
|
-
|
|
5
4
|
//#region src/rules/ariaActiveDescendantTabIndex.ts
|
|
6
5
|
const inherentlyTabbableElements = new Set([
|
|
7
6
|
"a",
|
|
@@ -15,7 +14,7 @@ var ariaActiveDescendantTabIndex_default = ruleCreator.createRule(typescriptLang
|
|
|
15
14
|
about: {
|
|
16
15
|
description: "Reports elements with aria-activedescendant without tabIndex.",
|
|
17
16
|
id: "ariaActiveDescendantTabIndex",
|
|
18
|
-
presets: ["logical"]
|
|
17
|
+
presets: ["logical", "logicalStrict"]
|
|
19
18
|
},
|
|
20
19
|
messages: { missingTabIndex: {
|
|
21
20
|
primary: "This element with `aria-activedescendant` is missing a `tabIndex` attribute to manage focus state.",
|
|
@@ -33,12 +32,10 @@ var ariaActiveDescendantTabIndex_default = ruleCreator.createRule(typescriptLang
|
|
|
33
32
|
if (firstCharacter === firstCharacter.toUpperCase() && firstCharacter !== firstCharacter.toLowerCase()) return;
|
|
34
33
|
}
|
|
35
34
|
if (!attributes.properties.some((property) => property.kind === SyntaxKind.JsxAttribute && property.name.kind === SyntaxKind.Identifier && property.name.text === "aria-activedescendant" && property.initializer)) return;
|
|
36
|
-
if (tagName.kind === SyntaxKind.Identifier)
|
|
37
|
-
if (inherentlyTabbableElements.has(tagName.text.toLowerCase())) return;
|
|
38
|
-
}
|
|
35
|
+
if (tagName.kind === SyntaxKind.Identifier && inherentlyTabbableElements.has(tagName.text.toLowerCase())) return;
|
|
39
36
|
if (!attributes.properties.some((property) => property.kind === SyntaxKind.JsxAttribute && property.name.kind === SyntaxKind.Identifier && property.name.text.toLowerCase() === "tabindex")) {
|
|
40
37
|
const ariaProperty = attributes.properties.find((property) => property.kind === SyntaxKind.JsxAttribute && property.name.kind === SyntaxKind.Identifier && property.name.text === "aria-activedescendant");
|
|
41
|
-
if (ariaProperty
|
|
38
|
+
if (ariaProperty?.kind === SyntaxKind.JsxAttribute) context.report({
|
|
42
39
|
message: "missingTabIndex",
|
|
43
40
|
range: getTSNodeRange(ariaProperty, sourceFile)
|
|
44
41
|
});
|
|
@@ -50,7 +47,7 @@ var ariaActiveDescendantTabIndex_default = ruleCreator.createRule(typescriptLang
|
|
|
50
47
|
} };
|
|
51
48
|
}
|
|
52
49
|
});
|
|
53
|
-
|
|
54
50
|
//#endregion
|
|
55
51
|
export { ariaActiveDescendantTabIndex_default as default };
|
|
52
|
+
|
|
56
53
|
//# sourceMappingURL=ariaActiveDescendantTabIndex.js.map
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
declare const _default: import("@flint.fyi/core").Rule<
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports elements with aria-hidden='true' that are focusable.";
|
|
3
|
+
readonly id: "ariaHiddenFocusables";
|
|
4
|
+
readonly presets: ["logical", "logicalStrict"];
|
|
5
|
+
} & {
|
|
6
|
+
presets?: ("logical" | "logicalStrict" | "stylistic")[];
|
|
7
|
+
url: string;
|
|
8
|
+
}, object, object, "ariaHiddenFocusable", import("@flint.fyi/core").AnyOptionalSchema>;
|
|
2
9
|
export default _default;
|
|
3
10
|
//# sourceMappingURL=ariaHiddenFocusables.d.ts.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ruleCreator } from "./ruleCreator.js";
|
|
2
2
|
import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
|
|
3
3
|
import { SyntaxKind } from "typescript";
|
|
4
|
-
|
|
5
4
|
//#region src/rules/ariaHiddenFocusables.ts
|
|
6
5
|
const focusableElements = new Set([
|
|
7
6
|
"a",
|
|
@@ -32,7 +31,7 @@ var ariaHiddenFocusables_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
32
31
|
const { attributes, tagName } = node;
|
|
33
32
|
if (tagName.kind !== SyntaxKind.Identifier) return;
|
|
34
33
|
const ariaHiddenProperty = attributes.properties.find((property) => property.kind === SyntaxKind.JsxAttribute && property.name.kind === SyntaxKind.Identifier && property.name.text.toLowerCase() === "aria-hidden");
|
|
35
|
-
if (
|
|
34
|
+
if (ariaHiddenProperty?.kind !== SyntaxKind.JsxAttribute || !isAriaHiddenTrue(ariaHiddenProperty)) return;
|
|
36
35
|
const tabIndexValue = findTabIndexValue(node);
|
|
37
36
|
if (tabIndexValue === -1) return;
|
|
38
37
|
if (focusableElements.has(tagName.text.toLowerCase()) || tabIndexValue !== void 0 && tabIndexValue >= 0) context.report({
|
|
@@ -47,24 +46,23 @@ var ariaHiddenFocusables_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
47
46
|
}
|
|
48
47
|
});
|
|
49
48
|
function findTabIndexValue(node) {
|
|
50
|
-
const tabIndexProperty = node.attributes.properties.find((property) => property.kind
|
|
49
|
+
const tabIndexProperty = node.attributes.properties.find((property) => property.kind === SyntaxKind.JsxAttribute && property.name.kind === SyntaxKind.Identifier && property.name.text.toLowerCase() === "tabindex");
|
|
51
50
|
if (!tabIndexProperty?.initializer) return;
|
|
52
|
-
if (tabIndexProperty.initializer.kind
|
|
51
|
+
if (tabIndexProperty.initializer.kind === SyntaxKind.JsxExpression) {
|
|
53
52
|
const expression = tabIndexProperty.initializer.expression;
|
|
54
|
-
if (expression
|
|
53
|
+
if (expression?.kind === SyntaxKind.NumericLiteral) return Number(expression.text);
|
|
55
54
|
}
|
|
56
|
-
if (tabIndexProperty.initializer.kind
|
|
55
|
+
if (tabIndexProperty.initializer.kind === SyntaxKind.StringLiteral) return Number(tabIndexProperty.initializer.text);
|
|
57
56
|
}
|
|
58
57
|
function isAriaHiddenTrue(ariaHiddenProperty) {
|
|
59
58
|
if (!ariaHiddenProperty.initializer) return false;
|
|
60
59
|
if (ariaHiddenProperty.initializer.kind === SyntaxKind.StringLiteral) return ariaHiddenProperty.initializer.text === "true";
|
|
61
60
|
if (ariaHiddenProperty.initializer.kind === SyntaxKind.JsxExpression) {
|
|
62
|
-
|
|
63
|
-
if (expression && expression.kind === SyntaxKind.TrueKeyword) return true;
|
|
61
|
+
if (ariaHiddenProperty.initializer.expression?.kind === SyntaxKind.TrueKeyword) return true;
|
|
64
62
|
}
|
|
65
63
|
return false;
|
|
66
64
|
}
|
|
67
|
-
|
|
68
65
|
//#endregion
|
|
69
66
|
export { ariaHiddenFocusables_default as default };
|
|
67
|
+
|
|
70
68
|
//# sourceMappingURL=ariaHiddenFocusables.js.map
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
declare const _default: import("@flint.fyi/core").Rule<
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports ARIA properties with invalid value types.";
|
|
3
|
+
readonly id: "ariaPropTypes";
|
|
4
|
+
readonly presets: ["logical", "logicalStrict"];
|
|
5
|
+
} & {
|
|
6
|
+
presets?: ("logical" | "logicalStrict" | "stylistic")[];
|
|
7
|
+
url: string;
|
|
8
|
+
}, object, object, "invalidPropType", import("@flint.fyi/core").AnyOptionalSchema>;
|
|
2
9
|
export default _default;
|
|
3
10
|
//# sourceMappingURL=ariaPropTypes.d.ts.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ruleCreator } from "./ruleCreator.js";
|
|
2
2
|
import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
|
|
3
3
|
import { SyntaxKind } from "typescript";
|
|
4
|
-
|
|
5
4
|
//#region src/rules/ariaPropTypes.ts
|
|
6
5
|
const ariaPropertyTypes = {
|
|
7
6
|
"aria-activedescendant": "id",
|
|
@@ -152,8 +151,8 @@ function isValidPropertyValue(propertyName, value, expectedType) {
|
|
|
152
151
|
if (value === void 0) return true;
|
|
153
152
|
switch (expectedType) {
|
|
154
153
|
case "boolean": return value === "true" || value === "false" || typeof value === "boolean";
|
|
155
|
-
case "id": return typeof value === "string" && value.length
|
|
156
|
-
case "idlist": return typeof value === "string" && value.trim().length
|
|
154
|
+
case "id": return typeof value === "string" && !!value.length;
|
|
155
|
+
case "idlist": return typeof value === "string" && !!value.trim().length;
|
|
157
156
|
case "integer":
|
|
158
157
|
if (typeof value === "number") return Number.isInteger(value);
|
|
159
158
|
if (typeof value === "string") {
|
|
@@ -169,11 +168,9 @@ function isValidPropertyValue(propertyName, value, expectedType) {
|
|
|
169
168
|
}
|
|
170
169
|
return false;
|
|
171
170
|
case "string": return typeof value === "string";
|
|
172
|
-
case "token":
|
|
171
|
+
case "token":
|
|
173
172
|
if (typeof value !== "string") return false;
|
|
174
|
-
|
|
175
|
-
return validTokens !== void 0 ? validTokens.has(value.toLowerCase()) : true;
|
|
176
|
-
}
|
|
173
|
+
return tokenValues[propertyName]?.has(value.toLowerCase()) ?? true;
|
|
177
174
|
case "tristate": return value === "true" || value === "false" || value === "mixed" || typeof value === "boolean";
|
|
178
175
|
default: return true;
|
|
179
176
|
}
|
|
@@ -182,7 +179,7 @@ var ariaPropTypes_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
182
179
|
about: {
|
|
183
180
|
description: "Reports ARIA properties with invalid value types.",
|
|
184
181
|
id: "ariaPropTypes",
|
|
185
|
-
presets: ["logical"]
|
|
182
|
+
presets: ["logical", "logicalStrict"]
|
|
186
183
|
},
|
|
187
184
|
messages: { invalidPropType: {
|
|
188
185
|
primary: "`{{ prop }}` should have a value of {{ expected }}, but received `{{ actual }}`.",
|
|
@@ -221,7 +218,7 @@ var ariaPropTypes_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
221
218
|
} };
|
|
222
219
|
}
|
|
223
220
|
});
|
|
224
|
-
|
|
225
221
|
//#endregion
|
|
226
222
|
export { ariaPropTypes_default as default };
|
|
223
|
+
|
|
227
224
|
//# sourceMappingURL=ariaPropTypes.js.map
|
package/lib/rules/ariaProps.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
declare const _default: import("@flint.fyi/core").Rule<
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports invalid ARIA properties.";
|
|
3
|
+
readonly id: "ariaProps";
|
|
4
|
+
readonly presets: ["logical", "logicalStrict"];
|
|
5
|
+
} & {
|
|
6
|
+
presets?: ("logical" | "logicalStrict" | "stylistic")[];
|
|
7
|
+
url: string;
|
|
8
|
+
}, object, object, "invalidAriaProp", import("@flint.fyi/core").AnyOptionalSchema>;
|
|
2
9
|
export default _default;
|
|
3
10
|
//# sourceMappingURL=ariaProps.d.ts.map
|
package/lib/rules/ariaProps.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ruleCreator } from "./ruleCreator.js";
|
|
2
2
|
import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
|
|
3
3
|
import { SyntaxKind } from "typescript";
|
|
4
|
-
|
|
5
4
|
//#region src/rules/ariaProps.ts
|
|
6
5
|
const validAriaProps = new Set([
|
|
7
6
|
"aria-activedescendant",
|
|
@@ -57,7 +56,7 @@ var ariaProps_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
57
56
|
about: {
|
|
58
57
|
description: "Reports invalid ARIA properties.",
|
|
59
58
|
id: "ariaProps",
|
|
60
|
-
presets: ["logical"]
|
|
59
|
+
presets: ["logical", "logicalStrict"]
|
|
61
60
|
},
|
|
62
61
|
messages: { invalidAriaProp: {
|
|
63
62
|
primary: "`{{ prop }}` is not a valid ARIA property and so has no effect on the browser.",
|
|
@@ -87,7 +86,7 @@ var ariaProps_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
87
86
|
} };
|
|
88
87
|
}
|
|
89
88
|
});
|
|
90
|
-
|
|
91
89
|
//#endregion
|
|
92
90
|
export { ariaProps_default as default };
|
|
91
|
+
|
|
93
92
|
//# sourceMappingURL=ariaProps.js.map
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
declare const _default: import("@flint.fyi/core").Rule<
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports invalid or abstract ARIA roles.";
|
|
3
|
+
readonly id: "ariaRoleValidity";
|
|
4
|
+
readonly presets: ["logical", "logicalStrict"];
|
|
5
|
+
} & {
|
|
6
|
+
presets?: ("logical" | "logicalStrict" | "stylistic")[];
|
|
7
|
+
url: string;
|
|
8
|
+
}, object, object, "invalidRole", import("@flint.fyi/core").AnyOptionalSchema>;
|
|
2
9
|
export default _default;
|
|
3
10
|
//# sourceMappingURL=ariaRoleValidity.d.ts.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ruleCreator } from "./ruleCreator.js";
|
|
2
2
|
import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
|
|
3
3
|
import { SyntaxKind } from "typescript";
|
|
4
|
-
|
|
5
4
|
//#region src/rules/ariaRoleValidity.ts
|
|
6
5
|
const validAriaRoles = new Set([
|
|
7
6
|
"alert",
|
|
@@ -79,7 +78,7 @@ var ariaRoleValidity_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
79
78
|
about: {
|
|
80
79
|
description: "Reports invalid or abstract ARIA roles.",
|
|
81
80
|
id: "ariaRoleValidity",
|
|
82
|
-
presets: ["logical"]
|
|
81
|
+
presets: ["logical", "logicalStrict"]
|
|
83
82
|
},
|
|
84
83
|
messages: { invalidRole: {
|
|
85
84
|
primary: "Invalid ARIA role '{{ role }}'. Use a valid, non-abstract role.",
|
|
@@ -94,7 +93,7 @@ var ariaRoleValidity_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
94
93
|
function checkRole(node, { sourceFile }) {
|
|
95
94
|
if (node.tagName.kind !== SyntaxKind.Identifier || node.tagName.text.toLowerCase() !== node.tagName.text) return;
|
|
96
95
|
const roleProperty = node.attributes.properties.find((property) => property.kind === SyntaxKind.JsxAttribute && property.name.kind === SyntaxKind.Identifier);
|
|
97
|
-
if (
|
|
96
|
+
if (roleProperty?.initializer?.kind !== SyntaxKind.StringLiteral) return;
|
|
98
97
|
const role = roleProperty.initializer.text.trim();
|
|
99
98
|
if (!role || !validAriaRoles.has(role)) context.report({
|
|
100
99
|
data: { role: role || "(empty)" },
|
|
@@ -108,7 +107,7 @@ var ariaRoleValidity_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
108
107
|
} };
|
|
109
108
|
}
|
|
110
109
|
});
|
|
111
|
-
|
|
112
110
|
//#endregion
|
|
113
111
|
export { ariaRoleValidity_default as default };
|
|
112
|
+
|
|
114
113
|
//# sourceMappingURL=ariaRoleValidity.js.map
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
declare const _default: import("@flint.fyi/core").Rule<
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports ARIA attributes on elements that don't support them.";
|
|
3
|
+
readonly id: "ariaUnsupportedElements";
|
|
4
|
+
readonly presets: ["logical", "logicalStrict"];
|
|
5
|
+
} & {
|
|
6
|
+
presets?: ("logical" | "logicalStrict" | "stylistic")[];
|
|
7
|
+
url: string;
|
|
8
|
+
}, object, object, "unsupportedElement", import("@flint.fyi/core").AnyOptionalSchema>;
|
|
2
9
|
export default _default;
|
|
3
10
|
//# sourceMappingURL=ariaUnsupportedElements.d.ts.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ruleCreator } from "./ruleCreator.js";
|
|
2
2
|
import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
|
|
3
3
|
import { SyntaxKind } from "typescript";
|
|
4
|
-
|
|
5
4
|
//#region src/rules/ariaUnsupportedElements.ts
|
|
6
5
|
const unsupportedElements = new Set([
|
|
7
6
|
"base",
|
|
@@ -51,7 +50,7 @@ var ariaUnsupportedElements_default = ruleCreator.createRule(typescriptLanguage,
|
|
|
51
50
|
about: {
|
|
52
51
|
description: "Reports ARIA attributes on elements that don't support them.",
|
|
53
52
|
id: "ariaUnsupportedElements",
|
|
54
|
-
presets: ["logical"]
|
|
53
|
+
presets: ["logical", "logicalStrict"]
|
|
55
54
|
},
|
|
56
55
|
messages: { unsupportedElement: {
|
|
57
56
|
primary: "The `{{ element }}` element does not support ARIA roles, states, or properties.",
|
|
@@ -83,7 +82,7 @@ var ariaUnsupportedElements_default = ruleCreator.createRule(typescriptLanguage,
|
|
|
83
82
|
} };
|
|
84
83
|
}
|
|
85
84
|
});
|
|
86
|
-
|
|
87
85
|
//#endregion
|
|
88
86
|
export { ariaUnsupportedElements_default as default };
|
|
87
|
+
|
|
89
88
|
//# sourceMappingURL=ariaUnsupportedElements.js.map
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
declare const _default: import("@flint.fyi/core").Rule<
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports autoFocus props that are not set to false.";
|
|
3
|
+
readonly id: "autoFocusProps";
|
|
4
|
+
readonly presets: ["logical", "logicalStrict"];
|
|
5
|
+
} & {
|
|
6
|
+
presets?: ("logical" | "logicalStrict" | "stylistic")[];
|
|
7
|
+
url: string;
|
|
8
|
+
}, object, object, "noAutoFocus", import("@flint.fyi/core").AnyOptionalSchema>;
|
|
2
9
|
export default _default;
|
|
3
10
|
//# sourceMappingURL=autoFocusProps.d.ts.map
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { ruleCreator } from "./ruleCreator.js";
|
|
2
2
|
import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
|
|
3
3
|
import { SyntaxKind } from "typescript";
|
|
4
|
-
|
|
5
4
|
//#region src/rules/autoFocusProps.ts
|
|
6
5
|
var autoFocusProps_default = ruleCreator.createRule(typescriptLanguage, {
|
|
7
6
|
about: {
|
|
8
7
|
description: "Reports autoFocus props that are not set to false.",
|
|
9
8
|
id: "autoFocusProps",
|
|
10
|
-
presets: ["logical"]
|
|
9
|
+
presets: ["logical", "logicalStrict"]
|
|
11
10
|
},
|
|
12
11
|
messages: { noAutoFocus: {
|
|
13
12
|
primary: "The `autoFocus` prop disruptively forces unintuitive focus behavior.",
|
|
@@ -21,10 +20,9 @@ var autoFocusProps_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
21
20
|
setup(context) {
|
|
22
21
|
function isSetToFalse(property) {
|
|
23
22
|
if (!property.initializer) return false;
|
|
24
|
-
if (property.initializer.kind === SyntaxKind.StringLiteral) return
|
|
23
|
+
if (property.initializer.kind === SyntaxKind.StringLiteral) return true;
|
|
25
24
|
if (property.initializer.kind === SyntaxKind.JsxExpression) {
|
|
26
|
-
|
|
27
|
-
if (expr && expr.kind === SyntaxKind.FalseKeyword) return true;
|
|
25
|
+
if (property.initializer.expression?.kind === SyntaxKind.FalseKeyword) return true;
|
|
28
26
|
}
|
|
29
27
|
return false;
|
|
30
28
|
}
|
|
@@ -40,7 +38,7 @@ var autoFocusProps_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
40
38
|
} };
|
|
41
39
|
}
|
|
42
40
|
});
|
|
43
|
-
|
|
44
41
|
//#endregion
|
|
45
42
|
export { autoFocusProps_default as default };
|
|
43
|
+
|
|
46
44
|
//# sourceMappingURL=autoFocusProps.js.map
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
declare const _default: import("@flint.fyi/core").Rule<
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Ensure the autocomplete attribute is correct and suitable for the form field.";
|
|
3
|
+
readonly id: "autocomplete";
|
|
4
|
+
readonly presets: ["logical", "logicalStrict"];
|
|
5
|
+
} & {
|
|
6
|
+
presets?: ("logical" | "logicalStrict" | "stylistic")[];
|
|
7
|
+
url: string;
|
|
8
|
+
}, object, object, "invalid", import("@flint.fyi/core").AnyOptionalSchema>;
|
|
2
9
|
export default _default;
|
|
3
10
|
//# sourceMappingURL=autocomplete.d.ts.map
|
|
@@ -2,7 +2,6 @@ import { ruleCreator } from "./ruleCreator.js";
|
|
|
2
2
|
import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
|
|
3
3
|
import { SyntaxKind } from "typescript";
|
|
4
4
|
import { nullThrows } from "@flint.fyi/utils";
|
|
5
|
-
|
|
6
5
|
//#region src/rules/autocomplete.ts
|
|
7
6
|
const validAutocompleteValues = new Set([
|
|
8
7
|
"address-level1",
|
|
@@ -81,7 +80,7 @@ var autocomplete_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
81
80
|
about: {
|
|
82
81
|
description: "Ensure the autocomplete attribute is correct and suitable for the form field.",
|
|
83
82
|
id: "autocomplete",
|
|
84
|
-
presets: ["logical"]
|
|
83
|
+
presets: ["logical", "logicalStrict"]
|
|
85
84
|
},
|
|
86
85
|
messages: { invalid: {
|
|
87
86
|
primary: "`{{ value }}` is not a valid value for autocomplete.",
|
|
@@ -102,7 +101,7 @@ var autocomplete_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
102
101
|
if (tagName.kind !== SyntaxKind.Identifier) return;
|
|
103
102
|
if (tagName.text.toLowerCase() !== "input") return;
|
|
104
103
|
const autocomplete = attributes.properties.find((property) => property.kind === SyntaxKind.JsxAttribute && property.name.kind === SyntaxKind.Identifier && property.name.text.toLowerCase() === "autocomplete");
|
|
105
|
-
if (
|
|
104
|
+
if (autocomplete?.kind !== SyntaxKind.JsxAttribute || !autocomplete.initializer) return;
|
|
106
105
|
const value = getStringLiteralValue(autocomplete.initializer);
|
|
107
106
|
if (value === void 0 || isValidAutocompleteValue(value)) return;
|
|
108
107
|
context.report({
|
|
@@ -121,7 +120,7 @@ function getStringLiteralValue(node) {
|
|
|
121
120
|
if (node.kind === SyntaxKind.StringLiteral) return node.text;
|
|
122
121
|
if (node.kind === SyntaxKind.NoSubstitutionTemplateLiteral && node.parent.kind !== SyntaxKind.TaggedTemplateExpression) return node.text;
|
|
123
122
|
}
|
|
124
|
-
|
|
125
123
|
//#endregion
|
|
126
124
|
export { autocomplete_default as default };
|
|
125
|
+
|
|
127
126
|
//# sourceMappingURL=autocomplete.js.map
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
declare const _default: import("@flint.fyi/core").Rule<
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Prefer shorthand boolean attributes over explicit {true} values in JSX.";
|
|
3
|
+
readonly id: "booleanValues";
|
|
4
|
+
readonly presets: ["stylistic"];
|
|
5
|
+
} & {
|
|
6
|
+
presets?: ("logical" | "logicalStrict" | "stylistic")[];
|
|
7
|
+
url: string;
|
|
8
|
+
}, object, object, "preferShorthand", import("@flint.fyi/core").AnyOptionalSchema>;
|
|
2
9
|
export default _default;
|
|
3
10
|
//# sourceMappingURL=booleanValues.d.ts.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ruleCreator } from "./ruleCreator.js";
|
|
2
2
|
import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
|
|
3
3
|
import { SyntaxKind } from "typescript";
|
|
4
|
-
|
|
5
4
|
//#region src/rules/booleanValues.ts
|
|
6
5
|
var booleanValues_default = ruleCreator.createRule(typescriptLanguage, {
|
|
7
6
|
about: {
|
|
@@ -16,7 +15,7 @@ var booleanValues_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
16
15
|
} },
|
|
17
16
|
setup(context) {
|
|
18
17
|
function checkElement(node, { sourceFile }) {
|
|
19
|
-
for (const property of node.attributes.properties) if (property.kind === SyntaxKind.JsxAttribute && property.name.kind === SyntaxKind.Identifier && property.initializer
|
|
18
|
+
for (const property of node.attributes.properties) if (property.kind === SyntaxKind.JsxAttribute && property.name.kind === SyntaxKind.Identifier && property.initializer?.kind === SyntaxKind.JsxExpression && property.initializer.expression?.kind === SyntaxKind.TrueKeyword) context.report({
|
|
20
19
|
data: { name: property.name.text },
|
|
21
20
|
message: "preferShorthand",
|
|
22
21
|
range: getTSNodeRange(property, sourceFile)
|
|
@@ -28,7 +27,7 @@ var booleanValues_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
28
27
|
} };
|
|
29
28
|
}
|
|
30
29
|
});
|
|
31
|
-
|
|
32
30
|
//#endregion
|
|
33
31
|
export { booleanValues_default as default };
|
|
32
|
+
|
|
34
33
|
//# sourceMappingURL=booleanValues.js.map
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
declare const _default: import("@flint.fyi/core").Rule<
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Disallow unnecessary JSX curly braces around literals and JSX elements.";
|
|
3
|
+
readonly id: "bracedStatements";
|
|
4
|
+
readonly presets: ["stylistic"];
|
|
5
|
+
} & {
|
|
6
|
+
presets?: ("logical" | "logicalStrict" | "stylistic")[];
|
|
7
|
+
url: string;
|
|
8
|
+
}, object, object, "unnecessaryBraces", import("@flint.fyi/core").AnyOptionalSchema>;
|
|
2
9
|
export default _default;
|
|
3
10
|
//# sourceMappingURL=bracedStatements.d.ts.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ruleCreator } from "./ruleCreator.js";
|
|
2
2
|
import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
|
|
3
3
|
import { SyntaxKind } from "typescript";
|
|
4
|
-
|
|
5
4
|
//#region src/rules/bracedStatements.ts
|
|
6
5
|
var bracedStatements_default = ruleCreator.createRule(typescriptLanguage, {
|
|
7
6
|
about: {
|
|
@@ -28,7 +27,7 @@ var bracedStatements_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
28
27
|
} } };
|
|
29
28
|
}
|
|
30
29
|
});
|
|
31
|
-
|
|
32
30
|
//#endregion
|
|
33
31
|
export { bracedStatements_default as default };
|
|
32
|
+
|
|
34
33
|
//# sourceMappingURL=bracedStatements.js.map
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
declare const _default: import("@flint.fyi/core").Rule<
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports button elements without an explicit type attribute.";
|
|
3
|
+
readonly id: "buttonTypes";
|
|
4
|
+
readonly presets: ["logical", "logicalStrict"];
|
|
5
|
+
} & {
|
|
6
|
+
presets?: ("logical" | "logicalStrict" | "stylistic")[];
|
|
7
|
+
url: string;
|
|
8
|
+
}, object, object, "invalidType" | "missingType", import("@flint.fyi/core").AnyOptionalSchema>;
|
|
2
9
|
export default _default;
|
|
3
10
|
//# sourceMappingURL=buttonTypes.d.ts.map
|
package/lib/rules/buttonTypes.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ruleCreator } from "./ruleCreator.js";
|
|
2
2
|
import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
|
|
3
3
|
import { SyntaxKind } from "typescript";
|
|
4
|
-
|
|
5
4
|
//#region src/rules/buttonTypes.ts
|
|
6
5
|
const validButtonTypes = new Set([
|
|
7
6
|
"button",
|
|
@@ -12,7 +11,7 @@ var buttonTypes_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
12
11
|
about: {
|
|
13
12
|
description: "Reports button elements without an explicit type attribute.",
|
|
14
13
|
id: "buttonTypes",
|
|
15
|
-
presets: ["logical"]
|
|
14
|
+
presets: ["logical", "logicalStrict"]
|
|
16
15
|
},
|
|
17
16
|
messages: {
|
|
18
17
|
invalidType: {
|
|
@@ -68,10 +67,10 @@ function getTypeValue(attribute) {
|
|
|
68
67
|
if (attribute.initializer.kind === SyntaxKind.StringLiteral) return attribute.initializer.text;
|
|
69
68
|
if (attribute.initializer.kind === SyntaxKind.JsxExpression) {
|
|
70
69
|
const expr = attribute.initializer.expression;
|
|
71
|
-
if (expr
|
|
70
|
+
if (expr?.kind === SyntaxKind.StringLiteral) return expr.text;
|
|
72
71
|
}
|
|
73
72
|
}
|
|
74
|
-
|
|
75
73
|
//#endregion
|
|
76
74
|
export { buttonTypes_default as default };
|
|
75
|
+
|
|
77
76
|
//# sourceMappingURL=buttonTypes.js.map
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
declare const _default: import("@flint.fyi/core").Rule<
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports usage of the children prop.";
|
|
3
|
+
readonly id: "childrenProps";
|
|
4
|
+
readonly presets: ["stylistic"];
|
|
5
|
+
} & {
|
|
6
|
+
presets?: ("logical" | "logicalStrict" | "stylistic")[];
|
|
7
|
+
url: string;
|
|
8
|
+
}, object, object, "noChildrenProp", import("@flint.fyi/core").AnyOptionalSchema>;
|
|
2
9
|
export default _default;
|
|
3
10
|
//# sourceMappingURL=childrenProps.d.ts.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ruleCreator } from "./ruleCreator.js";
|
|
2
2
|
import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
|
|
3
3
|
import { SyntaxKind } from "typescript";
|
|
4
|
-
|
|
5
4
|
//#region src/rules/childrenProps.ts
|
|
6
5
|
var childrenProps_default = ruleCreator.createRule(typescriptLanguage, {
|
|
7
6
|
about: {
|
|
@@ -34,7 +33,7 @@ var childrenProps_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
34
33
|
} };
|
|
35
34
|
}
|
|
36
35
|
});
|
|
37
|
-
|
|
38
36
|
//#endregion
|
|
39
37
|
export { childrenProps_default as default };
|
|
38
|
+
|
|
40
39
|
//# sourceMappingURL=childrenProps.js.map
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
declare const _default: import("@flint.fyi/core").Rule<
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports onClick without keyboard event handlers.";
|
|
3
|
+
readonly id: "clickEventKeyEvents";
|
|
4
|
+
readonly presets: ["logical", "logicalStrict"];
|
|
5
|
+
} & {
|
|
6
|
+
presets?: ("logical" | "logicalStrict" | "stylistic")[];
|
|
7
|
+
url: string;
|
|
8
|
+
}, object, object, "missingKeyEvent", import("@flint.fyi/core").AnyOptionalSchema>;
|
|
2
9
|
export default _default;
|
|
3
10
|
//# sourceMappingURL=clickEventKeyEvents.d.ts.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ruleCreator } from "./ruleCreator.js";
|
|
2
2
|
import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
|
|
3
3
|
import { SyntaxKind } from "typescript";
|
|
4
|
-
|
|
5
4
|
//#region src/rules/clickEventKeyEvents.ts
|
|
6
5
|
const interactiveElements = new Set([
|
|
7
6
|
"a",
|
|
@@ -14,7 +13,7 @@ var clickEventKeyEvents_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
14
13
|
about: {
|
|
15
14
|
description: "Reports onClick without keyboard event handlers.",
|
|
16
15
|
id: "clickEventKeyEvents",
|
|
17
|
-
presets: ["logical"]
|
|
16
|
+
presets: ["logical", "logicalStrict"]
|
|
18
17
|
},
|
|
19
18
|
messages: { missingKeyEvent: {
|
|
20
19
|
primary: "This `onClick` is missing accompanying `onKeyUp`, `onKeyDown`, and/or `onKeyPress` keyboard events.",
|
|
@@ -51,7 +50,7 @@ var clickEventKeyEvents_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
51
50
|
} };
|
|
52
51
|
}
|
|
53
52
|
});
|
|
54
|
-
|
|
55
53
|
//#endregion
|
|
56
54
|
export { clickEventKeyEvents_default as default };
|
|
55
|
+
|
|
57
56
|
//# sourceMappingURL=clickEventKeyEvents.js.map
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
declare const _default: import("@flint.fyi/core").Rule<
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports JSX text nodes that contain comment syntax but are rendered as text.";
|
|
3
|
+
readonly id: "commentTextNodes";
|
|
4
|
+
readonly presets: ["logical", "logicalStrict"];
|
|
5
|
+
} & {
|
|
6
|
+
presets?: ("logical" | "logicalStrict" | "stylistic")[];
|
|
7
|
+
url: string;
|
|
8
|
+
}, object, object, "commentAsText", import("@flint.fyi/core").AnyOptionalSchema>;
|
|
2
9
|
export default _default;
|
|
3
10
|
//# sourceMappingURL=commentTextNodes.d.ts.map
|