From 5a674b95f1d081daa5a788e91a84d8eb45b96bcc Mon Sep 17 00:00:00 2001 From: Martin Hochel Date: Tue, 10 Aug 2021 19:29:37 +0200 Subject: [PATCH] fix(scripts): resolve api-extractor execution issue within packages with new DX --- scripts/tasks/api-extractor.ts | 84 +++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/scripts/tasks/api-extractor.ts b/scripts/tasks/api-extractor.ts index cd535ecbbdf395..e78fc410b69cb2 100644 --- a/scripts/tasks/api-extractor.ts +++ b/scripts/tasks/api-extractor.ts @@ -1,6 +1,10 @@ +import fs from 'fs'; import * as glob from 'glob'; import * as path from 'path'; -import { apiExtractorVerifyTask, task, series } from 'just-scripts'; +import jju from 'jju'; +import { apiExtractorVerifyTask, task, series, resolveCwd, logger, TscTaskOptions } from 'just-scripts'; + +const noop = () => {}; const apiExtractorConfigs = glob .sync(path.join(process.cwd(), 'config/api-extractor*.json')) @@ -14,10 +18,86 @@ export function apiExtractor() { return apiExtractorConfigs.length ? series( ...apiExtractorConfigs.map(([configPath, configName]) => { + // note we have `"strictNullChecks": false,` turned off - so from TS point of view this always returns API 🚨 + const overrideApi = overrideExtractorConfigForPackagesWithTsPathAliases({ + apiExtractorConfigPath: configPath, + tsConfigPath: resolveCwd('./tsconfig.json'), + }); + + const cleanupOverrides = overrideApi ? overrideApi.resetConfig : () => noop; + const taskName = `api-extractor:${configName}`; - task(taskName, apiExtractorVerifyTask({ configJsonFilePath: configPath, localBuild })); + + task( + taskName, + series( + () => { + overrideApi && overrideApi.overrideConfig(); + }, + () => { + try { + return apiExtractorVerifyTask({ configJsonFilePath: configPath, localBuild }); + } catch (err) { + cleanupOverrides(); + console.error(err); + process.exit(1); + } + }, + () => { + cleanupOverrides(); + }, + ), + ); + return taskName; }), ) : 'no-op'; } + +interface TsConfig { + extends?: string; + + /** + * typescript doesn't provide a correct type for the compiler options file + * -> (typescript.CompilerOptions has enum values instead of raw options in some cases) + */ + compilerOptions: TscTaskOptions; + include?: string[]; + exclude?: string[]; +} + +function overrideExtractorConfigForPackagesWithTsPathAliases(options: { + tsConfigPath: string; + apiExtractorConfigPath: string; +}) { + const tsConfig: TsConfig = jju.parse(fs.readFileSync(options.tsConfigPath, 'utf-8')); + const shouldOverrideConfig = Boolean(tsConfig.extends); + + if (!shouldOverrideConfig) { + return null; + } + + logger.info(`📣 API-EXTRACTOR: package is using TS path aliases. Overriding ts compiler settings for api-extractor.`); + + const originalContent = fs.readFileSync(options.apiExtractorConfigPath, 'utf-8'); + const apiExtractorConfigOriginal = jju.parse(originalContent, { mode: 'json' }); + + tsConfig.compilerOptions.baseUrl = '.'; + apiExtractorConfigOriginal.compiler = { + overrideTsconfig: tsConfig, + }; + + const api = { + overrideConfig: () => { + const newContent = jju.update(originalContent, apiExtractorConfigOriginal, { mode: 'json', indent: 2 }); + + fs.writeFileSync(options.apiExtractorConfigPath, newContent, 'utf-8'); + }, + resetConfig: () => { + fs.writeFileSync(options.apiExtractorConfigPath, originalContent, 'utf-8'); + }, + }; + + return api; +}