/** * ESLint rule to enforce ViewDataBuilder import paths * * ViewDataBuilders in lib/builders/view-data/ must: * 1. Import DTO types from lib/types/generated/ * 2. Import ViewData types from lib/view-data/ */ module.exports = { meta: { type: 'problem', docs: { description: 'Enforce ViewDataBuilder import paths', category: 'Builders', recommended: true, }, fixable: null, schema: [], messages: { invalidDtoImport: 'ViewDataBuilders must import DTO types from lib/types/generated/, not from {{importPath}}', invalidViewDataImport: 'ViewDataBuilders must import ViewData types from lib/view-data/, not from {{importPath}}', noViewModelsInBuilders: 'ViewDataBuilders must not import ViewModels. ViewModels are client-only logic wrappers. Builders should only produce plain ViewData.', missingDtoImport: 'ViewDataBuilders must import DTO types from lib/types/generated/', missingViewDataImport: 'ViewDataBuilders must import ViewData types from lib/view-data/', }, }, create(context) { const filename = context.getFilename(); const isInViewDataBuilders = filename.includes('/lib/builders/view-data/'); if (!isInViewDataBuilders) return {}; let hasDtoImport = false; let hasViewDataImport = false; let dtoImportPath = null; let viewDataImportPath = null; return { ImportDeclaration(node) { const importPath = node.source.value; // Check for DTO imports (should be from lib/types/generated/) if (importPath.includes('/lib/types/')) { if (!importPath.includes('/lib/types/generated/')) { dtoImportPath = importPath; context.report({ node, messageId: 'invalidDtoImport', data: { importPath }, }); } else { hasDtoImport = true; } } // Check for ViewData imports (should be from lib/view-data/) if (importPath.includes('/lib/view-data/')) { hasViewDataImport = true; viewDataImportPath = importPath; } }, 'Program:exit'() { if (!hasDtoImport) { context.report({ node: context.getSourceCode().ast, messageId: 'missingDtoImport', }); } if (!hasViewDataImport) { context.report({ node: context.getSourceCode().ast, messageId: 'missingViewDataImport', }); } }, }; }, };