website refactor
This commit is contained in:
108
apps/website/eslint-rules/lib-no-next-imports.js
Normal file
108
apps/website/eslint-rules/lib-no-next-imports.js
Normal file
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* ESLint rule to forbid Next.js imports in lib/ directory
|
||||
*
|
||||
* The lib/ directory should be framework-agnostic.
|
||||
* Next.js imports (redirect, cookies, headers, etc.) should only be in app/ directory.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Forbid Next.js imports in lib/ directory',
|
||||
category: 'Architecture',
|
||||
recommended: true,
|
||||
},
|
||||
fixable: null,
|
||||
schema: [],
|
||||
messages: {
|
||||
noNextImports: 'Next.js imports are forbidden in lib/ directory. Found: {{import}} from "{{source}}"',
|
||||
noNextRedirect: 'redirect() must be used in app/ directory, not lib/ directory',
|
||||
noNextCookies: 'cookies() must be used in app/ directory, not lib/ directory',
|
||||
noNextHeaders: 'headers() must be used in app/ directory, not lib/ directory',
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const filename = context.getFilename();
|
||||
const isInLib = filename.includes('/lib/');
|
||||
|
||||
// Skip if not in lib directory
|
||||
if (!isInLib) return {};
|
||||
|
||||
return {
|
||||
// Track import statements
|
||||
ImportDeclaration(node) {
|
||||
const source = node.source.value;
|
||||
|
||||
// Check for Next.js imports
|
||||
if (source === 'next/navigation' ||
|
||||
source === 'next/headers' ||
|
||||
source === 'next/cookies' ||
|
||||
source === 'next/router' ||
|
||||
source === 'next/link' ||
|
||||
source === 'next/image' ||
|
||||
source === 'next/script' ||
|
||||
source === 'next/dynamic') {
|
||||
|
||||
// Check for specific named imports
|
||||
node.specifiers.forEach(spec => {
|
||||
if (spec.type === 'ImportSpecifier') {
|
||||
const imported = spec.imported.name;
|
||||
|
||||
if (imported === 'redirect') {
|
||||
context.report({
|
||||
node: spec,
|
||||
messageId: 'noNextRedirect',
|
||||
});
|
||||
} else if (imported === 'cookies') {
|
||||
context.report({
|
||||
node: spec,
|
||||
messageId: 'noNextCookies',
|
||||
});
|
||||
} else if (imported === 'headers') {
|
||||
context.report({
|
||||
node: spec,
|
||||
messageId: 'noNextHeaders',
|
||||
});
|
||||
} else {
|
||||
context.report({
|
||||
node: spec,
|
||||
messageId: 'noNextImports',
|
||||
data: { import: imported, source },
|
||||
});
|
||||
}
|
||||
} else if (spec.type === 'ImportDefaultSpecifier') {
|
||||
context.report({
|
||||
node: spec,
|
||||
messageId: 'noNextImports',
|
||||
data: { import: 'default', source },
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// Also check for require() calls
|
||||
CallExpression(node) {
|
||||
if (node.callee.type === 'Identifier' && node.callee.name === 'require') {
|
||||
if (node.arguments.length > 0 && node.arguments[0].type === 'Literal') {
|
||||
const source = node.arguments[0].value;
|
||||
|
||||
if (source === 'next/navigation' ||
|
||||
source === 'next/headers' ||
|
||||
source === 'next/cookies' ||
|
||||
source === 'next/router') {
|
||||
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'noNextImports',
|
||||
data: { import: 'require()', source },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user