@@ -12,30 +12,10 @@ import { existsSync } from 'node:fs';
1212import { writeFile } from 'node:fs/promises' ;
1313import { join } from 'node:path' ;
1414import { cosmiconfigSync } from 'cosmiconfig' ;
15+ import { CONFIG_DEFAULTS } from '../config/core.js' ;
1516import { loadGlobalConfig , saveGlobalConfig } from '../utils/global-config.js' ;
1617import * as output from '../utils/output.js' ;
1718
18- /**
19- * Default configuration values
20- */
21- let DEFAULT_CONFIG = {
22- comparison : {
23- threshold : 2.0 ,
24- minClusterSize : 2 ,
25- } ,
26- server : {
27- port : 47392 ,
28- timeout : 30000 ,
29- } ,
30- build : {
31- name : 'Build {timestamp}' ,
32- environment : 'test' ,
33- } ,
34- tdd : {
35- openReport : false ,
36- } ,
37- } ;
38-
3919/**
4020 * Create a config service instance
4121 * @param {Object } options
@@ -77,7 +57,7 @@ export function createConfigService({ workingDir }) {
7757 * Get merged configuration with source tracking
7858 */
7959 async function getMergedConfig ( ) {
80- let config = { ... DEFAULT_CONFIG } ;
60+ let config = cloneConfigValue ( CONFIG_DEFAULTS ) ;
8161 let sources = { } ;
8262
8363 // Layer 1: Global config
@@ -102,18 +82,17 @@ export function createConfigService({ workingDir }) {
10282
10383 // Layer 3: Environment variables
10484 if ( process . env . VIZZLY_THRESHOLD ) {
105- config . comparison . threshold = parseFloat ( process . env . VIZZLY_THRESHOLD ) ;
85+ config . comparison . threshold = Number ( process . env . VIZZLY_THRESHOLD ) ;
10686 sources . comparison = 'env' ;
10787 }
10888 if ( process . env . VIZZLY_MIN_CLUSTER_SIZE ) {
109- config . comparison . minClusterSize = parseInt (
110- process . env . VIZZLY_MIN_CLUSTER_SIZE ,
111- 10
89+ config . comparison . minClusterSize = Number (
90+ process . env . VIZZLY_MIN_CLUSTER_SIZE
11291 ) ;
11392 sources . comparison = 'env' ;
11493 }
11594 if ( process . env . VIZZLY_PORT ) {
116- config . server . port = parseInt ( process . env . VIZZLY_PORT , 10 ) ;
95+ config . server . port = Number ( process . env . VIZZLY_PORT ) ;
11796 sources . server = 'env' ;
11897 }
11998
@@ -240,7 +219,11 @@ export default defineConfig(${JSON.stringify(newConfig, null, 2)});
240219 // Validate threshold
241220 if ( config . comparison ?. threshold !== undefined ) {
242221 let threshold = config . comparison . threshold ;
243- if ( typeof threshold !== 'number' || threshold < 0 ) {
222+ if (
223+ typeof threshold !== 'number' ||
224+ ! Number . isFinite ( threshold ) ||
225+ threshold < 0
226+ ) {
244227 errors . push ( 'comparison.threshold must be a non-negative number' ) ;
245228 } else if ( threshold > 100 ) {
246229 warnings . push (
@@ -299,7 +282,7 @@ export default defineConfig(${JSON.stringify(newConfig, null, 2)});
299282 * Deep merge two objects
300283 */
301284function mergeDeep ( target , source ) {
302- let result = { ... target } ;
285+ let result = cloneConfigValue ( target ) ;
303286
304287 for ( let key in source ) {
305288 if (
@@ -308,6 +291,8 @@ function mergeDeep(target, source) {
308291 ! Array . isArray ( source [ key ] )
309292 ) {
310293 result [ key ] = mergeDeep ( result [ key ] || { } , source [ key ] ) ;
294+ } else if ( Array . isArray ( source [ key ] ) ) {
295+ result [ key ] = [ ...source [ key ] ] ;
311296 } else {
312297 result [ key ] = source [ key ] ;
313298 }
@@ -316,21 +301,45 @@ function mergeDeep(target, source) {
316301 return result ;
317302}
318303
304+ function cloneConfigValue ( value ) {
305+ if ( Array . isArray ( value ) ) {
306+ return value . map ( cloneConfigValue ) ;
307+ }
308+
309+ if ( value && typeof value === 'object' ) {
310+ let clone = { } ;
311+ for ( let key in value ) {
312+ clone [ key ] = cloneConfigValue ( value [ key ] ) ;
313+ }
314+ return clone ;
315+ }
316+
317+ return value ;
318+ }
319+
319320/**
320321 * Merge config with source tracking
321322 */
322- function mergeWithTracking ( target , source , sources , sourceName ) {
323+ function mergeWithTracking ( target , source , sources , sourceName , sectionName ) {
323324 for ( let key in source ) {
325+ let sourceSection = sectionName || key ;
326+
324327 if (
325328 source [ key ] &&
326329 typeof source [ key ] === 'object' &&
327330 ! Array . isArray ( source [ key ] )
328331 ) {
329332 if ( ! target [ key ] ) target [ key ] = { } ;
330- mergeWithTracking ( target [ key ] , source [ key ] , sources , sourceName ) ;
333+ mergeWithTracking (
334+ target [ key ] ,
335+ source [ key ] ,
336+ sources ,
337+ sourceName ,
338+ sourceSection
339+ ) ;
331340 } else {
332341 target [ key ] = source [ key ] ;
333- sources [ key ] = sourceName ;
342+ sources [ sourceSection ] = sourceName ;
334343 }
335344 }
336345}
0 commit comments