/** * ESLint rule to enforce View Data Builder contract implementation * * View Data Builders in lib/builders/view-data/ must: * 1. Be classes named *ViewDataBuilder * 2. Have a static build() method * * Note: 'implements' is deprecated in favor of 'satisfies' checked in view-data-builder-contract.js */ module.exports = { meta: { type: 'problem', docs: { description: 'Enforce View Data Builder contract implementation', category: 'Builders', recommended: true, }, fixable: null, schema: [], messages: { notAClass: 'View Data Builders must be classes named *ViewDataBuilder', missingBuildMethod: 'View Data Builders must have a static build() method', }, }, create(context) { const filename = context.getFilename(); const isInViewDataBuilders = filename.includes('/lib/builders/view-data/'); if (!isInViewDataBuilders) return {}; let hasBuildMethod = false; return { // Check class declaration ClassDeclaration(node) { const className = node.id?.name; if (!className || !className.endsWith('ViewDataBuilder')) { context.report({ node, messageId: 'notAClass', }); } // Check for static build method const buildMethod = node.body.body.find(member => member.type === 'MethodDefinition' && member.key.type === 'Identifier' && member.key.name === 'build' && member.static === true ); if (buildMethod) { hasBuildMethod = true; } }, 'Program:exit'() { if (!hasBuildMethod) { context.report({ node: context.getSourceCode().ast, messageId: 'missingBuildMethod', }); } }, }; }, };