website refactor

This commit is contained in:
2026-01-14 11:38:05 +01:00
parent 0d89ad027e
commit 02073f19ef
3 changed files with 300 additions and 10 deletions

View File

@@ -63,6 +63,38 @@ module.exports = {
},
},
// Rule 8: No 'use client' directive in templates
'no-use-client-in-templates': {
meta: {
type: 'problem',
docs: {
description: 'Forbid use client directive in templates',
category: 'Template Purity',
},
messages: {
message: 'Templates must not use "use client" directive - they should be stateless composition',
},
},
create(context) {
const filename = context.getFilename();
const isInTemplates = filename.includes('/templates/');
if (!isInTemplates) return {};
return {
ExpressionStatement(node) {
if (node.expression.type === 'Literal' &&
node.expression.value === 'use client') {
context.report({
node,
messageId: 'message',
});
}
},
};
},
},
// Rule 3: No computations in templates
'no-computations-in-templates': {
meta: {

View File

@@ -35,11 +35,18 @@ module.exports = {
if (!isInUi) return {};
let hasStateHooks = false;
let hasEffectHooks = false;
let hasContext = false;
return {
// Check for 'use client' directive
ExpressionStatement(node) {
if (node.expression.type === 'Literal' &&
node.expression.value === 'use client') {
context.report({
node,
messageId: 'noStateInUi',
});
}
},
// Check for state hooks
CallExpression(node) {
if (node.callee.type !== 'Identifier') return;
@@ -48,7 +55,6 @@ module.exports = {
// State management hooks
if (['useState', 'useReducer', 'useRef'].includes(hookName)) {
hasStateHooks = true;
context.report({
node,
messageId: 'noStateInUi',
@@ -57,7 +63,6 @@ module.exports = {
// Effect hooks
if (['useEffect', 'useLayoutEffect', 'useInsertionEffect'].includes(hookName)) {
hasEffectHooks = true;
context.report({
node,
messageId: 'noSideEffects',
@@ -66,7 +71,6 @@ module.exports = {
// Context (can introduce state)
if (hookName === 'useContext') {
hasContext = true;
context.report({
node,
messageId: 'noStateInUi',
@@ -76,8 +80,8 @@ module.exports = {
// Check for class components with state
ClassDeclaration(node) {
if (node.superClass &&
node.superClass.type === 'Identifier' &&
if (node.superClass &&
node.superClass.type === 'Identifier' &&
node.superClass.name === 'Component') {
context.report({
node,
@@ -90,7 +94,7 @@ module.exports = {
AssignmentExpression(node) {
if (node.left.type === 'MemberExpression' &&
node.left.property.type === 'Identifier' &&
(node.left.property.name === 'state' ||
(node.left.property.name === 'state' ||
node.left.property.name === 'setState')) {
context.report({
node,