Skip to content

Commit 6703e06

Browse files
committed
Add new filter logic by name and rename some config properties
1 parent 370ab05 commit 6703e06

File tree

10 files changed

+273
-36
lines changed

10 files changed

+273
-36
lines changed

apps/api-documenter/src/documenters/ExperimentalYamlDocumenter.ts

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -59,26 +59,7 @@ export class ExperimentalYamlDocumenter extends YamlDocumenter {
5959
name: apiItem.displayName,
6060
uid: this._getUid(apiItem)
6161
};
62-
// Filtering out the api-items as we build the tocItems array.
63-
if (apiItem instanceof ApiDocumentedItem) {
64-
const docInlineTag: DocInlineTag | undefined =
65-
(this._config && this._config.filterByInlineTag)
66-
? this._findInlineTagByName(this._config.filterByInlineTag, apiItem.tsdocComment)
67-
: undefined;
68-
69-
const tagContent: string | undefined =
70-
docInlineTag && docInlineTag.tagContent && docInlineTag.tagContent.trim();
71-
72-
if (tagContent && this._tocPointerMap[tagContent]) {
73-
// null assertion used because when pointer map was created we checked for presence of empty `items` array
74-
this._tocPointerMap[tagContent].items!.push(tocItem);
75-
} else {
76-
if (this._catchAllPointer && this._catchAllPointer.items) {
77-
this._catchAllPointer.items.push(tocItem);
78-
}
79-
}
80-
}
81-
62+
this._filterItem(apiItem, tocItem);
8263
}
8364
}
8465

