Files
Toju/tools/eslint-rules.js
Myx 79c6f91cd6 chore: enforce lint across codebase and ban "maybe" in identifiers
Remove member-ordering and complexity eslint-disable comments by reordering
class members and applying targeted fixes. Add metoyou/no-maybe-in-naming,
type-safe WebRTC e2e harness helpers, and resolve remaining lint errors so
npm run lint exits cleanly.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-11 11:08:26 +02:00

180 lines
5.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Custom ESLint rules shared across the workspace.
const FORBIDDEN_UNICODE_SYMBOLS = Object.freeze([
{ char: '\u2013', name: 'Unicode en dash ()', replacement: '-' },
{ char: '\u2014', name: 'Unicode em dash (—)', replacement: '-' },
{ char: '\u2026', name: 'Unicode ellipsis (…)', replacement: '...' },
{ char: '\u2192', name: 'Unicode right arrow (→)', replacement: '->' },
{ char: '\u2190', name: 'Unicode left arrow (←)', replacement: '<-' },
{ char: '\u2194', name: 'Unicode left-right arrow (↔)', replacement: '<->' },
{ char: '\u21d2', name: 'Unicode right double arrow (⇒)', replacement: '=>' },
{ char: '\u21d0', name: 'Unicode left double arrow (⇐)', replacement: '<=' },
{ char: '\u21d4', name: 'Unicode left-right double arrow (⇔)', replacement: '<=>' }
]);
function createReplaceFix(range, replacement) {
return (fixer) => fixer.replaceTextRange(range, replacement);
}
const MAYBE_PATTERN = /maybe/i;
function identifierContainsMaybe(name) {
return typeof name === 'string' && MAYBE_PATTERN.test(name);
}
function checkIdentifier(context, node, name) {
if (!identifierContainsMaybe(name))
return;
context.report({
node,
messageId: 'noMaybeInNaming',
data: { name }
});
}
module.exports = {
rules: {
'angular-template-spacing': {
meta: {
type: 'layout',
docs: {
description: 'Enforce spacing between elements and property grouping in Angular templates',
category: 'Stylistic Issues',
recommended: true
},
fixable: 'whitespace',
schema: []
},
create() {
// This is a placeholder for custom rule implementation.
// ESLint's template rules are limited, so manual formatting is recommended.
return {};
}
},
'no-maybe-in-naming': {
meta: {
type: 'suggestion',
docs: {
description: 'Disallow the word "maybe" in identifiers (variables, functions, classes, parameters)'
},
schema: [],
messages: {
noMaybeInNaming: 'Identifier "{{name}}" must not contain "maybe". Use an explicit name that states intent.'
}
},
create(context) {
const reportDefinition = (node, name) => checkIdentifier(context, node, name);
return {
VariableDeclarator(node) {
if (node.id.type === 'Identifier')
reportDefinition(node.id, node.id.name);
},
FunctionDeclaration(node) {
if (node.id)
reportDefinition(node.id, node.id.name);
},
ClassDeclaration(node) {
if (node.id)
reportDefinition(node.id, node.id.name);
},
MethodDefinition(node) {
if (node.key.type === 'Identifier')
reportDefinition(node.key, node.key.name);
},
PropertyDefinition(node) {
if (node.key.type === 'Identifier')
reportDefinition(node.key, node.key.name);
},
TSInterfaceDeclaration(node) {
reportDefinition(node.id, node.id.name);
},
TSTypeAliasDeclaration(node) {
reportDefinition(node.id, node.id.name);
},
TSMethodSignature(node) {
if (node.key.type === 'Identifier')
reportDefinition(node.key, node.key.name);
},
TSPropertySignature(node) {
if (node.key.type === 'Identifier')
reportDefinition(node.key, node.key.name);
},
TSParameterProperty(node) {
if (node.parameter.type === 'Identifier')
reportDefinition(node.parameter, node.parameter.name);
},
'FunctionDeclaration > Identifier[id]': function onParam(node) {
reportDefinition(node, node.name);
},
'FunctionExpression > Identifier[id]': function onParam(node) {
reportDefinition(node, node.name);
},
'ArrowFunctionExpression > Identifier[id]': function onParam(node) {
reportDefinition(node, node.name);
}
};
}
},
'no-unicode-symbols': {
meta: {
type: 'suggestion',
docs: {
description: 'Disallow AI/LLM-style Unicode symbols in source files'
},
fixable: 'code',
hasSuggestions: true,
schema: [],
messages: {
forbiddenSymbol: '{{name}} is not allowed. Use ASCII "{{replacement}}" instead.',
replaceSymbol: 'Replace with "{{replacement}}"'
}
},
create(context) {
const sourceCode = context.getSourceCode();
return {
Program() {
const sourceText = sourceCode.getText();
for (const symbol of FORBIDDEN_UNICODE_SYMBOLS) {
let index = sourceText.indexOf(symbol.char);
while (index !== -1) {
const range = [index, index + symbol.char.length];
const loc = {
start: sourceCode.getLocFromIndex(range[0]),
end: sourceCode.getLocFromIndex(range[1])
};
context.report({
loc,
messageId: 'forbiddenSymbol',
data: {
name: symbol.name,
replacement: symbol.replacement
},
fix: createReplaceFix(range, symbol.replacement),
suggest: [
{
messageId: 'replaceSymbol',
data: {
replacement: symbol.replacement
},
fix: createReplaceFix(range, symbol.replacement)
}
]
});
index = sourceText.indexOf(symbol.char, index + symbol.char.length);
}
}
}
};
}
}
},
FORBIDDEN_UNICODE_SYMBOLS
};