From 60582af5f41b69b09b75ba9e3fffefde991657d0 Mon Sep 17 00:00:00 2001 From: Chris Date: Sat, 9 Nov 2024 10:56:09 +0100 Subject: [PATCH] chore: check nested tsconfigs --- src/utils.ts | 61 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index ef6657b..0f8709f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,8 @@ import type { DtsGenerationConfig } from './types' import { readdir } from 'node:fs/promises' -import { extname, join } from 'node:path' +import { dirname, extname, isAbsolute, join, resolve } from 'node:path' import process from 'node:process' +import { pathToFileURL } from 'node:url' import { config } from './config' export async function writeToFile(filePath: string, content: string): Promise { @@ -20,17 +21,67 @@ export async function getAllTypeScriptFiles(directory?: string): Promise extname(file) === '.ts') } +// only checks for 2 potentially nested levels export async function checkIsolatedDeclarations(options?: DtsGenerationConfig): Promise { try { const cwd = options?.cwd || process.cwd() const tsconfigPath = options?.tsconfigPath || join(cwd, 'tsconfig.json') - const tsconfig = await import(tsconfigPath) - return tsconfig.compilerOptions?.isolatedDeclarations === true + // Convert to file URL for import() + const baseConfigPath = pathToFileURL(tsconfigPath).href + const baseConfig = await import(baseConfigPath) + + if (baseConfig.compilerOptions?.isolatedDeclarations === true) { + return true + } + + // If there's an extends property, we need to check the extended config + if (baseConfig.extends) { + // Make the extended path absolute relative to the base config + const extendedPath = makeAbsolute(tsconfigPath, baseConfig.extends) + // Add .json if not present + const fullExtendedPath = extendedPath.endsWith('.json') ? extendedPath : `${extendedPath}.json` + const extendedConfigPath = pathToFileURL(fullExtendedPath).href + const extendedConfig = await import(extendedConfigPath) + + // Recursively check extended configs + if (extendedConfig.compilerOptions?.isolatedDeclarations === true) { + return true + } + + // If the extended config also extends another config, check that too + if (extendedConfig.extends) { + // Make the next extended path absolute relative to the previous extended config + const nextExtendedPath = makeAbsolute(fullExtendedPath, extendedConfig.extends) + const fullNextExtendedPath = nextExtendedPath.endsWith('.json') ? nextExtendedPath : `${nextExtendedPath}.json` + const extendedExtendedConfigPath = pathToFileURL(fullNextExtendedPath).href + const extendedExtendedConfig = await import(extendedExtendedConfigPath) + + if (extendedExtendedConfig.compilerOptions?.isolatedDeclarations === true) { + return true + } + } + } + + return false } + // eslint-disable-next-line unused-imports/no-unused-vars catch (error) { - // eslint-disable-next-line no-console - console.log('Error reading tsconfig.json:', error) return false } } + +function makeAbsolute(basePath: string, configPath: string): string { + // If it's already absolute, return as is + if (isAbsolute(configPath)) { + return configPath + } + + // If it starts with a dot, resolve relative to base path + if (configPath.startsWith('.')) { + return resolve(dirname(basePath), configPath) + } + + // For node_modules paths, resolve from cwd + return resolve(process.cwd(), 'node_modules', configPath) +}