website refactor
This commit is contained in:
167
apps/website/eslint-rules/page-query-rules.js
Normal file
167
apps/website/eslint-rules/page-query-rules.js
Normal file
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* ESLint rules for Page Query Guardrails
|
||||
*
|
||||
* Enforces page query contracts and boundaries
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// Rule 1: No null returns in page queries
|
||||
'no-null-returns-in-page-queries': {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Forbid null returns in page queries',
|
||||
category: 'Page Query',
|
||||
},
|
||||
messages: {
|
||||
message: 'PageQueries must return PageQueryResult union, not null',
|
||||
},
|
||||
},
|
||||
create(context) {
|
||||
return {
|
||||
ReturnStatement(node) {
|
||||
if (node.argument &&
|
||||
node.argument.type === 'Literal' &&
|
||||
node.argument.value === null &&
|
||||
!isInComment(node)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'message',
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
// Rule 2: Invalid page query filename
|
||||
'invalid-page-query-filename': {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Enforce correct page query filename',
|
||||
category: 'Page Query',
|
||||
},
|
||||
messages: {
|
||||
message: 'PageQuery files must end with PageQuery.ts',
|
||||
},
|
||||
},
|
||||
create(context) {
|
||||
const filename = context.getFilename();
|
||||
if (filename.includes('/page-queries/') && !filename.endsWith('PageQuery.ts')) {
|
||||
context.report({
|
||||
loc: { line: 1, column: 0 },
|
||||
messageId: 'message',
|
||||
});
|
||||
}
|
||||
return {};
|
||||
},
|
||||
},
|
||||
|
||||
// Rule 3: PageQuery must implement contract
|
||||
'pagequery-must-implement-contract': {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Enforce PageQuery interface implementation',
|
||||
category: 'Page Query',
|
||||
},
|
||||
messages: {
|
||||
message: 'PageQuery class must implement PageQuery<TPageDto, TParams> interface',
|
||||
},
|
||||
},
|
||||
create(context) {
|
||||
return {
|
||||
ClassDeclaration(node) {
|
||||
const className = node.id?.name;
|
||||
if (className && className.endsWith('PageQuery')) {
|
||||
if (!node.implements ||
|
||||
!node.implements.some(impl =>
|
||||
impl.expression.type === 'GenericIdentifier' &&
|
||||
impl.expression.name === 'PageQuery')) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'message',
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
// Rule 4: PageQuery must have execute method
|
||||
'pagequery-must-have-execute': {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Enforce PageQuery execute method',
|
||||
category: 'Page Query',
|
||||
},
|
||||
messages: {
|
||||
message: 'PageQuery class must have execute(params) method',
|
||||
},
|
||||
},
|
||||
create(context) {
|
||||
return {
|
||||
ClassDeclaration(node) {
|
||||
const className = node.id?.name;
|
||||
if (className && className.endsWith('PageQuery')) {
|
||||
const hasExecute = node.body.body.some(member =>
|
||||
member.type === 'MethodDefinition' &&
|
||||
member.key.type === 'Identifier' &&
|
||||
member.key.name === 'execute'
|
||||
);
|
||||
|
||||
if (!hasExecute) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'message',
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
// Rule 5: PageQuery execute return type
|
||||
'pagequery-execute-return-type': {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Enforce PageQuery execute return type',
|
||||
category: 'Page Query',
|
||||
},
|
||||
messages: {
|
||||
message: 'PageQuery execute() must return Promise<PageQueryResult<TPageDto>>',
|
||||
},
|
||||
},
|
||||
create(context) {
|
||||
return {
|
||||
MethodDefinition(node) {
|
||||
if (node.key.type === 'Identifier' &&
|
||||
node.key.name === 'execute' &&
|
||||
node.value.type === 'FunctionExpression') {
|
||||
|
||||
const returnType = node.value.returnType;
|
||||
if (!returnType ||
|
||||
!returnType.typeAnnotation ||
|
||||
!returnType.typeAnnotation.typeName ||
|
||||
returnType.typeAnnotation.typeName.name !== 'Promise') {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'message',
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// Helper functions
|
||||
function isInComment(node) {
|
||||
return false;
|
||||
}
|
||||
Reference in New Issue
Block a user