This commit is contained in:
sharan 2025-12-23 15:34:34 -03:00 committed by GitHub
commit ebbde26548
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 102 additions and 1 deletions

View File

@ -80,6 +80,7 @@
"@swc/core": "^1.7.14",
"@swc/jest": "^0.2.36",
"@testing-library/react-hooks": "^8.0.1",
"@types/eslint": "^9.6.1",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^29.5.12",
"@types/lodash": "^4.14.197",

View File

@ -0,0 +1,37 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {TSESLint} from '@typescript-eslint/utils';
import rule from '../no-hardcoded-src';
declare const require: any;
const ruleTester = new TSESLint.RuleTester({
parser: require.resolve('@typescript-eslint/parser'),
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
});
ruleTester.run('no-hardcoded-src', rule, {
valid: [
{code: `<img src={require('./logo.png')} />`},
{
code: `import useBaseUrl from '@docusaurus/useBaseUrl';\n<img src={useBaseUrl('/img/logo.png')} />`,
},
{code: `<div src="/img/logo.png" />`},
{code: `<img src={variableName} />`},
],
invalid: [
{
code: `<img src="/img/logo.png" />`,
errors: [{messageId: 'hardcodedSrc'}],
},
{code: `<img src="logo.png" />`, errors: [{messageId: 'hardcodedSrc'}]},
],
});

View File

@ -0,0 +1,55 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {createRule} from '../util';
import type {TSESTree} from '@typescript-eslint/utils';
export default createRule({
name: 'no-hardcoded-src',
meta: {
type: 'problem',
docs: {
description:
'Enforce using require() or useBaseUrl() for src attributes.',
recommended: 'warn',
},
schema: [],
messages: {
hardcodedSrc:
'Do not use a hardcoded string for the src attribute. Use require() or useBaseUrl() for image paths instead.',
},
},
defaultOptions: [],
create(context) {
return {
JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
if (node.name.type !== 'JSXIdentifier' || node.name.name !== 'img') {
return;
}
const srcAttribute = node.attributes.find(
(attr): attr is TSESTree.JSXAttribute =>
attr.type === 'JSXAttribute' && attr.name.name === 'src',
);
if (!srcAttribute) {
return;
}
if (
srcAttribute.value?.type === 'Literal' &&
typeof srcAttribute.value.value === 'string' &&
srcAttribute.value.value.trim().length > 0
) {
context.report({
node: srcAttribute,
messageId: 'hardcodedSrc',
});
}
},
};
},
});

View File

@ -4243,6 +4243,14 @@
resolved "https://registry.yarnpkg.com/@types/escape-html/-/escape-html-1.0.4.tgz#dc7c166b76c7b03b27e32f80edf01d91eb5d9af2"
integrity sha512-qZ72SFTgUAZ5a7Tj6kf2SHLetiH5S6f8G5frB2SPQ3EyF02kxdyBFf4Tz4banE3xCgGnKgWLt//a6VuYHKYJTg==
"@types/eslint@^9.6.1":
version "9.6.1"
resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-9.6.1.tgz#d5795ad732ce81715f27f75da913004a56751584"
integrity sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==
dependencies:
"@types/estree" "*"
"@types/json-schema" "*"
"@types/estree-jsx@^1.0.0":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.5.tgz#858a88ea20f34fe65111f005a689fa1ebf70dc18"
@ -4432,7 +4440,7 @@
"@types/tough-cookie" "*"
parse5 "^7.0.0"
"@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
version "7.0.15"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==