@@ -17,9 +17,14 @@ import chalk from "chalk";
1717import clsx from "clsx" ;
1818import fs from "fs-extra" ;
1919import Yaml from "js-yaml" ;
20- import { groupBy } from "lodash" ;
21-
22- import type { PropSidebar , PropSidebarItemCategory } from "../types" ;
20+ import { groupBy , uniq } from "lodash" ;
21+ import type { DeepPartial } from "utility-types" ;
22+
23+ import type {
24+ InfoPageMetadata ,
25+ PropSidebar ,
26+ PropSidebarItemCategory ,
27+ } from "../types" ;
2328import { ApiPageMetadata } from "../types" ;
2429
2530interface Options {
@@ -28,26 +33,11 @@ interface Options {
2833 sidebarCollapsed : boolean ;
2934}
3035
31- export type BaseItem = {
32- title : string ;
33- permalink : string ;
34- id : string ;
35- source : string ;
36- sourceDirName : string ;
37- } ;
36+ type keys = "type" | "title" | "permalink" | "id" | "source" | "sourceDirName" ;
3837
39- export type InfoItem = BaseItem & {
40- type : "info" ;
41- } ;
42-
43- export type ApiItem = BaseItem & {
44- type : "api" ;
45- api : {
46- info ?: {
47- title ?: string ;
48- } ;
49- tags ?: string [ ] | undefined ;
50- } ;
38+ type InfoItem = Pick < InfoPageMetadata , keys > ;
39+ type ApiItem = Pick < ApiPageMetadata , keys > & {
40+ api : DeepPartial < ApiPageMetadata [ "api" ] > ;
5141} ;
5242
5343type Item = InfoItem | ApiItem ;
@@ -149,10 +139,7 @@ export async function generateSidebar(
149139/**
150140 * Takes a flat list of pages and groups them into categories based on there tags.
151141 */
152- function groupByTags (
153- items : Item [ ] ,
154- { sidebarCollapsible, sidebarCollapsed } : Options
155- ) : PropSidebar {
142+ function groupByTags ( items : Item [ ] , options : Options ) : PropSidebar {
156143 const intros = items . filter ( isInfoItem ) . map ( ( item ) => {
157144 return {
158145 type : "link" as const ,
@@ -162,81 +149,53 @@ function groupByTags(
162149 } ;
163150 } ) ;
164151
165- const tags = [
166- ...new Set (
167- items
168- . flatMap ( ( item ) => {
169- if ( isInfoItem ( item ) ) {
170- return undefined ;
171- }
172- return item . api . tags ;
173- } )
174- . filter ( Boolean ) as string [ ]
175- ) ,
176- ] ;
152+ const apiItems = items . filter ( isApiItem ) ;
153+
154+ const tags = uniq (
155+ apiItems
156+ . flatMap ( ( item ) => item . api . tags )
157+ . filter ( ( item ) : item is string => ! ! item )
158+ ) ;
159+
160+ function createLink ( item : ApiItem ) {
161+ return {
162+ type : "link" as const ,
163+ label : item . title ,
164+ href : item . permalink ,
165+ docId : item . id ,
166+ className : clsx (
167+ {
168+ "menu__list-item--deprecated" : item . api . deprecated ,
169+ "api-method" : ! ! item . api . method ,
170+ } ,
171+ item . api . method
172+ ) ,
173+ } ;
174+ }
177175
178176 const tagged = tags
179177 . map ( ( tag ) => {
180178 return {
181179 type : "category" as const ,
182180 label : tag ,
183- collapsible : sidebarCollapsible ,
184- collapsed : sidebarCollapsed ,
185- items : items
186- . filter ( ( item ) : item is ApiPageMetadata => {
187- if ( isInfoItem ( item ) ) {
188- return false ;
189- }
190- return ! ! item . api . tags ?. includes ( tag ) ;
191- } )
192- . map ( ( item ) => {
193- return {
194- type : "link" as const ,
195- label : item . title ,
196- href : item . permalink ,
197- docId : item . id ,
198- className : clsx ( {
199- "menu__list-item--deprecated" : item . api . deprecated ,
200- "api-method" : ! ! item . api . method ,
201- [ item . api . method ] : ! ! item . api . method ,
202- } ) ,
203- } ;
204- } ) ,
181+ collapsible : options . sidebarCollapsible ,
182+ collapsed : options . sidebarCollapsed ,
183+ items : apiItems
184+ . filter ( ( item ) => ! ! item . api . tags ?. includes ( tag ) )
185+ . map ( createLink ) ,
205186 } ;
206187 } )
207- . filter ( ( item ) => item . items . length > 0 ) ;
188+ . filter ( ( item ) => item . items . length > 0 ) ; // Filter out any categories with no items.
208189
209190 const untagged = [
210191 {
211192 type : "category" as const ,
212193 label : "API" ,
213- collapsible : sidebarCollapsible ,
214- collapsed : sidebarCollapsed ,
215- items : items
216- . filter ( ( item ) : item is ApiPageMetadata => {
217- // Filter out info pages and pages with tags
218- if ( isInfoItem ( item ) ) {
219- return false ;
220- }
221- if ( item . api . tags === undefined || item . api . tags . length === 0 ) {
222- // no tags
223- return true ;
224- }
225- return false ;
226- } )
227- . map ( ( item ) => {
228- return {
229- type : "link" as const ,
230- label : item . title ,
231- href : item . permalink ,
232- docId : item . id ,
233- className : clsx ( {
234- "menu__list-item--deprecated" : item . api . deprecated ,
235- "api-method" : ! ! item . api . method ,
236- [ item . api . method ] : ! ! item . api . method ,
237- } ) ,
238- } ;
239- } ) ,
194+ collapsible : options . sidebarCollapsible ,
195+ collapsed : options . sidebarCollapsed ,
196+ items : apiItems
197+ . filter ( ( { api } ) => api . tags === undefined || api . tags . length === 0 )
198+ . map ( createLink ) ,
240199 } ,
241200 ] ;
242201
0 commit comments