/** * GridPilot ESLint Rules Plugin * * Comprehensive architectural guardrails converted to ESLint rules * * Usage in .eslintrc.json: * { * "plugins": ["gridpilot-rules"], * "rules": { * "gridpilot-rules/presenter-contract": "error", * "gridpilot-rules/rsc-no-container-manager": "error", * ... * } * } */ const presenterContract = require('./presenter-contract'); const rscBoundaryRules = require('./rsc-boundary-rules'); const templatePurityRules = require('./template-purity-rules'); const displayObjectRules = require('./formatter-rules'); const pageQueryRules = require('./page-query-rules'); const servicesRules = require('./services-rules'); const clientOnlyRules = require('./client-only-rules'); const writeBoundaryRules = require('./write-boundary-rules'); const modelTaxonomyRules = require('./model-taxonomy-rules'); const filenameRules = require('./filename-rules'); const componentNoDataManipulation = require('./component-no-data-manipulation'); const presenterPurity = require('./presenter-purity'); const mutationContract = require('./mutation-contract'); const serverActionsMustUseMutations = require('./server-actions-must-use-mutations'); const viewDataLocation = require('./view-data-location'); const viewDataBuilderContract = require('./view-data-builder-contract'); const singleExportPerFile = require('./single-export-per-file'); const filenameMatchesExport = require('./filename-matches-export'); const pageQueryMustUseBuilders = require('./page-query-must-use-builders'); const pageQueryMustMapErrors = require('./page-query-must-map-errors'); const mutationMustUseBuilders = require('./mutation-must-use-builders'); const mutationMustMapErrors = require('./mutation-must-map-errors'); const serviceFunctionFormat = require('./service-function-format'); const libNoNextImports = require('./lib-no-next-imports'); const servicesNoInstantiation = require('./services-no-instantiation'); const noPageDtosDirectory = require('./no-page-dtos-directory'); const cleanErrorHandling = require('./clean-error-handling'); const servicesImplementContract = require('./services-implement-contract'); const serverActionsReturnResult = require('./server-actions-return-result'); const serverActionsInterface = require('./server-actions-interface'); const noDisplayObjectsInUi = require('./no-display-objects-in-ui'); const viewDataBuilderImplements = require('./view-data-builder-implements'); const viewDataBuilderImports = require('./view-data-builder-imports'); const viewDataImplements = require('./view-data-implements'); const viewModelImplements = require('./view-model-implements'); const viewModelTaxonomy = require('./view-model-taxonomy'); module.exports = { rules: { // Presenter Contract 'presenter-contract': presenterContract, 'presenter-purity': presenterPurity, // RSC Boundary Rules 'rsc-no-container-manager': rscBoundaryRules['no-container-manager-in-server'], 'rsc-no-page-data-fetcher': rscBoundaryRules['no-page-data-fetcher-fetch-in-server'], 'rsc-no-view-models': rscBoundaryRules['no-view-models-in-server'], 'rsc-no-presenters': rscBoundaryRules['no-presenters-in-server'], 'rsc-no-intl': rscBoundaryRules['no-intl-in-presentation'], 'rsc-no-sorting-filtering': rscBoundaryRules['no-sorting-filtering-in-server'], 'rsc-no-display-objects': rscBoundaryRules['no-display-objects-in-server'], 'rsc-no-unsafe-services': rscBoundaryRules['no-unsafe-services-in-server'], 'rsc-no-di': rscBoundaryRules['no-di-in-server'], 'rsc-no-local-helpers': rscBoundaryRules['no-local-helpers-in-server'], 'rsc-no-object-construction': rscBoundaryRules['no-object-construction-in-server'], 'rsc-no-container-manager-calls': rscBoundaryRules['no-container-manager-calls-in-server'], // Template Purity Rules 'template-no-direct-mutations': templatePurityRules['no-view-models-in-templates'], 'template-no-side-effects': templatePurityRules['no-state-hooks-in-templates'], 'template-no-async-render': templatePurityRules['no-computations-in-templates'], 'template-no-external-state': templatePurityRules['no-restricted-imports-in-templates'], 'template-no-global-objects': templatePurityRules['no-invalid-template-signature'], 'template-no-mutation-props': templatePurityRules['no-template-helper-exports'], 'template-no-unsafe-html': require('./template-no-unsafe-html'), // Display Object Rules 'display-no-domain-models': displayObjectRules['no-io-in-display-objects'], 'display-no-business-logic': displayObjectRules['no-non-class-display-exports'], 'formatters-must-return-primitives': displayObjectRules['formatters-must-return-primitives'], 'no-display-objects-in-ui': noDisplayObjectsInUi, // Page Query Rules 'page-query-no-null-returns': pageQueryRules['no-null-returns-in-page-queries'], 'page-query-filename': pageQueryRules['invalid-page-query-filename'], 'page-query-contract': pageQueryRules['pagequery-must-implement-contract'], 'page-query-execute': pageQueryRules['pagequery-must-have-execute'], 'page-query-return-type': pageQueryRules['pagequery-execute-return-type'], 'page-query-must-map-errors': pageQueryMustMapErrors, // Services Rules 'services-no-external-api': servicesRules['no-external-api-in-services'], 'services-must-be-pure': servicesRules['services-must-be-pure'], 'services-must-return-result': cleanErrorHandling, 'services-must-be-marked': servicesImplementContract, // Client-Only Rules 'client-only-no-server-code': clientOnlyRules['no-server-code-in-client-only'], 'client-only-must-have-directive': clientOnlyRules['client-only-must-have-directive'], // Write Boundary Rules 'write-boundary-no-direct-mutations': writeBoundaryRules['no-direct-mutations-in-write-boundaries'], 'write-boundary-must-use-repository': writeBoundaryRules['write-boundaries-must-use-repository'], // Model Taxonomy Rules 'model-no-domain-in-display': modelTaxonomyRules['no-domain-models-in-display-objects'], 'model-no-display-in-domain': modelTaxonomyRules['no-display-objects-in-domain-models'], // Filename Rules 'filename-presenter-match': filenameRules['presenter-filename-must-match-class'], 'filename-service-match': filenameRules['service-filename-must-match-function'], 'filename-display-match': filenameRules['display-filename-must-end-with-display-tsx'], // Component Data Manipulation Rules 'component-no-data-manipulation': componentNoDataManipulation, // Mutation Rules 'mutation-contract': mutationContract, 'mutation-must-use-builders': mutationMustUseBuilders, 'mutation-must-map-errors': mutationMustMapErrors, // Server Actions Rules 'server-actions-must-use-mutations': serverActionsMustUseMutations, 'server-actions-return-result': serverActionsReturnResult, 'server-actions-interface': serverActionsInterface, // View Data Rules 'view-data-location': viewDataLocation, 'view-data-builder-contract': viewDataBuilderContract, 'view-data-builder-implements': viewDataBuilderImplements, 'view-data-builder-imports': viewDataBuilderImports, 'view-data-implements': viewDataImplements, // View Model Rules 'view-model-implements': viewModelImplements, 'view-model-taxonomy': viewModelTaxonomy, // Single Export Rules 'single-export-per-file': singleExportPerFile, 'filename-matches-export': filenameMatchesExport, // Page Query Builder Rules 'page-query-must-use-builders': pageQueryMustUseBuilders, // Service Rules 'service-function-format': serviceFunctionFormat, 'lib-no-next-imports': libNoNextImports, 'services-no-instantiation': servicesNoInstantiation, // Page DTO Rules 'no-page-dtos-directory': noPageDtosDirectory, // Clean Error Handling Rules 'clean-error-handling': cleanErrorHandling, 'services-implement-contract': servicesImplementContract, // Component Architecture Rules 'no-raw-html-in-app': require('./no-raw-html-in-app'), 'ui-element-purity': require('./ui-element-purity'), 'no-nextjs-imports-in-ui': require('./no-nextjs-imports-in-ui'), 'component-classification': require('./component-classification'), // Route Configuration Rules 'no-hardcoded-routes': require('./no-hardcoded-routes'), 'no-hardcoded-search-params': require('./no-hardcoded-search-params'), // Logging Rules 'no-console': require('./no-console'), // Cookies 'no-next-cookies-in-pages': require('./no-next-cookies-in-pages'), // Config 'no-direct-process-env': require('./no-direct-process-env'), // Architecture Rules 'no-index-files': require('./no-index-files'), 'no-use-mutation-in-client': require('./no-use-mutation-in-client'), }, // Configurations for different use cases configs: { // Recommended: All rules enabled recommended: { plugins: ['gridpilot-rules'], rules: { // Presenter 'gridpilot-rules/presenter-contract': 'error', // RSC Boundary 'gridpilot-rules/rsc-no-container-manager': 'error', 'gridpilot-rules/rsc-no-page-data-fetcher': 'error', 'gridpilot-rules/rsc-no-view-models': 'error', 'gridpilot-rules/rsc-no-presenters': 'error', 'gridpilot-rules/rsc-no-intl': 'error', 'gridpilot-rules/rsc-no-sorting-filtering': 'error', 'gridpilot-rules/rsc-no-display-objects': 'error', 'gridpilot-rules/rsc-no-unsafe-services': 'error', 'gridpilot-rules/rsc-no-di': 'error', 'gridpilot-rules/rsc-no-local-helpers': 'error', 'gridpilot-rules/rsc-no-object-construction': 'error', 'gridpilot-rules/rsc-no-container-manager-calls': 'error', // Template Purity 'gridpilot-rules/template-no-direct-mutations': 'error', 'gridpilot-rules/template-no-side-effects': 'error', 'gridpilot-rules/template-no-async-render': 'error', 'gridpilot-rules/template-no-external-state': 'error', 'gridpilot-rules/template-no-global-objects': 'error', 'gridpilot-rules/template-no-mutation-props': 'error', 'gridpilot-rules/template-no-unsafe-html': 'warn', // Display Objects 'gridpilot-rules/display-no-domain-models': 'error', 'gridpilot-rules/display-no-business-logic': 'error', 'gridpilot-rules/formatters-must-return-primitives': 'error', 'gridpilot-rules/no-display-objects-in-ui': 'error', // Page Queries 'gridpilot-rules/page-query-no-null-returns': 'error', 'gridpilot-rules/page-query-filename': 'error', 'gridpilot-rules/page-query-contract': 'error', 'gridpilot-rules/page-query-execute': 'error', 'gridpilot-rules/page-query-return-type': 'error', // Services 'gridpilot-rules/services-no-external-api': 'error', 'gridpilot-rules/services-must-be-pure': 'error', // Client-Only 'gridpilot-rules/client-only-no-server-code': 'error', 'gridpilot-rules/client-only-must-have-directive': 'error', // Write Boundaries 'gridpilot-rules/write-boundary-no-direct-mutations': 'error', 'gridpilot-rules/write-boundary-must-use-repository': 'error', // Model Taxonomy 'gridpilot-rules/model-no-domain-in-display': 'error', 'gridpilot-rules/model-no-display-in-domain': 'error', // Filename 'gridpilot-rules/filename-presenter-match': 'error', 'gridpilot-rules/filename-service-match': 'error', 'gridpilot-rules/filename-display-match': 'error', // Mutations 'gridpilot-rules/mutation-contract': 'error', 'gridpilot-rules/mutation-must-use-builders': 'error', 'gridpilot-rules/mutation-must-map-errors': 'error', // Server Actions 'gridpilot-rules/server-actions-must-use-mutations': 'error', 'gridpilot-rules/server-actions-return-result': 'error', 'gridpilot-rules/server-actions-interface': 'error', // View Data 'gridpilot-rules/view-data-location': 'error', 'gridpilot-rules/view-data-builder-contract': 'error', 'gridpilot-rules/view-data-builder-implements': 'error', 'gridpilot-rules/view-data-builder-imports': 'error', 'gridpilot-rules/view-data-implements': 'error', // View Model 'gridpilot-rules/view-model-builder-contract': 'error', 'gridpilot-rules/view-model-builder-implements': 'error', 'gridpilot-rules/view-model-implements': 'error', // Single Export Rules 'gridpilot-rules/single-export-per-file': 'error', 'gridpilot-rules/filename-matches-export': 'error', // Page Query Builder Rules 'gridpilot-rules/page-query-must-use-builders': 'error', // Service Rules 'gridpilot-rules/service-function-format': 'error', 'gridpilot-rules/lib-no-next-imports': 'error', // Component Architecture Rules 'gridpilot-rules/no-raw-html-in-app': 'warn', 'gridpilot-rules/ui-element-purity': 'error', 'gridpilot-rules/no-nextjs-imports-in-ui': 'error', 'gridpilot-rules/component-classification': 'error', // Route Configuration Rules 'gridpilot-rules/no-hardcoded-routes': 'error', 'gridpilot-rules/no-use-mutation-in-client': 'error', }, }, // Presenter-only: Just the presenter rules presenters: { plugins: ['gridpilot-rules'], rules: { 'gridpilot-rules/presenter-contract': 'error', 'gridpilot-rules/filename-presenter-match': 'error', }, }, // RSC-only: Just RSC boundary rules rsc: { plugins: ['gridpilot-rules'], rules: { 'gridpilot-rules/rsc-no-container-manager': 'error', 'gridpilot-rules/rsc-no-page-data-fetcher': 'error', 'gridpilot-rules/rsc-no-view-models': 'error', 'gridpilot-rules/rsc-no-presenters': 'error', 'gridpilot-rules/rsc-no-intl': 'error', 'gridpilot-rules/rsc-no-sorting-filtering': 'error', 'gridpilot-rules/rsc-no-display-objects': 'error', 'gridpilot-rules/rsc-no-unsafe-services': 'error', 'gridpilot-rules/rsc-no-di': 'error', 'gridpilot-rules/rsc-no-local-helpers': 'error', 'gridpilot-rules/rsc-no-object-construction': 'error', 'gridpilot-rules/rsc-no-container-manager-calls': 'error', }, }, }, };