11/** @typedef  {import('./index').Logger } Logger */ 
22
3+ import  fs  from  'node:fs/promises' 
34import  path  from  'node:path' 
45
56import  debug  from  'debug' 
6- import  {  lilconfig  }  from  'lilconfig' 
77import  YAML  from  'yaml' 
88
99import  {  dynamicImport  }  from  './dynamicImport.js' 
@@ -37,8 +37,10 @@ export const searchPlaces = [
3737] 
3838
3939const  jsonParse  =  ( filePath ,  content )  =>  { 
40+   const  isPackageFile  =  PACKAGE_JSON_FILE . includes ( path . basename ( filePath ) ) 
4041  try  { 
41-     return  JSON . parse ( content ) 
42+     const  json  =  JSON . parse ( content ) 
43+     return  isPackageFile  ? json [ CONFIG_NAME ]  : json 
4244  }  catch  ( error )  { 
4345    if  ( path . basename ( filePath )  ===  PACKAGE_JSON_FILE )  { 
4446      debugLog ( 'Ignoring invalid package file `%s` with content:\n%s' ,  filePath ,  content ) 
@@ -64,6 +66,8 @@ const yamlParse = (filePath, content) => {
6466  } 
6567} 
6668
69+ const  NO_EXT  =  'noExt' 
70+ 
6771/** 
6872 * `lilconfig` doesn't support yaml files by default, 
6973 * so we add custom loaders for those. Files without 
@@ -77,10 +81,31 @@ const loaders = {
7781  '.cjs' : dynamicImport , 
7882  '.yaml' : yamlParse , 
7983  '.yml' : yamlParse , 
80-   noExt : yamlParse , 
84+   [ NO_EXT ] : yamlParse , 
85+ } 
86+ 
87+ const  readFile  =  async  ( filepath )  =>  { 
88+   const  absolutePath  =  path . resolve ( filepath ) 
89+   const  file  =  await  fs . readFile ( absolutePath ) 
90+   return  await  file . toString ( ) 
8191} 
8292
83- const  explorer  =  lilconfig ( CONFIG_NAME ,  {  searchPlaces,  loaders } ) 
93+ const  loadConfigByExt  =  async  ( filepath )  =>  { 
94+   filepath  =  path . resolve ( filepath ) 
95+   const  ext  =  path . extname ( filepath )  ||  NO_EXT 
96+   const  loader  =  loaders [ ext ] 
97+ 
98+   /** 
99+    * No need to read file contents when loader only takes in the filepath argument 
100+    * and reads itself; this is for `lilconfig` compatibility 
101+    */ 
102+   const  content  =  loader . length  >  1  ? await  readFile ( filepath )  : undefined 
103+ 
104+   return  { 
105+     config : await  loader ( filepath ,  content ) , 
106+     filepath, 
107+   } 
108+ } 
84109
85110/** 
86111 * @param  {object } options 
@@ -89,20 +114,22 @@ const explorer = lilconfig(CONFIG_NAME, { searchPlaces, loaders })
89114 */ 
90115export  const  loadConfig  =  async  ( {  configPath,  cwd } ,  logger )  =>  { 
91116  try  { 
117+     let  result 
118+ 
92119    if  ( configPath )  { 
93120      debugLog ( 'Loading configuration from `%s`...' ,  configPath ) 
121+       result  =  await  loadConfigByExt ( resolveConfig ( configPath ) ) 
94122    }  else  { 
95123      debugLog ( 'Searching for configuration from `%s`...' ,  cwd ) 
124+       const  {  lilconfig }  =  await  import ( 'lilconfig' ) 
125+       const  explorer  =  lilconfig ( CONFIG_NAME ,  {  searchPlaces,  loaders } ) 
126+       result  =  await  explorer . search ( cwd ) 
96127    } 
97128
98-     const  result  =  await  ( configPath 
99-       ? explorer . load ( resolveConfig ( configPath ) ) 
100-       : explorer . search ( cwd ) ) 
101- 
102129    if  ( ! result )  return  { } 
103130
104131    // config is a promise when using the `dynamicImport` loader 
105-     const  config  =  await  result . config 
132+     const  config  =  ( await  result . config )   ??   null 
106133    const  filepath  =  result . filepath 
107134
108135    debugLog ( 'Successfully loaded config from `%s`:\n%O' ,  filepath ,  config ) 
0 commit comments