Skip to content

Commit 54c83b6

Browse files
Josmithrexampleoctogonz
authored
[api-extractor] Correctly omit declarations associated with an entity whose release tag does not meet the configured threshold in API reports (#5211)
* test: Repro `export default` bug * fix: Trim all declarations for entities with a release level beneath the threshold * docs: Add changeset * Update common/changes/@microsoft/api-extractor/trim-export-default-from-reports_2025-04-29-00-30.json --------- Co-authored-by: Joshua Smithrud <[email protected]> Co-authored-by: Pete Gonzalez <[email protected]>
1 parent e441254 commit 54c83b6

File tree

7 files changed

+47
-22
lines changed

7 files changed

+47
-22
lines changed

apps/api-extractor/src/generators/ApiReportGenerator.ts

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import type { IAstModuleExportInfo } from '../analyzer/AstModule';
2222
import { SourceFileLocationFormatter } from '../analyzer/SourceFileLocationFormatter';
2323
import { ExtractorMessageId } from '../api/ExtractorMessageId';
2424
import type { ApiReportVariant } from '../api/IConfigFile';
25+
import type { SymbolMetadata } from '../collector/SymbolMetadata';
2526

2627
export class ApiReportGenerator {
2728
private static _trimSpacesRegExp: RegExp = / +$/gm;
@@ -93,6 +94,13 @@ export class ApiReportGenerator {
9394
// Emit the regular declarations
9495
for (const entity of collector.entities) {
9596
const astEntity: AstEntity = entity.astEntity;
97+
const symbolMetadata: SymbolMetadata | undefined = collector.tryFetchMetadataForAstEntity(astEntity);
98+
const maxEffectiveReleaseTag: ReleaseTag = symbolMetadata?.maxEffectiveReleaseTag ?? ReleaseTag.None;
99+
100+
if (!this._shouldIncludeReleaseTag(maxEffectiveReleaseTag, reportVariant)) {
101+
continue;
102+
}
103+
96104
if (entity.consumable || collector.extractorConfig.apiReportIncludeForgottenExports) {
97105
// First, collect the list of export names for this symbol. When reporting messages with
98106
// ExtractorMessage.properties.exportName, this will enable us to emit the warning comments alongside
@@ -133,7 +141,7 @@ export class ApiReportGenerator {
133141
messagesToReport.push(message);
134142
}
135143

136-
if (this._shouldIncludeInReport(collector, astDeclaration, reportVariant)) {
144+
if (this._shouldIncludeDeclaration(collector, astDeclaration, reportVariant)) {
137145
writer.ensureSkippedLine();
138146
writer.write(ApiReportGenerator._getAedocSynopsis(collector, astDeclaration, messagesToReport));
139147

@@ -276,7 +284,7 @@ export class ApiReportGenerator {
276284
): void {
277285
// Should we process this declaration at all?
278286
// eslint-disable-next-line no-bitwise
279-
if (!ApiReportGenerator._shouldIncludeInReport(collector, astDeclaration, reportVariant)) {
287+
if (!ApiReportGenerator._shouldIncludeDeclaration(collector, astDeclaration, reportVariant)) {
280288
span.modification.skipAll();
281289
return;
282290
}
@@ -420,7 +428,7 @@ export class ApiReportGenerator {
420428
astDeclaration
421429
);
422430

423-
if (ApiReportGenerator._shouldIncludeInReport(collector, childAstDeclaration, reportVariant)) {
431+
if (ApiReportGenerator._shouldIncludeDeclaration(collector, childAstDeclaration, reportVariant)) {
424432
if (sortChildren) {
425433
span.modification.sortChildren = true;
426434
child.modification.sortKey = Collector.getSortKeyIgnoringUnderscore(
@@ -456,7 +464,7 @@ export class ApiReportGenerator {
456464
}
457465
}
458466

459-
private static _shouldIncludeInReport(
467+
private static _shouldIncludeDeclaration(
460468
collector: Collector,
461469
astDeclaration: AstDeclaration,
462470
reportVariant: ApiReportVariant
@@ -469,22 +477,34 @@ export class ApiReportGenerator {
469477

470478
const apiItemMetadata: ApiItemMetadata = collector.fetchApiItemMetadata(astDeclaration);
471479

472-
// No specified release tag is considered the same as `@public`.
473-
const releaseTag: ReleaseTag =
474-
apiItemMetadata.effectiveReleaseTag === ReleaseTag.None
475-
? ReleaseTag.Public
476-
: apiItemMetadata.effectiveReleaseTag;
480+
return this._shouldIncludeReleaseTag(apiItemMetadata.effectiveReleaseTag, reportVariant);
481+
}
477482

478-
// If the declaration has a release tag that is not in scope, omit it from the report.
483+
private static _shouldIncludeReleaseTag(releaseTag: ReleaseTag, reportVariant: ApiReportVariant): boolean {
479484
switch (reportVariant) {
480485
case 'complete':
481486
return true;
482487
case 'alpha':
483-
return releaseTag >= ReleaseTag.Alpha;
488+
return (
489+
releaseTag === ReleaseTag.Alpha ||
490+
releaseTag === ReleaseTag.Beta ||
491+
releaseTag === ReleaseTag.Public ||
492+
// NOTE: No specified release tag is implicitly treated as `@public`.
493+
releaseTag === ReleaseTag.None
494+
);
484495
case 'beta':
485-
return releaseTag >= ReleaseTag.Beta;
496+
return (
497+
releaseTag === ReleaseTag.Beta ||
498+
releaseTag === ReleaseTag.Public ||
499+
// NOTE: No specified release tag is implicitly treated as `@public`.
500+
releaseTag === ReleaseTag.None
501+
);
486502
case 'public':
487-
return releaseTag === ReleaseTag.Public;
503+
return (
504+
releaseTag === ReleaseTag.Public ||
505+
// NOTE: No specified release tag is implicitly treated as `@public`.
506+
releaseTag === ReleaseTag.None
507+
);
488508
default:
489509
throw new Error(`Unrecognized release level: ${reportVariant}`);
490510
}

build-tests/api-extractor-lib2-test/dist/api-extractor-lib2-test.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @packageDocumentation
88
*/
99

10-
/** @public */
10+
/** @beta */
1111
declare class DefaultClass {
1212
}
1313
export default DefaultClass;

build-tests/api-extractor-lib2-test/etc/api-extractor-lib2-test.alpha.api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
```ts
66

7-
// @public (undocumented)
7+
// @beta (undocumented)
88
class DefaultClass {
99
}
1010
export default DefaultClass;

build-tests/api-extractor-lib2-test/etc/api-extractor-lib2-test.api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
```ts
66

7-
// @public (undocumented)
7+
// @beta (undocumented)
88
class DefaultClass {
99
}
1010
export default DefaultClass;

build-tests/api-extractor-lib2-test/etc/api-extractor-lib2-test.public.api.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@
44
55
```ts
66

7-
// @public (undocumented)
8-
class DefaultClass {
9-
}
10-
export default DefaultClass;
11-
127
// @public (undocumented)
138
export class Lib2Class {
149
// (undocumented)

build-tests/api-extractor-lib2-test/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ export class Lib2Class {
1818
/** @alpha */
1919
export interface Lib2Interface {}
2020

21-
/** @public */
21+
/** @beta */
2222
export default class DefaultClass {}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@microsoft/api-extractor",
5+
"comment": "Fix an issue where default exports were sometimes trimmed incorrectly in .api.md files when using `reportVariants` (GitHub #4775)",
6+
"type": "patch"
7+
}
8+
],
9+
"packageName": "@microsoft/api-extractor"
10+
}

0 commit comments

Comments
 (0)