11import type { DtsGenerationConfig } from './types'
22import { readdir } from 'node:fs/promises'
3- import { extname , join } from 'node:path'
3+ import { dirname , extname , isAbsolute , join , resolve } from 'node:path'
44import process from 'node:process'
5+ import { pathToFileURL } from 'node:url'
56import { config } from './config'
67
78export async function writeToFile ( filePath : string , content : string ) : Promise < void > {
@@ -20,17 +21,67 @@ export async function getAllTypeScriptFiles(directory?: string): Promise<string[
2021 return Array . prototype . concat ( ...files ) . filter ( file => extname ( file ) === '.ts' )
2122}
2223
24+ // only checks for 2 potentially nested levels
2325export async function checkIsolatedDeclarations ( options ?: DtsGenerationConfig ) : Promise < boolean > {
2426 try {
2527 const cwd = options ?. cwd || process . cwd ( )
2628 const tsconfigPath = options ?. tsconfigPath || join ( cwd , 'tsconfig.json' )
27- const tsconfig = await import ( tsconfigPath )
2829
29- return tsconfig . compilerOptions ?. isolatedDeclarations === true
30+ // Convert to file URL for import()
31+ const baseConfigPath = pathToFileURL ( tsconfigPath ) . href
32+ const baseConfig = await import ( baseConfigPath )
33+
34+ if ( baseConfig . compilerOptions ?. isolatedDeclarations === true ) {
35+ return true
36+ }
37+
38+ // If there's an extends property, we need to check the extended config
39+ if ( baseConfig . extends ) {
40+ // Make the extended path absolute relative to the base config
41+ const extendedPath = makeAbsolute ( tsconfigPath , baseConfig . extends )
42+ // Add .json if not present
43+ const fullExtendedPath = extendedPath . endsWith ( '.json' ) ? extendedPath : `${ extendedPath } .json`
44+ const extendedConfigPath = pathToFileURL ( fullExtendedPath ) . href
45+ const extendedConfig = await import ( extendedConfigPath )
46+
47+ // Recursively check extended configs
48+ if ( extendedConfig . compilerOptions ?. isolatedDeclarations === true ) {
49+ return true
50+ }
51+
52+ // If the extended config also extends another config, check that too
53+ if ( extendedConfig . extends ) {
54+ // Make the next extended path absolute relative to the previous extended config
55+ const nextExtendedPath = makeAbsolute ( fullExtendedPath , extendedConfig . extends )
56+ const fullNextExtendedPath = nextExtendedPath . endsWith ( '.json' ) ? nextExtendedPath : `${ nextExtendedPath } .json`
57+ const extendedExtendedConfigPath = pathToFileURL ( fullNextExtendedPath ) . href
58+ const extendedExtendedConfig = await import ( extendedExtendedConfigPath )
59+
60+ if ( extendedExtendedConfig . compilerOptions ?. isolatedDeclarations === true ) {
61+ return true
62+ }
63+ }
64+ }
65+
66+ return false
3067 }
68+ // eslint-disable-next-line unused-imports/no-unused-vars
3169 catch ( error ) {
32- // eslint-disable-next-line no-console
33- console . log ( 'Error reading tsconfig.json:' , error )
3470 return false
3571 }
3672}
73+
74+ function makeAbsolute ( basePath : string , configPath : string ) : string {
75+ // If it's already absolute, return as is
76+ if ( isAbsolute ( configPath ) ) {
77+ return configPath
78+ }
79+
80+ // If it starts with a dot, resolve relative to base path
81+ if ( configPath . startsWith ( '.' ) ) {
82+ return resolve ( dirname ( basePath ) , configPath )
83+ }
84+
85+ // For node_modules paths, resolve from cwd
86+ return resolve ( process . cwd ( ) , 'node_modules' , configPath )
87+ }
0 commit comments