@@ -8,17 +8,24 @@ interface ParsedSearch {
88 moduleWords : string [ ] ;
99 offsets : Set < number > ;
1010 metadataKeys : string [ ] ;
11+ metadataValues : string [ ] ;
1112}
1213
1314const EMPTY_PARSED : ParsedSearch = {
1415 nameWords : [ ] ,
1516 moduleWords : [ ] ,
1617 offsets : new Set ( ) ,
1718 metadataKeys : [ ] ,
19+ metadataValues : [ ] ,
1820} ;
1921
2022function isFilterPrefix ( word : string ) : boolean {
21- return word . startsWith ( "module:" ) || word . startsWith ( "offset:" ) || word . startsWith ( "metadata:" ) ;
23+ return (
24+ word . startsWith ( "module:" ) ||
25+ word . startsWith ( "offset:" ) ||
26+ word . startsWith ( "metadata:" ) ||
27+ word . startsWith ( "metadatavalue:" )
28+ ) ;
2229}
2330
2431function parseSearch ( search : string ) : ParsedSearch {
@@ -30,10 +37,14 @@ function parseSearch(search: string): ParsedSearch {
3037 . map ( ( x ) => parseOffset ( x . slice ( 7 ) ) )
3138 . filter ( ( x ) : x is number => x !== null ) ;
3239 const metadataKeys = words
33- . filter ( ( x ) => x . startsWith ( "metadata:" ) )
40+ . filter ( ( x ) => x . startsWith ( "metadata:" ) && ! x . startsWith ( "metadatavalue:" ) )
3441 . map ( ( x ) => x . slice ( 9 ) )
3542 . filter ( Boolean ) ;
36- return { nameWords, moduleWords, offsets : new Set ( offsetValues ) , metadataKeys } ;
43+ const metadataValues = words
44+ . filter ( ( x ) => x . startsWith ( "metadatavalue:" ) )
45+ . map ( ( x ) => x . slice ( 14 ) )
46+ . filter ( Boolean ) ;
47+ return { nameWords, moduleWords, offsets : new Set ( offsetValues ) , metadataKeys, metadataValues } ;
3748}
3849
3950export function useParsedSearch ( ) : ParsedSearch {
@@ -87,12 +98,16 @@ export function matchesMetadataKeys(
8798 keys : string [ ] ,
8899) : boolean {
89100 if ( ! metadata || metadata . length === 0 || keys . length === 0 ) return false ;
90- return keys . every ( ( key ) =>
91- metadata . some (
92- ( m ) =>
93- m . name . toLowerCase ( ) . includes ( key ) ||
94- ( m . value != null && m . value . toLowerCase ( ) . includes ( key ) ) ,
95- ) ,
101+ return keys . every ( ( key ) => metadata . some ( ( m ) => m . name . toLowerCase ( ) . includes ( key ) ) ) ;
102+ }
103+
104+ export function matchesMetadataValues (
105+ metadata : api . SchemaMetadataEntry [ ] | undefined ,
106+ values : string [ ] ,
107+ ) : boolean {
108+ if ( ! metadata || metadata . length === 0 || values . length === 0 ) return false ;
109+ return values . every ( ( val ) =>
110+ metadata . some ( ( m ) => m . value != null && m . value . toLowerCase ( ) . includes ( val ) ) ,
96111 ) ;
97112}
98113
@@ -108,7 +123,7 @@ export function filterItems<T extends HasNameAndMetadata>(
108123 collapseNonMatching : boolean ,
109124 extraMatch ?: ( item : T ) => boolean ,
110125) : { visible : T [ ] ; highlighted : Set < T > ; hiddenCount : number } {
111- const { nameWords, metadataKeys } = parsed ;
126+ const { nameWords, metadataKeys, metadataValues } = parsed ;
112127 // Words not already matched by the declaration name must match at the field level
113128 const declLower = declarationName . toLowerCase ( ) ;
114129 const remainingWords = nameWords . filter ( ( w ) => ! declLower . includes ( w ) ) ;
@@ -119,12 +134,16 @@ export function filterItems<T extends HasNameAndMetadata>(
119134 matchesWords ( item . name , remainingWords ) ||
120135 matchesMetadataKeys ( item . metadata , remainingWords ) ) &&
121136 ( metadataKeys . length === 0 || matchesMetadataKeys ( item . metadata , metadataKeys ) ) &&
137+ ( metadataValues . length === 0 || matchesMetadataValues ( item . metadata , metadataValues ) ) &&
122138 ( extraMatch == null || extraMatch ( item ) )
123139 ) ;
124140 }
125141
126142 const hasFieldFilter =
127- remainingWords . length > 0 || metadataKeys . length > 0 || parsed . offsets . size > 0 ;
143+ remainingWords . length > 0 ||
144+ metadataKeys . length > 0 ||
145+ metadataValues . length > 0 ||
146+ parsed . offsets . size > 0 ;
128147
129148 if ( ! collapseNonMatching ) {
130149 return {
@@ -142,7 +161,7 @@ export function filterItems<T extends HasNameAndMetadata>(
142161}
143162
144163function doSearch ( declarations : api . Declaration [ ] , parsed : ParsedSearch ) : api . Declaration [ ] {
145- const { nameWords, moduleWords, offsets : offsetSet , metadataKeys } = parsed ;
164+ const { nameWords, moduleWords, offsets : offsetSet , metadataKeys, metadataValues } = parsed ;
146165
147166 function filterModule ( declaration : api . Declaration ) : boolean {
148167 if ( moduleWords . length === 0 ) return true ;
@@ -158,12 +177,7 @@ function doSearch(declarations: api.Declaration[], parsed: ParsedSearch): api.De
158177 ) : boolean {
159178 return (
160179 name . includes ( word ) ||
161- ( metadata ?. some (
162- ( m ) =>
163- m . name . toLowerCase ( ) . includes ( word ) ||
164- ( m . value != null && m . value . toLowerCase ( ) . includes ( word ) ) ,
165- ) ??
166- false )
180+ ( metadata ?. some ( ( m ) => m . name . toLowerCase ( ) . includes ( word ) ) ?? false )
167181 ) ;
168182 }
169183
@@ -180,12 +194,16 @@ function doSearch(declarations: api.Declaration[], parsed: ParsedSearch): api.De
180194 }
181195
182196 function matchesMetadata ( declaration : api . Declaration ) : boolean {
183- if ( matchesMetadataKeys ( declaration . metadata , metadataKeys ) ) return true ;
184- if ( declaration . kind === "class" )
185- return declaration . fields . some ( ( f ) => matchesMetadataKeys ( f . metadata , metadataKeys ) ) ;
186- if ( declaration . kind === "enum" )
187- return declaration . members . some ( ( m ) => matchesMetadataKeys ( m . metadata , metadataKeys ) ) ;
188- return false ;
197+ const allMetadata : ( api . SchemaMetadataEntry [ ] | undefined ) [ ] = [ declaration . metadata ] ;
198+ if ( declaration . kind === "class" ) declaration . fields . forEach ( ( f ) => allMetadata . push ( f . metadata ) ) ;
199+ else if ( declaration . kind === "enum" ) declaration . members . forEach ( ( m ) => allMetadata . push ( m . metadata ) ) ;
200+
201+ const keysMatch =
202+ metadataKeys . length === 0 || allMetadata . some ( ( md ) => matchesMetadataKeys ( md , metadataKeys ) ) ;
203+ const valuesMatch =
204+ metadataValues . length === 0 ||
205+ allMetadata . some ( ( md ) => matchesMetadataValues ( md , metadataValues ) ) ;
206+ return keysMatch && valuesMatch ;
189207 }
190208
191209 function matchesOffset ( declaration : api . Declaration ) : boolean {
@@ -195,7 +213,7 @@ function doSearch(declarations: api.Declaration[], parsed: ParsedSearch): api.De
195213
196214 const hasNameFilter = nameWords . length > 0 ;
197215 const hasOffsetFilter = offsetSet . size > 0 ;
198- const hasMetadataFilter = metadataKeys . length > 0 ;
216+ const hasMetadataFilter = metadataKeys . length > 0 || metadataValues . length > 0 ;
199217
200218 return declarations . filter ( ( declaration ) => {
201219 if ( ! filterModule ( declaration ) ) return false ;
0 commit comments