From 15639d674ba14f7f881b1da2dfffde3939d39d17 Mon Sep 17 00:00:00 2001 From: Grace Park Date: Mon, 25 Nov 2024 11:54:35 -0800 Subject: [PATCH 1/9] update filenames --- eslint.config.js | 2 +- test-examples/flat/src/getAttribute.js | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/eslint.config.js b/eslint.config.js index bc454483..3dc2832f 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -23,7 +23,7 @@ module.exports = [ plugins: { eslintPlugin, importPlugin, - filenames, + filenamesPlugin: fixupPluginRules(filenames), 'i18n-text': fixupPluginRules(i18nTextPlugin), }, rules: { diff --git a/test-examples/flat/src/getAttribute.js b/test-examples/flat/src/getAttribute.js index 5aaca01c..bccff298 100644 --- a/test-examples/flat/src/getAttribute.js +++ b/test-examples/flat/src/getAttribute.js @@ -6,3 +6,9 @@ const title = document.createElement('h1') title.textContent = `${title}!` foobar(title) + +document.addEventListener('click', async function (event) { + const data = await fetch() + + event.preventDefault() +}) From c03d25be9dc68112df5e03142f5c8545c1f8db4e Mon Sep 17 00:00:00 2001 From: Grace Park Date: Mon, 25 Nov 2024 13:08:37 -0800 Subject: [PATCH 2/9] bring in filenames match regex to github --- README.md | 1 + eslint.config.js | 4 +--- lib/configs/flat/browser.js | 3 ++- lib/configs/flat/internal.js | 3 ++- lib/configs/flat/react.js | 3 ++- lib/configs/flat/recommended.js | 6 ++---- lib/configs/flat/typescript.js | 3 ++- lib/configs/recommended.js | 2 +- lib/plugin.js | 1 + test-examples/flat/eslint.config.mjs | 8 ++++---- test-examples/flat/package.json | 2 +- 11 files changed, 19 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index c69717b4..e98fc8e0 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,7 @@ This config will be interpreted in the following way: | [async-currenttarget](docs/rules/async-currenttarget.md) | disallow `event.currentTarget` calls inside of async functions | 🔍 | | | | [async-preventdefault](docs/rules/async-preventdefault.md) | disallow `event.preventDefault` calls inside of async functions | 🔍 | | | | [authenticity-token](docs/rules/authenticity-token.md) | disallow usage of CSRF tokens in JavaScript | 🔐 | | | +| [filenames-match-regex](docs/rules/filenames-match-regex.md) | ensure filenames match a regex naming convention | ✅ | | | | [get-attribute](docs/rules/get-attribute.md) | disallow wrong usage of attribute names | 🔍 | 🔧 | | | [js-class-name](docs/rules/js-class-name.md) | enforce a naming convention for js- prefixed classes | 🔐 | | | | [no-blur](docs/rules/no-blur.md) | disallow usage of `Element.prototype.blur()` | 🔍 | | | diff --git a/eslint.config.js b/eslint.config.js index 3dc2832f..e5dae376 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,7 +1,6 @@ const globals = require('globals') const eslintPlugin = require('eslint-plugin-eslint-plugin') const importPlugin = require('eslint-plugin-import') -const filenames = require('eslint-plugin-filenames') const i18nTextPlugin = require('eslint-plugin-i18n-text') const recommendedGitHub = require('./lib/configs/flat/recommended') const {fixupPluginRules} = require('@eslint/compat') @@ -23,13 +22,12 @@ module.exports = [ plugins: { eslintPlugin, importPlugin, - filenamesPlugin: fixupPluginRules(filenames), 'i18n-text': fixupPluginRules(i18nTextPlugin), }, rules: { 'importPlugin/extensions': 'off', 'importPlugin/no-commonjs': 'off', - 'filenamesPlugin/match-regex': 'off', + 'github/filenames-match-regex': 'off', 'i18n-text/no-en': 'off', 'eslint-plugin/prefer-placeholders': 'off', 'eslint-plugin/test-case-shorthand-strings': 'off', diff --git a/lib/configs/flat/browser.js b/lib/configs/flat/browser.js index 17f2b74c..67ba85fe 100644 --- a/lib/configs/flat/browser.js +++ b/lib/configs/flat/browser.js @@ -2,6 +2,7 @@ const globals = require('globals') const github = require('../../plugin') const importPlugin = require('eslint-plugin-import') const escompatPlugin = require('eslint-plugin-escompat') +const {fixupPluginRules} = require('@eslint/compat') module.exports = { ...escompatPlugin.configs['flat/recommended'], @@ -10,7 +11,7 @@ module.exports = { ...globals.browser, }, }, - plugins: {importPlugin, escompatPlugin, github}, + plugins: {importPlugin, escompatPlugin, github: fixupPluginRules(github)}, rules: { 'escompatPlugin/no-dynamic-imports': 'off', 'github/async-currenttarget': 'error', diff --git a/lib/configs/flat/internal.js b/lib/configs/flat/internal.js index e3aa8e43..0ce81f51 100644 --- a/lib/configs/flat/internal.js +++ b/lib/configs/flat/internal.js @@ -1,7 +1,8 @@ const github = require('../../plugin') +const {fixupPluginRules} = require('@eslint/compat') module.exports = { - plugins: {github}, + plugins: {github: fixupPluginRules(github)}, rules: { 'github/authenticity-token': 'error', 'github/js-class-name': 'error', diff --git a/lib/configs/flat/react.js b/lib/configs/flat/react.js index 8d2e0f80..497505fc 100644 --- a/lib/configs/flat/react.js +++ b/lib/configs/flat/react.js @@ -1,5 +1,6 @@ const github = require('../../plugin') const jsxA11yPlugin = require('eslint-plugin-jsx-a11y') +const {fixupPluginRules} = require('@eslint/compat') module.exports = { ...jsxA11yPlugin.flatConfigs.recommended, @@ -11,7 +12,7 @@ module.exports = { }, }, }, - plugins: {github, jsxA11yPlugin}, + plugins: {github: fixupPluginRules(github), jsxA11yPlugin}, rules: { 'jsxA11yPlugin/role-supports-aria-props': 'off', // Override with github/a11y-role-supports-aria-props until https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/issues/910 is resolved 'github/a11y-aria-label-is-well-formatted': 'error', diff --git a/lib/configs/flat/recommended.js b/lib/configs/flat/recommended.js index 061260fa..31cb3400 100644 --- a/lib/configs/flat/recommended.js +++ b/lib/configs/flat/recommended.js @@ -3,7 +3,6 @@ const github = require('../../plugin') const prettierPlugin = require('eslint-plugin-prettier') const eslintComments = require('eslint-plugin-eslint-comments') const importPlugin = require('eslint-plugin-import') -const filenames = require('eslint-plugin-filenames') const i18nTextPlugin = require('eslint-plugin-i18n-text') const noOnlyTestsPlugin = require('eslint-plugin-no-only-tests') const {fixupPluginRules} = require('@eslint/compat') @@ -17,13 +16,12 @@ module.exports = { }, }, plugins: { - filenamesPlugin: fixupPluginRules(filenames), prettierPlugin, eslintComments, importPlugin, 'i18n-text': fixupPluginRules(i18nTextPlugin), noOnlyTestsPlugin, - github, + github: fixupPluginRules(github), }, rules: { 'constructor-super': 'error', @@ -34,7 +32,7 @@ module.exports = { 'eslintComments/no-unused-disable': 'error', 'eslintComments/no-unused-enable': 'error', 'eslintComments/no-use': ['error', {allow: ['eslint', 'eslint-disable-next-line', 'eslint-env', 'globals']}], - 'filenamesPlugin/match-regex': ['error', '^[a-z0-9-]+(.[a-z0-9-]+)?$'], + 'github/filenames-match-regex': ['error', '^[a-z0-9-]+(.[a-z0-9-]+)?$'], 'func-style': ['error', 'declaration', {allowArrowFunctions: true}], 'github/array-foreach': 'error', 'github/no-implicit-buggy-globals': 'error', diff --git a/lib/configs/flat/typescript.js b/lib/configs/flat/typescript.js index eb6b71fd..50cc6c05 100644 --- a/lib/configs/flat/typescript.js +++ b/lib/configs/flat/typescript.js @@ -2,12 +2,13 @@ const eslint = require('@eslint/js') const tseslint = require('typescript-eslint') const escompatPlugin = require('eslint-plugin-escompat') const github = require('../../plugin') +const {fixupPluginRules} = require('@eslint/compat') module.exports = tseslint.config(eslint.configs.recommended, ...tseslint.configs.recommended, { languageOptions: { parser: tseslint.parser, }, - plugins: {'@typescript-eslint': tseslint.plugin, escompatPlugin, github}, + plugins: {'@typescript-eslint': tseslint.plugin, escompatPlugin, github: fixupPluginRules(github)}, rules: { camelcase: 'off', 'no-unused-vars': 'off', diff --git a/lib/configs/recommended.js b/lib/configs/recommended.js index cdbbd450..2ba51af6 100644 --- a/lib/configs/recommended.js +++ b/lib/configs/recommended.js @@ -18,7 +18,7 @@ module.exports = { 'eslint-comments/no-unused-disable': 'error', 'eslint-comments/no-unused-enable': 'error', 'eslint-comments/no-use': ['error', {allow: ['eslint', 'eslint-disable-next-line', 'eslint-env', 'globals']}], - 'filenames/match-regex': ['error', '^[a-z0-9-]+(.[a-z0-9-]+)?$'], + 'github/filenames-match-regex': ['error', '^[a-z0-9-]+(.[a-z0-9-]+)?$'], 'func-style': ['error', 'declaration', {allowArrowFunctions: true}], 'github/array-foreach': 'error', 'github/no-implicit-buggy-globals': 'error', diff --git a/lib/plugin.js b/lib/plugin.js index 3ed34175..eb25a25e 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -13,6 +13,7 @@ module.exports = { 'async-currenttarget': require('./rules/async-currenttarget'), 'async-preventdefault': require('./rules/async-preventdefault'), 'authenticity-token': require('./rules/authenticity-token'), + 'filenames-match-regex': require('./rules/filenames-match-regex'), 'get-attribute': require('./rules/get-attribute'), 'js-class-name': require('./rules/js-class-name'), 'no-blur': require('./rules/no-blur'), diff --git a/test-examples/flat/eslint.config.mjs b/test-examples/flat/eslint.config.mjs index db132c02..8bad9255 100644 --- a/test-examples/flat/eslint.config.mjs +++ b/test-examples/flat/eslint.config.mjs @@ -1,18 +1,18 @@ import github from 'eslint-plugin-github' export default [ - github.getFlatConfigs().browser, github.getFlatConfigs().recommended, - github.getFlatConfigs().react, - ...github.getFlatConfigs().typescript, + // github.getFlatConfigs().recommended, + // github.getFlatConfigs().react, + // ...github.getFlatConfigs().typescript, { files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'], ignores: ['eslint.config.mjs'], rules: { 'github/array-foreach': 'error', - 'github/async-preventdefault': 'warn', 'github/no-then': 'error', 'github/no-blur': 'error', + 'github/async-preventdefault': 'error', }, }, ] diff --git a/test-examples/flat/package.json b/test-examples/flat/package.json index 99ee6c96..ab18bedc 100644 --- a/test-examples/flat/package.json +++ b/test-examples/flat/package.json @@ -9,7 +9,7 @@ "@eslint/js": "^9.5.0", "@types/node": "^20.14.5", "cross-env": "^7.0.3", - "eslint": "^8.57.0", + "eslint": "^9.14.0", "eslint-plugin-github": "file:../..", "typescript": "^5.6.3", "typescript-eslint": "^8.12.2" From 752026053e93465688416e235f843101b10499c1 Mon Sep 17 00:00:00 2001 From: Grace Park Date: Mon, 25 Nov 2024 13:12:17 -0800 Subject: [PATCH 3/9] add back in test examples; --- test-examples/flat/eslint.config.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test-examples/flat/eslint.config.mjs b/test-examples/flat/eslint.config.mjs index 8bad9255..2d4f781e 100644 --- a/test-examples/flat/eslint.config.mjs +++ b/test-examples/flat/eslint.config.mjs @@ -2,9 +2,9 @@ import github from 'eslint-plugin-github' export default [ github.getFlatConfigs().recommended, - // github.getFlatConfigs().recommended, - // github.getFlatConfigs().react, - // ...github.getFlatConfigs().typescript, + github.getFlatConfigs().browser, + github.getFlatConfigs().react, + ...github.getFlatConfigs().typescript, { files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'], ignores: ['eslint.config.mjs'], From 725f1a137af08e65065e825fc2b16c4db2214ca8 Mon Sep 17 00:00:00 2001 From: Grace Park Date: Mon, 25 Nov 2024 13:13:35 -0800 Subject: [PATCH 4/9] bring in filenames to github rules --- lib/rules/filenames-match-regex.js | 49 ++++++++++++++++++++++++++++++ lib/utils/get-exported-name.js | 37 ++++++++++++++++++++++ lib/utils/is-ignored-filename.js | 5 +++ lib/utils/parse-filename.js | 12 ++++++++ 4 files changed, 103 insertions(+) create mode 100644 lib/rules/filenames-match-regex.js create mode 100644 lib/utils/get-exported-name.js create mode 100644 lib/utils/is-ignored-filename.js create mode 100644 lib/utils/parse-filename.js diff --git a/lib/rules/filenames-match-regex.js b/lib/rules/filenames-match-regex.js new file mode 100644 index 00000000..5c556ce7 --- /dev/null +++ b/lib/rules/filenames-match-regex.js @@ -0,0 +1,49 @@ +const path = require('path') +const parseFilename = require('../utils/parse-filename') +const getExportedName = require('../utils/get-exported-name') +const isIgnoredFilename = require('../utils/is-ignored-filename') + +module.exports = { + meta: { + type: 'problem', + docs: { + description: 'ensure filenames match a regex naming convention', + url: require('../url')(module), + }, + schema: { + type: 'array', + minItems: 1, + maxItems: 2, + items: [ + { + type: 'string', + }, + ], + }, + }, + + create(context) { + const defaultRegexp = /^([a-z0-9]+)([A-Z][a-z0-9]+)*$/g + const conventionRegexp = context.options[0] ? new RegExp(context.options[0]) : defaultRegexp + const ignoreExporting = context.options[1] ? context.options[1] : false + + return { + Program(node) { + const filename = context.getFilename() + const absoluteFilename = path.resolve(filename) + const parsed = parseFilename(absoluteFilename) + const shouldIgnore = isIgnoredFilename(filename) + const isExporting = Boolean(getExportedName(node)) + const matchesRegex = conventionRegexp.test(parsed.name) + + if (shouldIgnore) return + if (ignoreExporting && isExporting) return + if (!matchesRegex) { + context.report(node, "Filename '{{name}}' does not match the regex naming convention.", { + name: parsed.base, + }) + } + }, + } + }, +} diff --git a/lib/utils/get-exported-name.js b/lib/utils/get-exported-name.js new file mode 100644 index 00000000..642f0a0c --- /dev/null +++ b/lib/utils/get-exported-name.js @@ -0,0 +1,37 @@ +function getNodeName(node, options) { + const op = options || [] + + if (node.type === 'Identifier') { + return node.name + } + + if (node.id && node.id.type === 'Identifier') { + return node.id.name + } + + if (op[2] && node.type === 'CallExpression' && node.callee.type === 'Identifier') { + return node.callee.name + } +} + +module.exports = function getExportedName(programNode, options) { + for (let i = 0; i < programNode.body.length; i += 1) { + const node = programNode.body[i] + + if (node.type === 'ExportDefaultDeclaration') { + return getNodeName(node.declaration, options) + } + + if ( + node.type === 'ExpressionStatement' && + node.expression.type === 'AssignmentExpression' && + node.expression.left.type === 'MemberExpression' && + node.expression.left.object.type === 'Identifier' && + node.expression.left.object.name === 'module' && + node.expression.left.property.type === 'Identifier' && + node.expression.left.property.name === 'exports' + ) { + return getNodeName(node.expression.right, options) + } + } +} diff --git a/lib/utils/is-ignored-filename.js b/lib/utils/is-ignored-filename.js new file mode 100644 index 00000000..18f41153 --- /dev/null +++ b/lib/utils/is-ignored-filename.js @@ -0,0 +1,5 @@ +const ignoredFilenames = ['', ''] + +module.exports = function isIgnoredFilename(filename) { + return ignoredFilenames.indexOf(filename) !== -1 +} diff --git a/lib/utils/parse-filename.js b/lib/utils/parse-filename.js new file mode 100644 index 00000000..ce589c71 --- /dev/null +++ b/lib/utils/parse-filename.js @@ -0,0 +1,12 @@ +const path = require('path') + +module.exports = function parseFilename(filename) { + const ext = path.extname(filename) + + return { + dir: path.dirname(filename), + base: path.basename(filename), + ext, + name: path.basename(filename, ext), + } +} From 813592d2d741115a9b0f576799edf31a248eb238 Mon Sep 17 00:00:00 2001 From: Grace Park Date: Mon, 25 Nov 2024 13:15:49 -0800 Subject: [PATCH 5/9] rule docs for filenames match regex --- docs/rules/filenames-match-regex.md | 35 +++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 docs/rules/filenames-match-regex.md diff --git a/docs/rules/filenames-match-regex.md b/docs/rules/filenames-match-regex.md new file mode 100644 index 00000000..317a465f --- /dev/null +++ b/docs/rules/filenames-match-regex.md @@ -0,0 +1,35 @@ +# Ensure filenames match a regex naming convention (`github/filenames-match-regex`) + +💼 This rule is enabled in the ✅ `recommended` config. + + + +## Rule Details + +TRule to ensure that filenames match a convention, with a default of camelCase. + +👎 Examples of **incorrect** filename for this default rule: + +`file-name.js` + +👍 Examples of **correct** code for this rule: + +`fileName.js` + +## Options + +regex - Regex to match the filename structure. Defaults to camelCase. + + +```json +{ + "filenames-match-regex": [ + "error", + "^[a-z0-9-]+(.[a-z0-9-]+)?$" + ] +} +``` + +## Version + +4.3.2 From 259194f92bda4426963f27f8c48d0b35aa443aa3 Mon Sep 17 00:00:00 2001 From: Grace Park Date: Mon, 25 Nov 2024 13:21:32 -0800 Subject: [PATCH 6/9] remove filenames plugin --- lib/configs/recommended.js | 2 +- package.json | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/configs/recommended.js b/lib/configs/recommended.js index 2ba51af6..23399b9f 100644 --- a/lib/configs/recommended.js +++ b/lib/configs/recommended.js @@ -8,7 +8,7 @@ module.exports = { env: { es6: true, }, - plugins: ['github', 'prettier', 'eslint-comments', 'import', 'filenames', 'i18n-text', 'no-only-tests'], + plugins: ['github', 'prettier', 'eslint-comments', 'import', 'i18n-text', 'no-only-tests'], rules: { 'constructor-super': 'error', 'eslint-comments/disable-enable-pair': 'off', diff --git a/package.json b/package.json index 49792dc1..00864e63 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,6 @@ "eslint-config-prettier": ">=8.0.0", "eslint-plugin-escompat": "^3.11.3", "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-filenames": "^1.3.2", "eslint-plugin-i18n-text": "^1.0.1", "eslint-plugin-import": "^2.25.2", "eslint-plugin-jsx-a11y": "^6.7.1", From a78d1effe03589e8cb95b689a420175b1d64c685 Mon Sep 17 00:00:00 2001 From: Grace Park Date: Mon, 25 Nov 2024 13:28:26 -0800 Subject: [PATCH 7/9] update items max and min --- lib/rules/filenames-match-regex.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rules/filenames-match-regex.js b/lib/rules/filenames-match-regex.js index 5c556ce7..69881a52 100644 --- a/lib/rules/filenames-match-regex.js +++ b/lib/rules/filenames-match-regex.js @@ -12,8 +12,8 @@ module.exports = { }, schema: { type: 'array', - minItems: 1, - maxItems: 2, + minItems: 0, + maxItems: 1, items: [ { type: 'string', From 3116c0c79539fc699762aecb6db8a8a10ad35a2c Mon Sep 17 00:00:00 2001 From: Grace Park Date: Mon, 25 Nov 2024 14:06:45 -0800 Subject: [PATCH 8/9] Update docs/rules/filenames-match-regex.md Co-authored-by: Arelia Jones <2359538+arelia@users.noreply.github.com> --- docs/rules/filenames-match-regex.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/filenames-match-regex.md b/docs/rules/filenames-match-regex.md index 317a465f..dbbf1900 100644 --- a/docs/rules/filenames-match-regex.md +++ b/docs/rules/filenames-match-regex.md @@ -6,7 +6,7 @@ ## Rule Details -TRule to ensure that filenames match a convention, with a default of camelCase. +Rule to ensure that filenames match a convention, with a default of camelCase. 👎 Examples of **incorrect** filename for this default rule: From e86d15540f301567f938d7c3aeba8516bfd367c9 Mon Sep 17 00:00:00 2001 From: Grace Park Date: Mon, 25 Nov 2024 14:26:55 -0800 Subject: [PATCH 9/9] add comment --- lib/rules/filenames-match-regex.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/rules/filenames-match-regex.js b/lib/rules/filenames-match-regex.js index 69881a52..515887ea 100644 --- a/lib/rules/filenames-match-regex.js +++ b/lib/rules/filenames-match-regex.js @@ -1,3 +1,5 @@ +// This is adapted from https://github.com/selaux/eslint-plugin-filenames since it's no longer actively maintained +// and needed a fix for eslint v9 const path = require('path') const parseFilename = require('../utils/parse-filename') const getExportedName = require('../utils/get-exported-name') pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy