import { Linter } from "eslint" ; import { generateTestESLintConfig , getTestESLintDependencies } from "generator/test-framework" ; import { generateTypescriptESLintConfig , getTypescriptESLintDependencies } from "generator/typescript" ; import { generateEnvESLintConfig } from "generator/env" ; import { generateFrontFrameworkESLintConfig , getFrontFrameworkESLintDependencies } from "generator/front-framework" ; import { cleanPrettierConfig , generatePrettierESlintConfig , getPrettierESLintDependencies } from "generator/prettier" ; import { eslintBaseConfig , eslintBaseDependencies } from "generator/base-configs/eslintBaseConfig" ; import { ESLintDependencyGenerator , ESLintGenerator } from "generator/types" ; import { areArraysEqual , mergeArrays , pipe } from "utils/utility" ; import { ProjectInfoObject } from "types" ; function addEslintOverride ( overrides , newOverride ) { if ( overrides . length === 0 ) { return [ newOverride ] ; } const [ currentOverride , ... rest ] = overrides ; const areOverrideFilesEqual = areArraysEqual ( typeof currentOverride . files === "string" ? [ currentOverride . files ] : currentOverride . files , typeof newOverride . files === "string" ? [ newOverride . files ] : newOverride . files ) ; if ( currentOverride . parser === newOverride . parser || areOverrideFilesEqual ) { return [ concatConfig ( newOverride ) ( currentOverride ) , ... rest ] ; } return [ currentOverride , ... addEslintOverride ( rest , newOverride ) ] ; } function concatEslintOverrides ( prevOverrides , nextOverrides ) { return nextOverrides . reduce ( addEslintOverride , prevOverrides ) ; } function concatESlintObjects < T extends Record < string , unknown > > ( prevObject , nextObject ) { return { ... prevObject , ... nextObject } ; } function shouldKeepConfigEntry ( configEntry ) { const [ _ , value ] = configEntry ; if ( typeof value === "object" && value !== null && Object . keys ( value ) . length === 0 ) { return false ; } return true ; } function cleanObjectConfig < T > ( config ) { const entries = Object . entries ( config ) ; const cleanEntries = entries . filter ( shouldKeepConfigEntry ) ; return Object . fromEntries ( cleanEntries ) as T ; } function cleanExtendsValue ( extendsValue , filterPredicate ) { if ( typeof extendsValue === "string" ) { return filterPredicate ( extendsValue ) ? extendsValue : [ ] ; } else { return extendsValue . filter ( filterPredicate ) ; } } function cleanExtendsField < T extends Linter . Config > ( config , filterPredicate ) { const { extends : extendsValue } = config ; if ( extendsValue === undefined ) { return config ; } return { ... config , extends : cleanExtendsValue ( extendsValue , filterPredicate ) , } ; } export function cleanESLintExtendsField ( config , filterPredicate ) { const { overrides , ... rest } = cleanExtendsField ( config , filterPredicate ) ; const cleanOverrides = overrides ?. map ( ( overrideConfig ) => cleanExtendsField ( overrideConfig , filterPredicate ) ) ; if ( overrides ) { return { ... rest , overrides : cleanOverrides } ; } return { ... rest } ; } function clearEmptyFields ( config ) { const { overrides , ... rest } = cleanObjectConfig ( config ) ; const cleanOverrides = overrides ?. map ( cleanObjectConfig ) ; if ( overrides ) { return { ... rest , overrides : cleanOverrides } ; } return { ... rest } ; } function cleanESLintConfig ( config ) { return pipe ( cleanPrettierConfig , clearEmptyFields ) ( config ) ; } function concatESlintArrays ( prev , next ) { const prevArray = typeof prev === "string" ? [ prev ] : prev ; const nextArray = typeof next === "string" ? [ next ] : next ; return mergeArrays ( prevArray , nextArray ) ; } export function concatConfig < T extends Linter . Config | Linter . ConfigOverride > ( config ) { return ( prevConfig ) => ( { ... prevConfig , ... config , extends : concatESlintArrays ( prevConfig . extends ?? [ ] , config . extends ?? [ ] ) , rules : concatESlintObjects ( prevConfig . rules ?? { } , config . rules ?? { } ) , plugins : concatESlintArrays ( prevConfig . plugins ?? [ ] , config . plugins ?? [ ] ) , parserOptions : concatESlintObjects ( prevConfig . parserOptions ?? { } , config . parserOptions ?? { } ) , env : concatESlintObjects ( prevConfig . env ?? { } , config . env ?? { } ) , overrides : concatEslintOverrides ( prevConfig . overrides ?? [ ] , config . overrides ?? [ ] ) , } ) ; } export function concatDependencies ( deps2 ) { return ( deps1 ) => mergeArrays ( deps1 , deps2 ) ; } const generateBaseESLintConfig = ( _userAnswers ) => { return concatConfig ( eslintBaseConfig ) ; } ; const getBaseESLintDependencies = ( _userAnswers ) => concatDependencies ( eslintBaseDependencies ) ; export function generateEslintConfig ( userAnswers , startConfig = { } ) { return pipe ( generateBaseESLintConfig ( userAnswers ) , generateTypescriptESLintConfig ( userAnswers ) , generateEnvESLintConfig ( userAnswers ) , generateTestESLintConfig ( userAnswers ) , generateFrontFrameworkESLintConfig ( userAnswers ) , generatePrettierESlintConfig ( userAnswers ) , cleanESLintConfig ) ( startConfig ) ; } export function getConfigDependencies ( userAnswers ) { return pipe ( getBaseESLintDependencies ( userAnswers ) , getTypescriptESLintDependencies ( userAnswers ) , getTestESLintDependencies ( userAnswers ) , getFrontFrameworkESLintDependencies ( userAnswers ) , getPrettierESLintDependencies ( userAnswers ) ) ( [ ] ) ; }