1- import type { CoreConfig } from '@code-pushup/models' ;
1+ import type {
2+ CategoryConfig ,
3+ CoreConfig ,
4+ PluginConfig ,
5+ } from '@code-pushup/models' ;
26import { filterItemRefsBy } from '@code-pushup/utils' ;
7+ import {
8+ applyFilters ,
9+ extractSkippedItems ,
10+ filterPluginsFromCategories ,
11+ filterSkippedItems ,
12+ isValidCategoryRef ,
13+ } from './filter.middleware.utils.js' ;
314import type { FilterOptions , Filterables } from './filter.model.js' ;
415import {
516 handleConflictingOptions ,
617 validateFilterOption ,
718 validateFinalState ,
19+ validateSkippedCategories ,
820} from './validate-filter-options.utils.js' ;
921
22+ // eslint-disable-next-line max-lines-per-function
1023export function filterMiddleware < T extends FilterOptions > (
1124 originalProcessArgs : T ,
1225) : T {
1326 const {
14- plugins ,
15- categories ,
27+ categories : rcCategories ,
28+ plugins : rcPlugins ,
1629 skipCategories = [ ] ,
1730 onlyCategories = [ ] ,
1831 skipPlugins = [ ] ,
1932 onlyPlugins = [ ] ,
2033 verbose = false ,
2134 } = originalProcessArgs ;
2235
36+ const plugins = filterSkippedInPlugins ( rcPlugins ) ;
37+ const categories = filterSkippedCategories ( rcCategories , plugins ) ;
38+
2339 if (
2440 skipCategories . length === 0 &&
2541 onlyCategories . length === 0 &&
2642 skipPlugins . length === 0 &&
2743 onlyPlugins . length === 0
2844 ) {
29- return originalProcessArgs ;
45+ if ( rcCategories && categories ) {
46+ validateSkippedCategories ( rcCategories , categories , verbose ) ;
47+ }
48+ return {
49+ ...originalProcessArgs ,
50+ ...( categories && { categories } ) ,
51+ plugins,
52+ } ;
3053 }
3154
3255 handleConflictingOptions ( 'categories' , onlyCategories , skipCategories ) ;
3356 handleConflictingOptions ( 'plugins' , onlyPlugins , skipPlugins ) ;
3457
58+ const skippedPlugins = extractSkippedItems ( rcPlugins , plugins ) ;
59+ const skippedCategories = extractSkippedItems ( rcCategories , categories ) ;
60+
3561 const filteredCategories = applyCategoryFilters (
3662 { categories, plugins } ,
37- skipCategories ,
38- onlyCategories ,
39- verbose ,
63+ skippedCategories ,
64+ { skipCategories, onlyCategories, verbose } ,
4065 ) ;
4166 const filteredPlugins = applyPluginFilters (
4267 { categories : filteredCategories , plugins } ,
43- skipPlugins ,
44- onlyPlugins ,
45- verbose ,
68+ skippedPlugins ,
69+ { skipPlugins, onlyPlugins, verbose } ,
4670 ) ;
4771 const finalCategories = filteredCategories
4872 ? filterItemRefsBy ( filteredCategories , ref =>
@@ -52,7 +76,7 @@ export function filterMiddleware<T extends FilterOptions>(
5276
5377 validateFinalState (
5478 { categories : finalCategories , plugins : filteredPlugins } ,
55- { categories, plugins } ,
79+ { categories : rcCategories , plugins : rcPlugins } ,
5680 ) ;
5781
5882 return {
@@ -62,53 +86,37 @@ export function filterMiddleware<T extends FilterOptions>(
6286 } ;
6387}
6488
65- function applyFilters < T > (
66- items : T [ ] ,
67- skipItems : string [ ] ,
68- onlyItems : string [ ] ,
69- key : keyof T ,
70- ) : T [ ] {
71- return items . filter ( item => {
72- const itemKey = item [ key ] as unknown as string ;
73- return (
74- ! skipItems . includes ( itemKey ) &&
75- ( onlyItems . length === 0 || onlyItems . includes ( itemKey ) )
76- ) ;
77- } ) ;
78- }
79-
8089function applyCategoryFilters (
8190 { categories, plugins } : Filterables ,
82- skipCategories : string [ ] ,
83- onlyCategories : string [ ] ,
84- verbose : boolean ,
91+ skippedCategories : string [ ] ,
92+ options : Pick < FilterOptions , 'skipCategories' | 'onlyCategories' | 'verbose' > ,
8593) : CoreConfig [ 'categories' ] {
94+ const { skipCategories = [ ] , onlyCategories = [ ] , verbose = false } = options ;
8695 if (
8796 ( skipCategories . length === 0 && onlyCategories . length === 0 ) ||
88- ! categories ||
89- categories . length === 0
97+ ( ( ! categories || categories . length === 0 ) && skippedCategories . length === 0 )
9098 ) {
9199 return categories ;
92100 }
93101 validateFilterOption (
94102 'skipCategories' ,
95103 { plugins, categories } ,
96- { itemsToFilter : skipCategories , verbose } ,
104+ { itemsToFilter : skipCategories , skippedItems : skippedCategories , verbose } ,
97105 ) ;
98106 validateFilterOption (
99107 'onlyCategories' ,
100108 { plugins, categories } ,
101- { itemsToFilter : onlyCategories , verbose } ,
109+ { itemsToFilter : onlyCategories , skippedItems : skippedCategories , verbose } ,
102110 ) ;
103- return applyFilters ( categories , skipCategories , onlyCategories , 'slug' ) ;
111+ return applyFilters ( categories ?? [ ] , skipCategories , onlyCategories , 'slug' ) ;
104112}
105113
106114function applyPluginFilters (
107115 { categories, plugins } : Filterables ,
108- skipPlugins : string [ ] ,
109- onlyPlugins : string [ ] ,
110- verbose : boolean ,
116+ skippedPlugins : string [ ] ,
117+ options : Pick < FilterOptions , 'skipPlugins' | 'onlyPlugins' | 'verbose' > ,
111118) : CoreConfig [ 'plugins' ] {
119+ const { skipPlugins = [ ] , onlyPlugins = [ ] , verbose = false } = options ;
112120 const filteredPlugins = filterPluginsFromCategories ( {
113121 categories,
114122 plugins,
@@ -119,25 +127,43 @@ function applyPluginFilters(
119127 validateFilterOption (
120128 'skipPlugins' ,
121129 { plugins : filteredPlugins , categories } ,
122- { itemsToFilter : skipPlugins , verbose } ,
130+ { itemsToFilter : skipPlugins , skippedItems : skippedPlugins , verbose } ,
123131 ) ;
124132 validateFilterOption (
125133 'onlyPlugins' ,
126134 { plugins : filteredPlugins , categories } ,
127- { itemsToFilter : onlyPlugins , verbose } ,
135+ { itemsToFilter : onlyPlugins , skippedItems : skippedPlugins , verbose } ,
128136 ) ;
129137 return applyFilters ( filteredPlugins , skipPlugins , onlyPlugins , 'slug' ) ;
130138}
131139
132- function filterPluginsFromCategories ( {
133- categories,
134- plugins,
135- } : Filterables ) : CoreConfig [ 'plugins' ] {
136- if ( ! categories || categories . length === 0 ) {
137- return plugins ;
138- }
139- const validPluginSlugs = new Set (
140- categories . flatMap ( category => category . refs . map ( ref => ref . plugin ) ) ,
141- ) ;
142- return plugins . filter ( plugin => validPluginSlugs . has ( plugin . slug ) ) ;
140+ export function filterSkippedInPlugins (
141+ plugins : PluginConfig [ ] ,
142+ ) : PluginConfig [ ] {
143+ return plugins . map ( ( plugin : PluginConfig ) => {
144+ const filteredAudits = filterSkippedItems ( plugin . audits ) ;
145+ return {
146+ ...plugin ,
147+ ...( plugin . groups && {
148+ groups : filterItemRefsBy ( filterSkippedItems ( plugin . groups ) , ref =>
149+ filteredAudits . some ( ( { slug } ) => slug === ref . slug ) ,
150+ ) ,
151+ } ) ,
152+ audits : filteredAudits ,
153+ } ;
154+ } ) ;
155+ }
156+
157+ export function filterSkippedCategories (
158+ categories : CoreConfig [ 'categories' ] ,
159+ plugins : CoreConfig [ 'plugins' ] ,
160+ ) : CoreConfig [ 'categories' ] {
161+ return categories
162+ ?. map ( category => {
163+ const validRefs = category . refs . filter ( ref =>
164+ isValidCategoryRef ( ref , plugins ) ,
165+ ) ;
166+ return validRefs . length > 0 ? { ...category , refs : validRefs } : null ;
167+ } )
168+ . filter ( ( category ) : category is CategoryConfig => category != null ) ;
143169}
0 commit comments