Skip to content

Commit 6dab01c

Browse files
committed
refactor: Make the structure of tagsToReport easier to override
1 parent c2c0dc1 commit 6dab01c

File tree

10 files changed

+77
-65
lines changed

10 files changed

+77
-65
lines changed

apps/api-extractor/src/api/ExtractorConfig.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,13 @@ const defaultApiReportVariants: readonly ApiReportVariant[] = ['complete'];
183183
* Also note that the order of tags in this list is significant, as it determines the order of tags in the report.
184184
* Any changes to this list should be considered breaking.
185185
*/
186-
const defaultTagsToReport: readonly string[] = [
187-
'@sealed',
188-
'@virtual',
189-
'@override',
190-
'@eventProperty',
191-
'@deprecated'
192-
];
186+
const defaultTagsToReport: Readonly<Record<`@${string}`, boolean>> = {
187+
'@sealed': true,
188+
'@virtual': true,
189+
'@override': true,
190+
'@eventProperty': true,
191+
'@deprecated': true
192+
};
193193

194194
interface IExtractorConfigParameters {
195195
projectFolder: string;
@@ -205,7 +205,7 @@ interface IExtractorConfigParameters {
205205
reportFolder: string;
206206
reportTempFolder: string;
207207
apiReportIncludeForgottenExports: boolean;
208-
tagsToReport: readonly string[];
208+
tagsToReport: Readonly<Record<`@${string}`, boolean>>;
209209
docModelEnabled: boolean;
210210
apiJsonFilePath: string;
211211
docModelIncludeForgottenExports: boolean;
@@ -302,7 +302,7 @@ export class ExtractorConfig {
302302
/** {@inheritDoc IConfigApiReport.reportTempFolder} */
303303
public readonly reportTempFolder: string;
304304
/** {@inheritDoc IConfigApiReport.tagsToReport} */
305-
public readonly tagsToReport: readonly string[];
305+
public readonly tagsToReport: Readonly<Record<`@${string}`, boolean>>;
306306

307307
/**
308308
* Gets the file path for the "complete" (default) report configuration, if one was specified.
@@ -938,7 +938,7 @@ export class ExtractorConfig {
938938
let reportFolder: string = tokenContext.projectFolder;
939939
let reportTempFolder: string = tokenContext.projectFolder;
940940
const reportConfigs: IExtractorConfigApiReport[] = [];
941-
let tagsToReport: readonly string[] = defaultTagsToReport;
941+
let tagsToReport: Record<`@${string}`, boolean> = {};
942942
if (apiReportEnabled) {
943943
// Undefined case checked above where we assign `apiReportEnabled`
944944
const apiReportConfig: IConfigApiReport = configObject.apiReport!;
@@ -1008,7 +1008,10 @@ export class ExtractorConfig {
10081008
}
10091009

10101010
if (apiReportConfig.tagsToReport !== undefined) {
1011-
tagsToReport = apiReportConfig.tagsToReport;
1011+
tagsToReport = {
1012+
...defaultTagsToReport,
1013+
...apiReportConfig.tagsToReport
1014+
};
10121015
}
10131016
}
10141017

apps/api-extractor/src/api/IConfigFile.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,18 +145,16 @@ export interface IConfigApiReport {
145145
* items whose documentation contains them.
146146
*
147147
* @remarks
148-
* Tag names must begin with \"@\".
148+
* Tag names must begin with `@`.
149149
*
150150
* This list may include standard TSDoc tags as well as custom ones.
151151
* TODO: document requirements around custom tags.
152152
*
153-
* Tags will appear in the order they are specified in this list.
154-
*
155153
* Note that an item's release tag will always reported; this behavior cannot be overridden.
156154
*
157-
* @defaultValue `["@sealed", "\@virtual", "@override", "@eventProperty", "@deprecated"]`
155+
* @defaultValue `@sealed`, `@virtual`, `@override`, `@eventProperty`, `deprecated`
158156
*/
159-
tagsToReport?: string[];
157+
tagsToReport?: Readonly<Record<`@${string}`, boolean>>;
160158
}
161159

162160
/**

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

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -566,43 +566,45 @@ export class ApiReportGenerator {
566566
}
567567
}
568568

569-
// 2. Enumerate configured tags in the order they were specified
570-
for (const tag of collector.extractorConfig.tagsToReport) {
571-
// Note that we check some tags specially.
572-
switch (tag) {
573-
case '@sealed':
574-
if (apiItemMetadata.isSealed) {
575-
footerParts.push(tag);
576-
}
577-
break;
578-
case '@virtual':
579-
if (apiItemMetadata.isVirtual) {
580-
footerParts.push(tag);
581-
}
582-
break;
583-
case '@override':
584-
if (apiItemMetadata.isOverride) {
585-
footerParts.push(tag);
586-
}
587-
break;
588-
case '@eventProperty':
589-
if (apiItemMetadata.isEventProperty) {
590-
footerParts.push(tag);
591-
}
592-
break;
593-
case '@deprecated':
594-
if (apiItemMetadata.tsdocComment?.deprecatedBlock) {
595-
footerParts.push(tag);
596-
}
597-
break;
598-
default:
599-
// If the tag was not handled specially, check if it is present in the metadata.
600-
if (apiItemMetadata.tsdocComment?.customBlocks.some((block) => block.blockTag.tagName === tag)) {
601-
footerParts.push(tag);
602-
} else if (apiItemMetadata.tsdocComment?.modifierTagSet.hasTagName(tag)) {
603-
footerParts.push(tag);
604-
}
605-
break;
569+
// 2. Enumerate configured tags, reporting standard system tags first and then other configured tags.
570+
// Note that the ordering we handle the standard tags is important for backwards compatibility.
571+
// Also note that we had special mechanisms for checking whether or not an item is documented with these tags,
572+
// so they are checked specially.
573+
const {
574+
'@sealed': reportSealedTag,
575+
'@virtual': reportVirtualTag,
576+
'@override': reportOverrideTag,
577+
'@eventProperty': reportEventPropertyTag,
578+
'@deprecated': reportDeprecatedTag,
579+
...otherTagsToReport
580+
} = collector.extractorConfig.tagsToReport;
581+
582+
// 2.a Check for standard tags and report those that are both configured and present in the metadata.
583+
if (reportSealedTag && apiItemMetadata.isSealed) {
584+
footerParts.push('@sealed');
585+
}
586+
if (reportVirtualTag && apiItemMetadata.isVirtual) {
587+
footerParts.push('@virtual');
588+
}
589+
if (reportOverrideTag && apiItemMetadata.isOverride) {
590+
footerParts.push('@override');
591+
}
592+
if (reportEventPropertyTag && apiItemMetadata.isEventProperty) {
593+
footerParts.push('@eventProperty');
594+
}
595+
if (reportDeprecatedTag && apiItemMetadata.tsdocComment?.deprecatedBlock) {
596+
footerParts.push('@deprecated');
597+
}
598+
599+
// 2.b Check for other configured tags and report those that are present in the tsdoc metadata.
600+
for (const [tag, reportTag] of Object.entries(otherTagsToReport)) {
601+
if (reportTag) {
602+
// If the tag was not handled specially, check if it is present in the metadata.
603+
if (apiItemMetadata.tsdocComment?.customBlocks.some((block) => block.blockTag.tagName === tag)) {
604+
footerParts.push(tag);
605+
} else if (apiItemMetadata.tsdocComment?.modifierTagSet.hasTagName(tag)) {
606+
footerParts.push(tag);
607+
}
606608
}
607609
}
608610

apps/api-extractor/src/schemas/api-extractor.schema.json

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,13 @@
110110

111111
"tagsToReport": {
112112
"description": "Specifies a list of TSDoc tags that should be reported in the API report file for items whose documentation contains them. This can be used to include standard TSDoc tags or custom ones. Specified tag names must begin with \"@\". By default, the following tags are reported: [@sealed, @virtual, @override, @eventProperty, @deprecated]. Tags will appear in the order they are specified in this list. Note that an item's release tag will always reported; this behavior cannot be overridden.",
113-
"type": "array",
114-
"items": {
115-
"type": "string"
116-
}
113+
"type": "object",
114+
"patternProperties": {
115+
"^@[^\\s]*$": {
116+
"type": "boolean"
117+
}
118+
},
119+
"additionalProperties": false
117120
}
118121
},
119122
"required": ["enabled"],

build-tests/api-documenter-test/etc/api-documenter-test.api.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,13 @@ export class DocBaseClass {
3636
export class DocClass1 extends DocBaseClass implements IDocInterface1, IDocInterface2 {
3737
// @internal
3838
constructor(name: string);
39-
// @deprecated (undocumented)
39+
// (undocumented)
4040
deprecatedExample(): void;
4141
exampleFunction(a: string, b: string): string;
4242
exampleFunction(x: number): number;
4343
genericWithConstraintAndDefault<T extends Constraint = DefaultType>(x: T): void;
4444
interestingEdgeCases(): void;
45-
// @eventProperty
4645
malformedEvent: SystemEvent;
47-
// @eventProperty
4846
readonly modifiedEvent: SystemEvent;
4947
protected static readonly multipleModifiersProperty: boolean;
5048
optionalParamFunction(x?: number): void;
@@ -117,7 +115,7 @@ export interface IDocInterface1 {
117115

118116
// @public (undocumented)
119117
export interface IDocInterface2 extends IDocInterface1 {
120-
// @deprecated (undocumented)
118+
// (undocumented)
121119
deprecatedExample(): void;
122120
}
123121

build-tests/api-extractor-lib3-test/config/api-extractor.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@
55

66
"apiReport": {
77
"enabled": true,
8-
"tagsToReport": ["@customBlockTag", "@customModifierTag"]
8+
"tagsToReport": {
9+
// Disable reporting of `@virtual`, which is reported by default
10+
"@virtual": false,
11+
// Enable reporting of our custom TSDoc tags.
12+
"@customBlockTag": true,
13+
"@customModifierTag": true
14+
}
915
},
1016

1117
"docModel": {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export declare class Lib3Class {
1919
/**
2020
* I am a documented property!
2121
* @customBlockTag My docs include a custom block tag!
22+
* @virtual @override
2223
*/
2324
prop: boolean;
2425
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export { Lib1Class }
1010

1111
// @public @customModifierTag (undocumented)
1212
export class Lib3Class {
13-
// @customBlockTag
13+
// @override @customBlockTag
1414
prop: boolean;
1515
}
1616

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export class Lib3Class {
2020
/**
2121
* I am a documented property!
2222
* @customBlockTag My docs include a custom block tag!
23+
* @virtual @override
2324
*/
2425
prop: boolean;
2526
}

common/reviews/api/api-extractor.api.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export class ExtractorConfig {
8787
readonly reportTempFolder: string;
8888
readonly rollupEnabled: boolean;
8989
readonly skipLibCheck: boolean;
90-
readonly tagsToReport: readonly string[];
90+
readonly tagsToReport: Readonly<Record<`@${string}`, boolean>>;
9191
readonly testMode: boolean;
9292
static tryLoadForFolder(options: IExtractorConfigLoadForFolderOptions): IExtractorConfigPrepareOptions | undefined;
9393
readonly tsconfigFilePath: string;
@@ -187,7 +187,7 @@ export interface IConfigApiReport {
187187
reportFolder?: string;
188188
reportTempFolder?: string;
189189
reportVariants?: ApiReportVariant[];
190-
tagsToReport?: string[];
190+
tagsToReport?: Readonly<Record<`@${string}`, boolean>>;
191191
}
192192

193193
// @public

0 commit comments

Comments
 (0)