1+ type SearchParamValue = string | string [ ] | undefined ;
2+
13export type SessionArchiveSearchParams = {
2- cursor ?: string ;
3- q ?: string ;
4- member ?: string ;
5- month ?: string ;
6- pmin ?: string ;
7- pmax ?: string ;
4+ cursor ?: SearchParamValue ;
5+ q ?: SearchParamValue ;
6+ member ?: SearchParamValue ;
7+ month ?: SearchParamValue ;
8+ pmin ?: SearchParamValue ;
9+ pmax ?: SearchParamValue ;
810} ;
911
1012export type ParsedSessionArchiveParams = {
1113 cursorId ?: number ;
1214 filters : {
1315 q ?: string ;
14- memberId ?: string ;
16+ memberIds ?: string [ ] ;
1517 month ?: string ;
1618 pmin ?: number ;
1719 pmax ?: number ;
@@ -22,20 +24,21 @@ export type ParsedSessionArchiveParams = {
2224export function parseSessionArchiveParams (
2325 params : SessionArchiveSearchParams ,
2426) : ParsedSessionArchiveParams {
27+ const memberIds = parseStringListParam ( params . member ) ;
2528 const filters = {
26- q : params . q ?. trim ( ) || undefined ,
27- memberId : params . member ?. trim ( ) || undefined ,
28- month : parseMonthParam ( params . month ) ?? undefined ,
29- pmin : parseNonNegativeInt ( params . pmin ) ,
30- pmax : parseNonNegativeInt ( params . pmax ) ,
29+ q : firstSearchParam ( params . q ) ?. trim ( ) || undefined ,
30+ memberIds : memberIds . length > 0 ? memberIds : undefined ,
31+ month : parseMonthParam ( firstSearchParam ( params . month ) ) ?? undefined ,
32+ pmin : parseNonNegativeInt ( firstSearchParam ( params . pmin ) ) ,
33+ pmax : parseNonNegativeInt ( firstSearchParam ( params . pmax ) ) ,
3134 } ;
3235
3336 return {
34- cursorId : parsePositiveInt ( params . cursor ) ,
37+ cursorId : parsePositiveInt ( firstSearchParam ( params . cursor ) ) ,
3538 filters,
3639 hasActiveFilters : Boolean (
3740 filters . q ||
38- filters . memberId ||
41+ filters . memberIds ?. length ||
3942 filters . month ||
4043 filters . pmin != null ||
4144 filters . pmax != null ,
@@ -44,12 +47,15 @@ export function parseSessionArchiveParams(
4447}
4548
4649export function buildSessionArchiveHref (
47- params : Record < string , string | undefined > ,
50+ params : Record < string , SearchParamValue > ,
4851) : string {
4952 const q = new URLSearchParams ( ) ;
5053 for ( const [ key , value ] of Object . entries ( params ) ) {
51- const trimmed = value ?. trim ( ) ;
52- if ( trimmed ) q . set ( key , trimmed ) ;
54+ const values = Array . isArray ( value ) ? value : [ value ] ;
55+ for ( const item of values ) {
56+ const trimmed = item ?. trim ( ) ;
57+ if ( trimmed ) q . append ( key , trimmed ) ;
58+ }
5359 }
5460 const query = q . toString ( ) ;
5561 return query ? `/sessions?${ query } ` : "/sessions" ;
@@ -72,6 +78,27 @@ export function parseMonthRange(month: string | undefined): {
7278 } ;
7379}
7480
81+ function firstSearchParam ( raw : SearchParamValue ) : string | undefined {
82+ if ( Array . isArray ( raw ) ) {
83+ return raw . find ( ( value ) => value . trim ( ) ) ;
84+ }
85+ return raw ;
86+ }
87+
88+ function parseStringListParam ( raw : SearchParamValue ) : string [ ] {
89+ const values = Array . isArray ( raw ) ? raw : raw ? [ raw ] : [ ] ;
90+ const seen = new Set < string > ( ) ;
91+ const parsed : string [ ] = [ ] ;
92+
93+ for ( const value of values ) {
94+ const trimmed = value . trim ( ) ;
95+ if ( ! trimmed || seen . has ( trimmed ) ) continue ;
96+ seen . add ( trimmed ) ;
97+ parsed . push ( trimmed ) ;
98+ }
99+
100+ return parsed ;
101+ }
75102function parseMonthParam ( raw : string | undefined ) : string | null {
76103 const value = raw ?. trim ( ) ;
77104 if ( ! value ) return null ;
0 commit comments