@@ -102,13 +83,15 @@ export class ExperimentalYamlDocumenter extends YamlDocumenter {
10283

10384
// Parses the tocConfig object to build a pointers map of nodes where we want to sort out the API items
10485
private _generateTocPointersMap(tocConfig: IYamlTocFile | IYamlTocItem): void {
86+
const { catchAllCategory } = this._config;
87+
10588
if (tocConfig.items) {
10689
for (const tocItem of tocConfig.items) {
10790
if (tocItem.items && tocItem.items.length > 0 && this._shouldNotIncludeInPointersMap(tocItem)) {
10891
this._generateTocPointersMap(tocItem);
10992
} else {
11093
// check for presence of the `catchAllCategory` config option
111-
if (this._config && this._config.catchAllCategory && tocItem.name === this._config.catchAllCategory) {
94+
if (catchAllCategory && tocItem.name === catchAllCategory) {
11295
this._catchAllPointer = tocItem;
11396
} else {
11497
this._tocPointerMap[tocItem.name] = tocItem;
@@ -118,11 +101,57 @@ export class ExperimentalYamlDocumenter extends YamlDocumenter {
118101
}
119102
}
120103

104+
/**
105+
* Filtering out the api-item by inlineTags or category name presence in the item name.
106+
*/
107+
private _filterItem(apiItem: ApiItem, tocItem: IYamlTocItem): void {
108+
const { categoryInlineTag, categorizeByName } = this._config;
109+
const { name: itemName } = tocItem;
110+
let filtered: boolean = false;
111+
112+
// First we attempt to filter by inline tag if provided.
113+
if (apiItem instanceof ApiDocumentedItem) {
114+
const docInlineTag: DocInlineTag | undefined =
115+
categoryInlineTag
116+
? this._findInlineTagByName(categoryInlineTag, apiItem.tsdocComment)
117+
: undefined;
118+
119+
const tagContent: string | undefined =
120+
docInlineTag && docInlineTag.tagContent && docInlineTag.tagContent.trim();
121+
122+
if (tagContent && this._tocPointerMap[tagContent]) {
123+
// null assertion used because when pointer map was created we checked for presence of empty `items` array
124+
this._tocPointerMap[tagContent].items!.push(tocItem);
125+
filtered = true;
126+
}
127+
}
128+
129+
// If not filtered by inline tag and `categorizeByName` config is enabled attempt to filter it by category name.
130+
if (!filtered && categorizeByName) {
131+
const pointers: string[] = Object.keys(this._tocPointerMap);
132+
for (let i: number = 0, length: number = pointers.length; i < length; i++) {
133+
if (itemName.indexOf(pointers[i]) !== -1) {
134+
// null assertion used because when pointer map was created we checked for presence of empty `items` array
135+
this._tocPointerMap[pointers[i]].items!.push(tocItem);
136+
filtered = true;
137+
break;
138+
}
139+
}
140+
}
141+
142+
// If item still not filtered and a `catchAllCategory` config provided push it to it.
143+
if (!filtered && this._catchAllPointer && this._catchAllPointer.items) {
144+
this._catchAllPointer.items.push(tocItem);
145+
}
146+
}
147+
121148
// This is a direct copy of a @docCategory inline tag finder in office-ui-fabric-react,
122149
// but is generic enough to be used for any inline tag
123150
private _findInlineTagByName(tagName: string, docComment: DocComment | undefined): DocInlineTag | undefined {
151+
const tagNameToCheck: string = `@${tagName}`;
152+
124153
if (docComment instanceof DocInlineTag) {
125-
if (docComment.tagName === tagName) {
154+
if (docComment.tagName === tagNameToCheck) {
126155
return docComment;
127156
}
128157
}
@@ -138,9 +167,9 @@ export class ExperimentalYamlDocumenter extends YamlDocumenter {
138167
}
139168

140169
private _shouldNotIncludeInPointersMap(item: IYamlTocItem): boolean {
141-
const { categoryNodes } = this._config;
142-
if (categoryNodes && categoryNodes.length) {
143-
return categoryNodes.indexOf(item.name) === -1;
170+
const { nonEmptyCategoryNodeNames } = this._config;
171+
if (nonEmptyCategoryNodeNames && nonEmptyCategoryNodeNames.length) {
172+
return nonEmptyCategoryNodeNames.indexOf(item.name) === -1;
144173
}
145174
return true;
146175
}

apps/api-documenter/src/documenters/IConfigFile.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,39 @@ import { IYamlTocFile } from '../yaml/IYamlTocFile';
99
export interface IConfigTableOfContents {
1010
/**
1111
* Represents the tree structure describing the toc.file format.
12-
* Only the nodes that have an empty `items` array will be filled with API items
12+
* Nodes that have an empty `items` array property or their name will be included in the
13+
* {@link IConfigTableOfContents.categoryNodes} will be filled with API items
1314
* that are matched with the filters provided. Everything else will be placed under a catchAll category
1415
* that is highly recommended to be provided.
1516
*/
1617
tocConfig: IYamlTocFile;
1718

1819
/**
19-
* Optional category name that is recommended to include in the `tocConfig`,
20-
* along with one of the filters: `filterByApiItemName` or `filterByInlineTag`.
20+
* Optional category name that is recommended to be included along with
21+
* one of the filters available: `filterByApiItemName` or `filterByInlineTag`.
2122
* Any items that are not matched to the mentioned filters will be placed under this
2223
* catchAll category. If none provided the items will not be included in the final toc.yml file.
2324
*/
2425
catchAllCategory?: string;
2526

2627
/**
2728
* Toggle either sorting of the API items should be made based on category name presence
28-
* in the API item's name.
29+
* in the API item's name. Useful when there are API items without an inline tag to categorize them,
30+
* but still need to filter the items under categories. Note: this type of filter might place some items
31+
* under wrong categories if the names similar but are supposed to be in different categories.
2932
*/
30-
filterByApiItemName?: boolean;
33+
categorizeByName?: boolean;
3134

3235
/**
3336
* Filter that can be used to sort the API items according to an inline custom tag
3437
* that is present on them.
3538
*/
36-
filterByInlineTag?: string;
39+
categoryInlineTag?: string;
3740

3841
/**
3942
* Array of node names to which API items will be pushed when filtered
4043
*/
41-
categoryNodes?: string[];
44+
nonEmptyCategoryNodeNames?: string[];
4245
}
4346

4447
/**

build-tests/api-documenter-test/config/api-documenter.json

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@
1717
{ "name": "DocClass1", "items": [] }
1818
]
1919
},
20+
{
21+
"name": "Interfaces",
22+
"items": [
23+
{ "name": "Interface5", "items": [] },
24+
{ "name": "Interface6", "items": [{ "name": "InjectedCustomInterface", "uid": "customUid" }] }
25+
]
26+
},
2027
{
2128
"name": "References",
2229
"items": [
@@ -27,10 +34,9 @@
2734
}
2835
]
2936
},
30-
"categoryNodes": ["References"],
37+
"nonEmptyCategoryNodeNames": ["References", "Interface6"],
3138
"catchAllCategory": "References",
32-
"noDuplicateEntries": true,
33-
"filterByApiItemName": false,
34-
"filterByInlineTag": "@docCategory"
39+
"categorizeByName": true,
40+
"categoryInlineTag": "docCategory"
3541
}
3642
}

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

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,112 @@
11821182
],
11831183
"extendsTokenRanges": []
11841184
},
1185+
{
1186+
"kind": "Interface",
1187+
"canonicalReference": "(IDocInterface5:interface)",
1188+
"docComment": "/**\n * Interface without inline tag to test custom TOC\n *\n * @public\n */\n",
1189+
"excerptTokens": [
1190+
{
1191+
"kind": "Content",
1192+
"text": "export interface "
1193+
},
1194+
{
1195+
"kind": "Reference",
1196+
"text": "IDocInterface5"
1197+
},
1198+
{
1199+
"kind": "Content",
1200+
"text": " "
1201+
}
1202+
],
1203+
"releaseTag": "Public",
1204+
"name": "IDocInterface5",
1205+
"members": [
1206+
{
1207+
"kind": "PropertySignature",
1208+
"canonicalReference": "string",
1209+
"docComment": "/**\n * string property\n */\n",
1210+
"excerptTokens": [
1211+
{
1212+
"kind": "Reference",
1213+
"text": "string"
1214+
},
1215+
{
1216+
"kind": "Content",
1217+
"text": ": "
1218+
},
1219+
{
1220+
"kind": "Content",
1221+
"text": "string"
1222+
},
1223+
{
1224+
"kind": "Content",
1225+
"text": ";"
1226+
}
1227+
],
1228+
"releaseTag": "Public",
1229+
"name": "string",
1230+
"propertyTypeTokenRange": {
1231+
"startIndex": 2,
1232+
"endIndex": 3
1233+
}
1234+
}
1235+
],
1236+
"extendsTokenRanges": []
1237+
},
1238+
{
1239+
"kind": "Interface",
1240+
"canonicalReference": "(IDocInterface6:interface)",
1241+
"docComment": "",
1242+
"excerptTokens": [
1243+
{
1244+
"kind": "Content",
1245+
"text": "export interface "
1246+
},
1247+
{
1248+
"kind": "Reference",
1249+
"text": "IDocInterface6"
1250+
},
1251+
{
1252+
"kind": "Content",
1253+
"text": " "
1254+
}
1255+
],
1256+
"releaseTag": "Public",
1257+
"name": "IDocInterface6",
1258+
"members": [
1259+
{
1260+
"kind": "PropertySignature",
1261+
"canonicalReference": "number",
1262+
"docComment": "/**\n * number property\n */\n",
1263+
"excerptTokens": [
1264+
{
1265+
"kind": "Reference",
1266+
"text": "number"
1267+
},
1268+
{
1269+
"kind": "Content",
1270+
"text": ": "
1271+
},
1272+
{
1273+
"kind": "Content",
1274+
"text": "number"
1275+
},
1276+
{
1277+
"kind": "Content",
1278+
"text": ";"
1279+
}
1280+
],
1281+
"releaseTag": "Public",
1282+
"name": "number",
1283+
"propertyTypeTokenRange": {
1284+
"startIndex": 2,
1285+
"endIndex": 3
1286+
}
1287+
}
1288+
],
1289+
"extendsTokenRanges": []
1290+
},
11851291
{
11861292
"kind": "Namespace",
11871293
"canonicalReference": "(OuterNamespace:namespace)",

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,16 @@ export interface IDocInterface4 {
7676
stringOrNumber: string | number;
7777
}
7878

79+
// @public
80+
export interface IDocInterface5 {
81+
string: string;
82+
}
83+
84+
// @public (undocumented)
85+
export interface IDocInterface6 {
86+
number: number;
87+
}
88+
7989
// @public
8090
export namespace OuterNamespace {
8191
export namespace InnerNamespace {

build-tests/api-documenter-test/etc/yaml/api-documenter-test.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ items:
2020
- api-documenter-test.IDocInterface2
2121
- api-documenter-test.IDocInterface3
2222
- api-documenter-test.IDocInterface4
23+
- api-documenter-test.IDocInterface5
24+
- api-documenter-test.IDocInterface6
2325
- api-documenter-test.OuterNamespace.InnerNamespace.nestedFunction
2426
- api-documenter-test.SystemEvent
2527
- uid: api-documenter-test.globalFunction
@@ -75,5 +77,9 @@ references:
7577
name: IDocInterface3
7678
- uid: api-documenter-test.IDocInterface4
7779
name: IDocInterface4
80+
- uid: api-documenter-test.IDocInterface5
81+
name: IDocInterface5
82+
- uid: api-documenter-test.IDocInterface6
83+
name: IDocInterface6
7884
- uid: api-documenter-test.SystemEvent
7985
name: SystemEvent
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
### YamlMime:UniversalReference
2+
items:
3+
- uid: api-documenter-test.IDocInterface5
4+
summary: Interface without inline tag to test custom TOC
5+
name: IDocInterface5
6+
fullName: IDocInterface5
7+
langs:
8+
- typeScript
9+
type: interface
10+
package: api-documenter-test
11+
children:
12+
- api-documenter-test.IDocInterface5.string
13+
- uid: api-documenter-test.IDocInterface5.string
14+
summary: string property
15+
name: string
16+
fullName: string
17+
langs:
18+
- typeScript
19+
type: property
20+
syntax:
21+
content: 'string: string;'
22+
return:
23+
type:
24+
- string
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
### YamlMime:UniversalReference
2+
items:
3+
- uid: api-documenter-test.IDocInterface6
4+
name: IDocInterface6
5+
fullName: IDocInterface6
6+
langs:
7+
- typeScript
8+
type: interface
9+
package: api-documenter-test
10+
children:
11+
- api-documenter-test.IDocInterface6.number
12+
- uid: api-documenter-test.IDocInterface6.number
13+
summary: number property
14+
name: number
15+
fullName: number
16+
langs:
17+
- typeScript
18+
type: property
19+
syntax:
20+
content: 'number: number;'
21+
return:
22+
type:
23+
- number

0 commit comments

Comments
 (0)