11import fs from 'fs' ;
22import path from 'path' ;
33import yaml from 'js-yaml' ;
4+ import { z } from 'astro:content' ;
45
5- interface SiteConfig {
6- sections : {
7- about : boolean ;
8- workExperience : boolean ;
9- talks : boolean ;
10- writing : boolean ;
11- socialLinks : boolean ;
12- } ;
13- elements : {
14- avatar : boolean ;
15- themeSwitch : boolean ;
16- header : boolean ;
17- footer : boolean ;
18- } ;
19- }
6+ const SiteConfigSchema = z . object ( {
7+ sections : z . object ( {
8+ about : z . boolean ( ) ,
9+ workExperience : z . boolean ( ) ,
10+ talks : z . boolean ( ) ,
11+ writing : z . boolean ( ) ,
12+ socialLinks : z . boolean ( ) ,
13+ } ) ,
14+ elements : z . object ( {
15+ avatar : z . boolean ( ) ,
16+ themeSwitch : z . boolean ( ) ,
17+ header : z . boolean ( ) ,
18+ footer : z . boolean ( ) ,
19+ } ) ,
20+ } ) ;
21+
22+ type SiteConfig = z . infer < typeof SiteConfigSchema > ;
2023
2124const defaultConfig : SiteConfig = {
2225 sections : {
@@ -55,42 +58,8 @@ function deepMerge(target: any, source: any): any {
5558 return target ;
5659}
5760
58- function isValidConfig ( config : any ) : boolean {
59- if (
60- ! config ||
61- typeof config !== 'object' ||
62- ! config . sections ||
63- typeof config . sections !== 'object' ||
64- ! config . elements ||
65- typeof config . elements !== 'object'
66- ) {
67- return false ;
68- }
69- // Optionally, check for required keys
70- const sectionKeys = [
71- 'about' ,
72- 'workExperience' ,
73- 'talks' ,
74- 'writing' ,
75- 'socialLinks' ,
76- ] ;
77- const elementKeys = [
78- 'avatar' ,
79- 'themeSwitch' ,
80- 'header' ,
81- 'footer' ,
82- ] ;
83- for ( const key of sectionKeys ) {
84- if ( typeof config . sections [ key ] !== 'boolean' ) {
85- return false ;
86- }
87- }
88- for ( const key of elementKeys ) {
89- if ( typeof config . elements [ key ] !== 'boolean' ) {
90- return false ;
91- }
92- }
93- return true ;
61+ function isValidConfig ( config : SiteConfig ) : config is SiteConfig {
62+ return SiteConfigSchema . safeParse ( config ) . success ;
9463}
9564
9665export function getSiteConfig ( ) : SiteConfig {
@@ -100,23 +69,32 @@ export function getSiteConfig(): SiteConfig {
10069 const fileContents = fs . readFileSync ( configPath , 'utf8' ) ;
10170 loadedConfig = yaml . load ( fileContents ) ;
10271 if ( ! loadedConfig || typeof loadedConfig !== 'object' ) {
103- console . warn ( 'config.yml is empty or not a valid YAML object, using defaults' ) ;
72+ console . warn (
73+ 'config.yml is empty or not a valid YAML object, using defaults' ,
74+ ) ;
10475 return defaultConfig ;
10576 }
10677 // Merge loaded config with defaults
10778 const mergedConfig = deepMerge ( loadedConfig , defaultConfig ) ;
10879 if ( ! isValidConfig ( mergedConfig ) ) {
109- console . warn ( 'config.yml is malformed or missing required fields, using defaults' ) ;
80+ console . warn (
81+ 'config.yml is malformed or missing required fields, using defaults' ,
82+ ) ;
11083 return defaultConfig ;
11184 }
11285 return mergedConfig as SiteConfig ;
11386 } catch ( error : any ) {
11487 if ( error . code === 'ENOENT' ) {
11588 console . warn ( 'config.yml not found, using defaults' ) ;
116- } else if ( error . name === 'YAMLException' || error instanceof yaml . YAMLException ) {
89+ } else if (
90+ error . name === 'YAMLException' ||
91+ error instanceof yaml . YAMLException
92+ ) {
11793 console . warn ( 'config.yml is malformed YAML, using defaults' ) ;
11894 } else {
119- console . warn ( `Error loading config.yml: ${ error . message } , using defaults` ) ;
95+ console . warn (
96+ `Error loading config.yml: ${ error . message } , using defaults` ,
97+ ) ;
12098 }
12199 return defaultConfig ;
122100 }
0 commit comments