@@ -4,6 +4,9 @@ import { z } from 'zod';
44import type {
55 CategoryConfig ,
66 CoreConfig ,
7+ PersistConfig ,
8+ PluginConfig ,
9+ UploadConfig ,
710} from './packages/models/src/index.js' ;
811import coveragePlugin , {
912 getNxCoveragePaths ,
@@ -265,3 +268,148 @@ export const coverageCoreConfigNx = async (
265268 categories : coverageCategories ,
266269 } ;
267270} ;
271+
272+ export function mergeConfigs (
273+ config : CoreConfig ,
274+ ...configs : Partial < CoreConfig > [ ]
275+ ) : CoreConfig {
276+ return configs . reduce < CoreConfig > (
277+ ( acc , obj ) => ( {
278+ ...acc ,
279+ ...mergeCategories ( acc . categories , obj . categories ) ,
280+ ...mergePlugins ( acc . plugins , obj . plugins ) ,
281+ ...mergePersist ( acc . persist , obj . persist ) ,
282+ ...mergeUpload ( acc . upload , obj . upload ) ,
283+ } ) ,
284+ config ,
285+ ) ;
286+ }
287+
288+ function mergeCategories (
289+ a : CategoryConfig [ ] | undefined ,
290+ b : CategoryConfig [ ] | undefined ,
291+ ) : Pick < CoreConfig , 'categories' > {
292+ if ( ! a && ! b ) {
293+ return { } ;
294+ }
295+
296+ const mergedMap = new Map < string , CategoryConfig > ( ) ;
297+
298+ const addToMap = ( categories : CategoryConfig [ ] ) => {
299+ categories . forEach ( newObject => {
300+ if ( mergedMap . has ( newObject . slug ) ) {
301+ const existingObject : CategoryConfig | undefined = mergedMap . get (
302+ newObject . slug ,
303+ ) ;
304+
305+ mergedMap . set ( newObject . slug , {
306+ ...existingObject ,
307+ ...newObject ,
308+
309+ refs : mergeByUniqueCategoryRefCombination (
310+ existingObject ?. refs ,
311+ newObject . refs ,
312+ ) ,
313+ } ) ;
314+ } else {
315+ mergedMap . set ( newObject . slug , newObject ) ;
316+ }
317+ } ) ;
318+ } ;
319+
320+ if ( a ) {
321+ addToMap ( a ) ;
322+ }
323+ if ( b ) {
324+ addToMap ( b ) ;
325+ }
326+
327+ // Convert the map back to an array
328+ return { categories : [ ...mergedMap . values ( ) ] } ;
329+ }
330+
331+ function mergePlugins (
332+ a : PluginConfig [ ] | undefined ,
333+ b : PluginConfig [ ] | undefined ,
334+ ) : Pick < CoreConfig , 'plugins' > {
335+ if ( ! a && ! b ) {
336+ return { plugins : [ ] } ;
337+ }
338+
339+ const mergedMap = new Map < string , PluginConfig > ( ) ;
340+
341+ const addToMap = ( plugins : PluginConfig [ ] ) => {
342+ plugins . forEach ( newObject => {
343+ mergedMap . set ( newObject . slug , newObject ) ;
344+ } ) ;
345+ } ;
346+
347+ if ( a ) {
348+ addToMap ( a ) ;
349+ }
350+ if ( b ) {
351+ addToMap ( b ) ;
352+ }
353+
354+ return { plugins : [ ...mergedMap . values ( ) ] } ;
355+ }
356+
357+ function mergePersist (
358+ a : PersistConfig | undefined ,
359+ b : PersistConfig | undefined ,
360+ ) : Pick < CoreConfig , 'persist' > {
361+ if ( ! a && ! b ) {
362+ return { } ;
363+ }
364+
365+ if ( a ) {
366+ return b ? { persist : { ...a , ...b } } : { } ;
367+ } else {
368+ return { persist : b } ;
369+ }
370+ }
371+
372+ function mergeByUniqueCategoryRefCombination <
373+ T extends { slug : string ; type : string ; plugin : string } ,
374+ > ( a : T [ ] | undefined , b : T [ ] | undefined ) {
375+ const map = new Map < string , T > ( ) ;
376+
377+ const addToMap = ( refs : T [ ] ) => {
378+ refs . forEach ( ref => {
379+ const uniqueIdentification = `${ ref . type } :${ ref . plugin } :${ ref . slug } ` ;
380+ if ( map . has ( uniqueIdentification ) ) {
381+ map . set ( uniqueIdentification , {
382+ ...map . get ( uniqueIdentification ) ,
383+ ...ref ,
384+ } ) ;
385+ } else {
386+ map . set ( uniqueIdentification , ref ) ;
387+ }
388+ } ) ;
389+ } ;
390+
391+ // Add objects from both arrays to the map
392+ if ( a ) {
393+ addToMap ( a ) ;
394+ }
395+ if ( b ) {
396+ addToMap ( b ) ;
397+ }
398+
399+ return [ ...map . values ( ) ] ;
400+ }
401+
402+ function mergeUpload (
403+ a : UploadConfig | undefined ,
404+ b : UploadConfig | undefined ,
405+ ) : Pick < CoreConfig , 'upload' > {
406+ if ( ! a && ! b ) {
407+ return { } ;
408+ }
409+
410+ if ( a ) {
411+ return b ? { upload : { ...a , ...b } } : { } ;
412+ } else {
413+ return { upload : b } ;
414+ }
415+ }
0 commit comments