Files
2025-05-12 10:34:17 +01:00

97 lines
2.8 KiB
JavaScript

// @ts-check
const { AST_NODE_TYPES } = require('@typescript-eslint/utils');
const { upperFirst } = require('lodash');
/** @typedef {import('@typescript-eslint/utils/ts-eslint').RuleContext<'publicImg' | 'importImage' | 'useBuildFolder', []>} RuleContextWithOptions */
/**
* @param {string} str
*/
const camelCase = (str) => {
return str
.replace(/[-_]/g, ' ')
.split(' ')
.map((word, index) => (index === 0 ? word : upperFirst(word)))
.join('');
};
/**
* @param {string} value
* @returns {string}
*/
const convertPathToImportName = (value) => {
const fullFileName = value.split('/').pop() || '';
const fileType = fullFileName.split('.').pop();
const fileName = fullFileName.replace(`.${fileType}`, '');
return camelCase(fileName) + upperFirst(fileType);
};
/**
* @param {import('@typescript-eslint/utils/ts-eslint').RuleFixer} fixer
* @param {import('@typescript-eslint/utils').TSESTree.StringLiteral} node
* @param {RuleContextWithOptions} context
*/
function getImageImportFixers(fixer, node, context) {
const { value: importPath } = node;
const pathWithoutPublic = importPath.replace('public/', '');
/** e.g. public/img/checkbox.png -> checkboxPng */
const imageImportName = convertPathToImportName(importPath);
const body = context.sourceCode.ast.body;
const existingImport = body.find(
(node) => node.type === AST_NODE_TYPES.ImportDeclaration && node.source.value === pathWithoutPublic
);
const fixers = [];
// If there's no existing import at all, add a fixer for this
if (!existingImport) {
const importStatementFixer = fixer.insertTextBefore(
body[0],
`import ${imageImportName} from '${pathWithoutPublic}';\n`
);
fixers.push(importStatementFixer);
}
const isInAttribute = node.parent.type === AST_NODE_TYPES.JSXAttribute;
const variableReplacement = isInAttribute ? `{${imageImportName}}` : imageImportName;
const variableFixer = fixer.replaceText(node, variableReplacement);
fixers.push(variableFixer);
return fixers;
}
/**
* @param {import('@typescript-eslint/utils/ts-eslint').RuleFixer} fixer
* @param {import('@typescript-eslint/utils').TSESTree.StringLiteral} node
*/
const replaceWithPublicBuild = (fixer, node) => {
const { value } = node;
const startingQuote = node.raw.startsWith('"') ? '"' : "'";
return fixer.replaceText(
node,
`${startingQuote}${value.replace('public/img/', 'public/build/img/')}${startingQuote}`
);
};
/**
* @param {string} value
*/
const isInvalidImageLocation = (value) => {
return (
value.startsWith('public/img/') ||
(!value.startsWith('public/build/') &&
!value.startsWith('public/plugins/') &&
/public.*(\.svg|\.png|\.jpg|\.jpeg|\.gif)$/.test(value))
);
};
module.exports = {
getImageImportFixers,
replaceWithPublicBuild,
isInvalidImageLocation,
};