Created
November 14, 2024 22:59
-
-
Save LeCoupa/a0904b48986536a7eff6cef482c407eb to your computer and use it in GitHub Desktop.
ESLint custom rule to enforce consistent indentation in i18n blocks in .vue files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Check our product https://www.thecompaniesapi.com/ | |
import type { Rule } from 'eslint' | |
const rule: Rule.RuleModule = { | |
meta: { | |
docs: { | |
category: 'Best Practices', | |
description: 'Enforce consistent indentation in i18n blocks', | |
recommended: true, | |
}, | |
fixable: 'whitespace', | |
messages: { | |
indentError: 'Invalid indentation for i18n content. Expected {{expected}} spaces.', | |
invalidJson: 'Invalid JSON in i18n block: {{error}}', | |
}, | |
schema: [], | |
type: 'problem', | |
}, | |
create(context) { | |
if (!context.filename.endsWith('.vue')) { | |
return {} | |
} | |
return { | |
Program() { | |
const source = context.sourceCode.getText() | |
const i18nMatch = source.match(/(<i18n\s+lang=["']json["']>)([\s\S]*?)(<\/i18n>)/i) | |
if (i18nMatch) { | |
const startOffset = i18nMatch.index! + i18nMatch[1].length | |
const i18nContent = i18nMatch[2] | |
try { | |
const parsed = JSON.parse(i18nContent.trim()) | |
const totalSpaces = 2 | |
// Format the content with proper indentation | |
const formattedContent = `\n${JSON.stringify(parsed, null, totalSpaces)}\n` | |
// Compare the trimmed versions to check for actual content differences | |
if (formattedContent.trim() !== i18nContent.trim()) { | |
context.report({ | |
data: { expected: String(totalSpaces) }, | |
fix(fixer) { | |
return fixer.replaceTextRange( | |
[startOffset, startOffset + i18nContent.length], | |
formattedContent, | |
) | |
}, | |
loc: { | |
end: context.sourceCode.getLocFromIndex(startOffset + i18nContent.length), | |
start: context.sourceCode.getLocFromIndex(startOffset), | |
}, | |
messageId: 'indentError', | |
}) | |
} | |
} | |
catch (error: any) { | |
context.report({ | |
data: { error: error.message }, | |
loc: { | |
end: context.sourceCode.getLocFromIndex(startOffset + i18nContent.length), | |
start: context.sourceCode.getLocFromIndex(startOffset), | |
}, | |
messageId: 'invalidJson', | |
}) | |
} | |
} | |
}, | |
} | |
}, | |
} | |
export default rule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment