From 7bb0293155d573bd65ea8d47cb99a93ed08ac9b4 Mon Sep 17 00:00:00 2001 From: Leon Schiffler <11432983+Monkeylordz@users.noreply.github.com> Date: Sat, 26 Jul 2025 18:06:33 -0700 Subject: [PATCH 1/4] Add ability for api-extractor-scenarios to customize the extractor compiler options --- build-tests/run-scenarios-helpers/src/index.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/build-tests/run-scenarios-helpers/src/index.ts b/build-tests/run-scenarios-helpers/src/index.ts index 97c7ed20fe3..7fc8b403099 100644 --- a/build-tests/run-scenarios-helpers/src/index.ts +++ b/build-tests/run-scenarios-helpers/src/index.ts @@ -30,6 +30,7 @@ export async function runScenariosAsync( { libFolderPath, additionalApiExtractorConfig, afterApiExtractorAsync }: IRunScenariosOptions ): Promise { const entryPoints: string[] = []; + const scenariosWithCustomCompilerOptions: string[] = []; const scenarioFolderNames: string[] = []; const folderItems: FolderItem[] = await FileSystem.readFolderItemsAsync(libFolderPath); @@ -56,6 +57,10 @@ export async function runScenariosAsync( } } + if (apiExtractorJsonOverrides && 'compiler' in apiExtractorJsonOverrides) { + scenariosWithCustomCompilerOptions.push(scenarioFolderName); + } + const apiExtractorJson: {} = { $schema: 'https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json', @@ -93,7 +98,7 @@ export async function runScenariosAsync( { concurrency: 10 } ); - let compilerState: CompilerState | undefined = undefined; + let baseCompilerState: CompilerState | undefined = undefined; for (const scenarioFolderName of scenarioFolderNames) { logger.terminal.writeLine(`Scenario: ${scenarioFolderName}`); @@ -101,10 +106,19 @@ export async function runScenariosAsync( const apiExtractorJsonPath: string = `${buildFolderPath}/temp/configs/api-extractor-${scenarioFolderName}.json`; const extractorConfig: ExtractorConfig = ExtractorConfig.loadFileAndPrepare(apiExtractorJsonPath); - if (!compilerState) { + let compilerState: CompilerState; + if (scenariosWithCustomCompilerOptions.includes(scenarioFolderName)) { + logger.terminal.writeLine(`Using custom compiler state (${scenarioFolderName})`); compilerState = CompilerState.create(extractorConfig, { additionalEntryPoints: entryPoints }); + } else { + if (!baseCompilerState) { + baseCompilerState = CompilerState.create(extractorConfig, { + additionalEntryPoints: entryPoints + }); + } + compilerState = baseCompilerState; } const extractorResult: ExtractorResult = Extractor.invoke(extractorConfig, { From 6ce7f0fa08ce541ae6c3300ebbcc6406a0c54eeb Mon Sep 17 00:00:00 2001 From: Leon Schiffler <11432983+Monkeylordz@users.noreply.github.com> Date: Sat, 26 Jul 2025 18:08:53 -0700 Subject: [PATCH 2/4] Add api-extractor-scenarios "bundlerModuleResolution" scenario --- .../api-extractor-scenarios.api.json | 206 ++++++++++++++++++ .../api-extractor-scenarios.api.md | 14 ++ .../etc/bundlerModuleResolution/rollup.d.ts | 8 + .../config/api-extractor-overrides.json | 5 + .../config/tsconfig.json | 7 + .../src/bundlerModuleResolution/index.ts | 6 + .../src/bundlerModuleResolution/other.ts | 3 + 7 files changed, 249 insertions(+) create mode 100644 build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/api-extractor-scenarios.api.json create mode 100644 build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/api-extractor-scenarios.api.md create mode 100644 build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/rollup.d.ts create mode 100644 build-tests/api-extractor-scenarios/src/bundlerModuleResolution/config/api-extractor-overrides.json create mode 100644 build-tests/api-extractor-scenarios/src/bundlerModuleResolution/config/tsconfig.json create mode 100644 build-tests/api-extractor-scenarios/src/bundlerModuleResolution/index.ts create mode 100644 build-tests/api-extractor-scenarios/src/bundlerModuleResolution/other.ts diff --git a/build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/api-extractor-scenarios.api.json new file mode 100644 index 00000000000..792380c3cb6 --- /dev/null +++ b/build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/api-extractor-scenarios.api.json @@ -0,0 +1,206 @@ +{ + "metadata": { + "toolPackage": "@microsoft/api-extractor", + "toolVersion": "[test mode]", + "schemaVersion": 1011, + "oldestForwardsCompatibleVersion": 1001, + "tsdocConfig": { + "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", + "noStandardTags": true, + "tagDefinitions": [ + { + "tagName": "@alpha", + "syntaxKind": "modifier" + }, + { + "tagName": "@beta", + "syntaxKind": "modifier" + }, + { + "tagName": "@defaultValue", + "syntaxKind": "block" + }, + { + "tagName": "@decorator", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@deprecated", + "syntaxKind": "block" + }, + { + "tagName": "@eventProperty", + "syntaxKind": "modifier" + }, + { + "tagName": "@example", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@experimental", + "syntaxKind": "modifier" + }, + { + "tagName": "@inheritDoc", + "syntaxKind": "inline" + }, + { + "tagName": "@internal", + "syntaxKind": "modifier" + }, + { + "tagName": "@label", + "syntaxKind": "inline" + }, + { + "tagName": "@link", + "syntaxKind": "inline", + "allowMultiple": true + }, + { + "tagName": "@override", + "syntaxKind": "modifier" + }, + { + "tagName": "@packageDocumentation", + "syntaxKind": "modifier" + }, + { + "tagName": "@param", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@privateRemarks", + "syntaxKind": "block" + }, + { + "tagName": "@public", + "syntaxKind": "modifier" + }, + { + "tagName": "@readonly", + "syntaxKind": "modifier" + }, + { + "tagName": "@remarks", + "syntaxKind": "block" + }, + { + "tagName": "@returns", + "syntaxKind": "block" + }, + { + "tagName": "@sealed", + "syntaxKind": "modifier" + }, + { + "tagName": "@see", + "syntaxKind": "block" + }, + { + "tagName": "@throws", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@typeParam", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@virtual", + "syntaxKind": "modifier" + }, + { + "tagName": "@betaDocumentation", + "syntaxKind": "modifier" + }, + { + "tagName": "@internalRemarks", + "syntaxKind": "block" + }, + { + "tagName": "@preapproved", + "syntaxKind": "modifier" + } + ], + "supportForTags": { + "@alpha": true, + "@beta": true, + "@defaultValue": true, + "@decorator": true, + "@deprecated": true, + "@eventProperty": true, + "@example": true, + "@experimental": true, + "@inheritDoc": true, + "@internal": true, + "@label": true, + "@link": true, + "@override": true, + "@packageDocumentation": true, + "@param": true, + "@privateRemarks": true, + "@public": true, + "@readonly": true, + "@remarks": true, + "@returns": true, + "@sealed": true, + "@see": true, + "@throws": true, + "@typeParam": true, + "@virtual": true, + "@betaDocumentation": true, + "@internalRemarks": true, + "@preapproved": true + }, + "reportUnsupportedHtmlElements": false + } + }, + "kind": "Package", + "canonicalReference": "api-extractor-scenarios!", + "docComment": "", + "name": "api-extractor-scenarios", + "preserveMemberOrder": false, + "members": [ + { + "kind": "EntryPoint", + "canonicalReference": "api-extractor-scenarios!", + "name": "", + "preserveMemberOrder": false, + "members": [ + { + "kind": "Variable", + "canonicalReference": "api-extractor-scenarios!reexport:var", + "docComment": "/**\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "reexport: " + }, + { + "kind": "Content", + "text": "import(\"./other\")." + }, + { + "kind": "Reference", + "text": "Foo", + "canonicalReference": "api-extractor-scenarios!~Foo:class" + } + ], + "fileUrlPath": "src/bundlerModuleResolution/index.ts", + "isReadonly": true, + "releaseTag": "Public", + "name": "reexport", + "variableTypeTokenRange": { + "startIndex": 1, + "endIndex": 3 + } + } + ] + } + ] +} diff --git a/build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/api-extractor-scenarios.api.md b/build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/api-extractor-scenarios.api.md new file mode 100644 index 00000000000..6f4c89dcf73 --- /dev/null +++ b/build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/api-extractor-scenarios.api.md @@ -0,0 +1,14 @@ +## API Report File for "api-extractor-scenarios" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { Foo } from './other'; + +// @public (undocumented) +export const reexport: Foo; + +// (No @packageDocumentation comment for this package) + +``` diff --git a/build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/rollup.d.ts b/build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/rollup.d.ts new file mode 100644 index 00000000000..951348ae8be --- /dev/null +++ b/build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/rollup.d.ts @@ -0,0 +1,8 @@ +import { Foo } from './other'; + +/** + * @public + */ +export declare const reexport: Foo; + +export { } diff --git a/build-tests/api-extractor-scenarios/src/bundlerModuleResolution/config/api-extractor-overrides.json b/build-tests/api-extractor-scenarios/src/bundlerModuleResolution/config/api-extractor-overrides.json new file mode 100644 index 00000000000..01d3d35df03 --- /dev/null +++ b/build-tests/api-extractor-scenarios/src/bundlerModuleResolution/config/api-extractor-overrides.json @@ -0,0 +1,5 @@ +{ + "compiler": { + "tsconfigFilePath": "/src/bundlerModuleResolution/config/tsconfig.json" + } +} diff --git a/build-tests/api-extractor-scenarios/src/bundlerModuleResolution/config/tsconfig.json b/build-tests/api-extractor-scenarios/src/bundlerModuleResolution/config/tsconfig.json new file mode 100644 index 00000000000..337ccda7424 --- /dev/null +++ b/build-tests/api-extractor-scenarios/src/bundlerModuleResolution/config/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "module": "esnext", + "moduleResolution": "bundler" + } +} diff --git a/build-tests/api-extractor-scenarios/src/bundlerModuleResolution/index.ts b/build-tests/api-extractor-scenarios/src/bundlerModuleResolution/index.ts new file mode 100644 index 00000000000..5587838462e --- /dev/null +++ b/build-tests/api-extractor-scenarios/src/bundlerModuleResolution/index.ts @@ -0,0 +1,6 @@ +import { foo } from './other'; + +/** + * @public + */ +export const reexport = foo; diff --git a/build-tests/api-extractor-scenarios/src/bundlerModuleResolution/other.ts b/build-tests/api-extractor-scenarios/src/bundlerModuleResolution/other.ts new file mode 100644 index 00000000000..a047a632f4d --- /dev/null +++ b/build-tests/api-extractor-scenarios/src/bundlerModuleResolution/other.ts @@ -0,0 +1,3 @@ +export class Foo {} + +export const foo = new Foo(); From ff4ffe5e62bf8f7809fe3fd5f47170e411737b50 Mon Sep 17 00:00:00 2001 From: Leon Schiffler <11432983+Monkeylordz@users.noreply.github.com> Date: Sat, 26 Jul 2025 19:28:00 -0700 Subject: [PATCH 3/4] [api-extractor] Fix ExportAnalyzer unable to resolve type import declaration with LiteralTypeNode argument --- apps/api-extractor/src/analyzer/ExportAnalyzer.ts | 5 ++++- .../bundlerModuleResolution/api-extractor-scenarios.api.md | 4 ++-- .../etc/bundlerModuleResolution/rollup.d.ts | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/api-extractor/src/analyzer/ExportAnalyzer.ts b/apps/api-extractor/src/analyzer/ExportAnalyzer.ts index d8a68a2b76c..c92d817e7bf 100644 --- a/apps/api-extractor/src/analyzer/ExportAnalyzer.ts +++ b/apps/api-extractor/src/analyzer/ExportAnalyzer.ts @@ -264,9 +264,12 @@ export class ExportAnalyzer { importOrExportDeclaration: ts.ImportDeclaration | ts.ExportDeclaration | ts.ImportTypeNode, moduleSpecifier: string ): boolean { - const specifier: ts.TypeNode | ts.Expression | undefined = ts.isImportTypeNode(importOrExportDeclaration) + let specifier: ts.TypeNode | ts.Expression | undefined = ts.isImportTypeNode(importOrExportDeclaration) ? importOrExportDeclaration.argument : importOrExportDeclaration.moduleSpecifier; + if (specifier && ts.isLiteralTypeNode(specifier)) { + specifier = specifier.literal; + } const mode: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext | undefined = specifier && ts.isStringLiteralLike(specifier) ? TypeScriptInternals.getModeForUsageLocation( diff --git a/build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/api-extractor-scenarios.api.md b/build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/api-extractor-scenarios.api.md index 6f4c89dcf73..49848c6f755 100644 --- a/build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/api-extractor-scenarios.api.md +++ b/build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/api-extractor-scenarios.api.md @@ -4,8 +4,8 @@ ```ts -import { Foo } from './other'; - +// Warning: (ae-forgotten-export) The symbol "Foo" needs to be exported by the entry point index.d.ts +// // @public (undocumented) export const reexport: Foo; diff --git a/build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/rollup.d.ts b/build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/rollup.d.ts index 951348ae8be..e5eff73d8ab 100644 --- a/build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/rollup.d.ts +++ b/build-tests/api-extractor-scenarios/etc/bundlerModuleResolution/rollup.d.ts @@ -1,4 +1,5 @@ -import { Foo } from './other'; +declare class Foo { +} /** * @public From b16743fd6e33728e063c522a221020380397e0ee Mon Sep 17 00:00:00 2001 From: Leon Schiffler <11432983+Monkeylordz@users.noreply.github.com> Date: Sat, 26 Jul 2025 19:30:46 -0700 Subject: [PATCH 4/4] rush change --- ...lordz-scenario-compiler-state_2025-07-27-02-30.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 common/changes/@microsoft/api-extractor/monkeylordz-scenario-compiler-state_2025-07-27-02-30.json diff --git a/common/changes/@microsoft/api-extractor/monkeylordz-scenario-compiler-state_2025-07-27-02-30.json b/common/changes/@microsoft/api-extractor/monkeylordz-scenario-compiler-state_2025-07-27-02-30.json new file mode 100644 index 00000000000..6faa2661fdb --- /dev/null +++ b/common/changes/@microsoft/api-extractor/monkeylordz-scenario-compiler-state_2025-07-27-02-30.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@microsoft/api-extractor", + "comment": "Fixes a bug in ExtractorAnalyzer._isExternalModulePath where type import declarations were not resolved.", + "type": "patch" + } + ], + "packageName": "@microsoft/api-extractor" +} \ No newline at end of file