From 06c8e9186b95dda6964fca0689bbd561b65a918d Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Mon, 19 May 2025 11:19:53 +0100 Subject: [PATCH] chore: remove flatMap polyfill Uses native functionality instead. Part of #16. --- .changeset/slimy-taxes-check.md | 5 +++++ __tests__/__util__/helpers/parsers.js | 5 ++--- __tests__/__util__/ruleOptionsMapperFactory.js | 3 +-- package.json | 1 - src/rules/alt-text.js | 4 +--- src/rules/media-has-caption.js | 3 +-- src/util/isInteractiveElement.js | 10 +++------- src/util/isInteractiveRole.js | 3 +-- src/util/isNonInteractiveElement.js | 10 +++------- src/util/isNonInteractiveRole.js | 3 +-- yarn.lock | 13 ------------- 11 files changed, 18 insertions(+), 42 deletions(-) create mode 100644 .changeset/slimy-taxes-check.md diff --git a/.changeset/slimy-taxes-check.md b/.changeset/slimy-taxes-check.md new file mode 100644 index 00000000..9ec9ec9e --- /dev/null +++ b/.changeset/slimy-taxes-check.md @@ -0,0 +1,5 @@ +--- +"eslint-plugin-jsx-a11y-x": patch +--- + +Removes `flatMap` polyfill and uses native functionality instead. diff --git a/__tests__/__util__/helpers/parsers.js b/__tests__/__util__/helpers/parsers.js index 8eb7096f..f4e7be12 100644 --- a/__tests__/__util__/helpers/parsers.js +++ b/__tests__/__util__/helpers/parsers.js @@ -2,7 +2,6 @@ import path from 'path'; import semver from 'semver'; import entries from 'object.entries'; import { version } from 'eslint/package.json'; -import flatMap from 'array.prototype.flatmap'; let tsParserVersion; try { @@ -26,7 +25,7 @@ function minEcmaVersion(features, parserOptions) { ...[] .concat( (parserOptions && parserOptions.ecmaVersion) || [], - flatMap(entries(minEcmaVersionForFeatures), entry => { + entries(minEcmaVersionForFeatures).flatMap(entry => { const f = entry[0]; const y = entry[1]; return features.has(f) ? y : []; @@ -78,7 +77,7 @@ const parsers = { }; }, all: function all(tests) { - const t = flatMap(tests, test => { + const t = tests.flatMap(test => { /* eslint no-param-reassign: 0 */ if (typeof test === 'string') { test = { code: test }; diff --git a/__tests__/__util__/ruleOptionsMapperFactory.js b/__tests__/__util__/ruleOptionsMapperFactory.js index 74ac7f88..ce51751a 100644 --- a/__tests__/__util__/ruleOptionsMapperFactory.js +++ b/__tests__/__util__/ruleOptionsMapperFactory.js @@ -1,7 +1,6 @@ /** @flow */ import entries from 'object.entries'; -import flatMap from 'array.prototype.flatmap'; import fromEntries from 'object.fromentries'; type ESLintTestRunnerTestCase = { @@ -33,7 +32,7 @@ export default function ruleOptionsMapperFactory( // Flatten the array of objects in an array of one object. options: [ fromEntries( - flatMap((options || []).concat(ruleOptions), item => entries(item)), + (options || []).concat(ruleOptions).flatMap(item => entries(item)), ), ], parserOptions, diff --git a/package.json b/package.json index d5c3700c..0822051a 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,6 @@ }, "dependencies": { "aria-query": "^5.3.2", - "array.prototype.flatmap": "^1.3.2", "ast-types-flow": "^0.0.8", "axe-core": "^4.10.2", "axobject-query": "^4.1.0", diff --git a/src/rules/alt-text.js b/src/rules/alt-text.js index 74123951..a1bbd476 100644 --- a/src/rules/alt-text.js +++ b/src/rules/alt-text.js @@ -8,7 +8,6 @@ // ---------------------------------------------------------------------------- import { getProp, getPropValue, getLiteralPropValue } from 'jsx-ast-utils'; -import flatMap from 'array.prototype.flatmap'; import { generateObjSchema, arraySchema } from '../util/schemas'; import getElementType from '../util/getElementType'; @@ -218,8 +217,7 @@ export default { // Elements to validate for alt text. const elementOptions = options.elements || DEFAULT_ELEMENTS; // Get custom components for just the elements that will be tested. - const customComponents = flatMap( - elementOptions, + const customComponents = elementOptions.flatMap( element => options[element], ); const typesToValidate = new Set( diff --git a/src/rules/media-has-caption.js b/src/rules/media-has-caption.js index c3454942..20a41ab3 100644 --- a/src/rules/media-has-caption.js +++ b/src/rules/media-has-caption.js @@ -10,7 +10,6 @@ import type { JSXElement, JSXOpeningElement, Node } from 'ast-types-flow'; import { getProp, getLiteralPropValue } from 'jsx-ast-utils'; -import flatMap from 'array.prototype.flatmap'; import type { ESLintConfig, @@ -34,7 +33,7 @@ const schema = generateObjSchema({ const isMediaType = (context, type) => { const options = context.options[0] || {}; return MEDIA_TYPES.concat( - flatMap(MEDIA_TYPES, mediaType => options[mediaType]), + MEDIA_TYPES.flatMap(mediaType => options[mediaType]), ).some(typeToCheck => typeToCheck === type); }; diff --git a/src/util/isInteractiveElement.js b/src/util/isInteractiveElement.js index 327a1776..a7b60042 100644 --- a/src/util/isInteractiveElement.js +++ b/src/util/isInteractiveElement.js @@ -2,7 +2,6 @@ import { dom, elementRoles, roles } from 'aria-query'; import type { Node } from 'ast-types-flow'; import { AXObjects, elementAXObjects } from 'axobject-query'; -import flatMap from 'array.prototype.flatmap'; import attributesComparator from './attributesComparator'; @@ -47,16 +46,14 @@ const interactiveRoles = new Set( ), ); -const interactiveElementRoleSchemas = flatMap( - elementRoleEntries, +const interactiveElementRoleSchemas = elementRoleEntries.flatMap( ([elementSchema, rolesArr]) => rolesArr.some((role): boolean => interactiveRoles.has(role)) ? [elementSchema] : [], ); -const nonInteractiveElementRoleSchemas = flatMap( - elementRoleEntries, +const nonInteractiveElementRoleSchemas = elementRoleEntries.flatMap( ([elementSchema, rolesArr]) => rolesArr.every((role): boolean => nonInteractiveRoles.has(role)) ? [elementSchema] @@ -67,8 +64,7 @@ const interactiveAXObjects = new Set( AXObjects.keys().filter(name => AXObjects.get(name).type === 'widget'), ); -const interactiveElementAXObjectSchemas = flatMap( - [...elementAXObjects], +const interactiveElementAXObjectSchemas = [...elementAXObjects].flatMap( ([elementSchema, AXObjectsArr]) => AXObjectsArr.every((role): boolean => interactiveAXObjects.has(role)) ? [elementSchema] diff --git a/src/util/isInteractiveRole.js b/src/util/isInteractiveRole.js index e37790b0..e7446e24 100644 --- a/src/util/isInteractiveRole.js +++ b/src/util/isInteractiveRole.js @@ -2,7 +2,6 @@ import { roles as rolesMap } from 'aria-query'; import type { Node } from 'ast-types-flow'; import { getProp, getLiteralPropValue } from 'jsx-ast-utils'; -import flatMap from 'array.prototype.flatmap'; const roles = rolesMap.keys(); const interactiveRoles = roles.filter( @@ -40,7 +39,7 @@ const isInteractiveRole = ( let isInteractive = false; const normalizedValues = String(value).toLowerCase().split(' '); - const validRoles = flatMap(normalizedValues, (name: string) => + const validRoles = normalizedValues.flatMap((name: string) => roles.includes(name) ? [name] : [], ); if (validRoles.length > 0) { diff --git a/src/util/isNonInteractiveElement.js b/src/util/isNonInteractiveElement.js index 5cba0b8f..cd49b927 100644 --- a/src/util/isNonInteractiveElement.js +++ b/src/util/isNonInteractiveElement.js @@ -3,7 +3,6 @@ import { dom, elementRoles, roles } from 'aria-query'; import { AXObjects, elementAXObjects } from 'axobject-query'; import type { Node } from 'ast-types-flow'; -import flatMap from 'array.prototype.flatmap'; import attributesComparator from './attributesComparator'; @@ -54,16 +53,14 @@ const interactiveRoles = new Set( ), ); -const interactiveElementRoleSchemas = flatMap( - elementRoleEntries, +const interactiveElementRoleSchemas = elementRoleEntries.flatMap( ([elementSchema, rolesArr]) => rolesArr.some((role): boolean => interactiveRoles.has(role)) ? [elementSchema] : [], ); -const nonInteractiveElementRoleSchemas = flatMap( - elementRoleEntries, +const nonInteractiveElementRoleSchemas = elementRoleEntries.flatMap( ([elementSchema, rolesArr]) => rolesArr.every((role): boolean => nonInteractiveRoles.has(role)) ? [elementSchema] @@ -76,8 +73,7 @@ const nonInteractiveAXObjects = new Set( ), ); -const nonInteractiveElementAXObjectSchemas = flatMap( - [...elementAXObjects], +const nonInteractiveElementAXObjectSchemas = [...elementAXObjects].flatMap( ([elementSchema, AXObjectsArr]) => AXObjectsArr.every((role): boolean => nonInteractiveAXObjects.has(role)) ? [elementSchema] diff --git a/src/util/isNonInteractiveRole.js b/src/util/isNonInteractiveRole.js index 6a7da32a..8fa308bf 100644 --- a/src/util/isNonInteractiveRole.js +++ b/src/util/isNonInteractiveRole.js @@ -3,7 +3,6 @@ import { dom, roles as rolesMap } from 'aria-query'; import type { Node } from 'ast-types-flow'; import { getProp, getLiteralPropValue } from 'jsx-ast-utils'; -import flatMap from 'array.prototype.flatmap'; const nonInteractiveRoles = rolesMap .keys() @@ -47,7 +46,7 @@ const isNonInteractiveRole = ( let isNonInteractive = false; const normalizedValues = String(role).toLowerCase().split(' '); - const validRoles = flatMap(normalizedValues, (name: string) => + const validRoles = normalizedValues.flatMap((name: string) => rolesMap.has(name) ? [name] : [], ); if (validRoles.length > 0) { diff --git a/yarn.lock b/yarn.lock index e186797c..8538f645 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2673,18 +2673,6 @@ __metadata: languageName: node linkType: hard -"array.prototype.flatmap@npm:^1.3.2": - version: 1.3.3 - resolution: "array.prototype.flatmap@npm:1.3.3" - dependencies: - call-bind: "npm:^1.0.8" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.5" - es-shim-unscopables: "npm:^1.0.2" - checksum: 10c0/ba899ea22b9dc9bf276e773e98ac84638ed5e0236de06f13d63a90b18ca9e0ec7c97d622d899796e3773930b946cd2413d098656c0c5d8cc58c6f25c21e6bd54 - languageName: node - linkType: hard - "arraybuffer.prototype.slice@npm:^1.0.4": version: 1.0.4 resolution: "arraybuffer.prototype.slice@npm:1.0.4" @@ -3808,7 +3796,6 @@ __metadata: "@eslint/eslintrc": "npm:^3.3.1" "@eslint/js": "npm:^9.26.0" aria-query: "npm:^5.3.2" - array.prototype.flatmap: "npm:^1.3.2" ast-types-flow: "npm:^0.0.8" auto-changelog: "npm:^2.5.0" axe-core: "npm:^4.10.2"