@@ -20,6 +20,53 @@ import { normalizeCreatorListPage } from './creator-list-page.guard';
2020// Legacy query schema
2121import { LegacyCreatorQuerySchema } from '../creators/creators.schemas' ;
2222
23+ const ALLOWED_CREATOR_SELECT_FIELDS = [
24+ 'id' ,
25+ 'handle' ,
26+ 'displayName' ,
27+ 'bio' ,
28+ 'avatarUrl' ,
29+ 'bannerUrl' ,
30+ 'isVerified' ,
31+ 'keysSupply' ,
32+ 'floorPrice' ,
33+ 'createdAt' ,
34+ 'updatedAt' ,
35+ ] as const ;
36+
37+ type AllowedCreatorSelectField = ( typeof ALLOWED_CREATOR_SELECT_FIELDS ) [ number ] ;
38+
39+ function parseSelectFields ( raw : unknown ) : string [ ] {
40+ if ( typeof raw !== 'string' || ! raw . trim ( ) ) {
41+ return [ ] ;
42+ }
43+
44+ return raw
45+ . split ( ',' )
46+ . map ( ( field ) => field . trim ( ) )
47+ . filter ( Boolean ) ;
48+ }
49+
50+ function getInvalidSelectFields ( fields : string [ ] ) : string [ ] {
51+ return fields . filter (
52+ ( field ) =>
53+ ! ALLOWED_CREATOR_SELECT_FIELDS . includes ( field as AllowedCreatorSelectField )
54+ ) ;
55+ }
56+
57+ function pickFields < T extends Record < string , unknown > > (
58+ item : T ,
59+ fields : string [ ]
60+ ) : Partial < T > {
61+ if ( ! fields . length ) {
62+ return item ;
63+ }
64+
65+ return Object . fromEntries (
66+ Object . entries ( item ) . filter ( ( [ key ] ) => fields . includes ( key ) )
67+ ) as Partial < T > ;
68+ }
69+
2370// Typed Express handler
2471export const listCreators : RequestHandler = async ( req , res ) => {
2572 try {
@@ -33,6 +80,18 @@ export const listCreators: RequestHandler = async (req, res) => {
3380 return sendValidationError ( res , 'Invalid query parameters' , parsed . details ) ;
3481 }
3582
83+ const selectedFields = parseSelectFields ( ctx . query [ 'select-fields' ] ) ;
84+ const invalidFields = getInvalidSelectFields ( selectedFields ) ;
85+
86+ if ( invalidFields . length > 0 ) {
87+ return sendValidationError ( res , 'Invalid query parameters' , [
88+ {
89+ field : 'select-fields' ,
90+ message : `Invalid select-fields: ${ invalidFields . join ( ', ' ) } ` ,
91+ } ,
92+ ] ) ;
93+ }
94+
3695 // Destructure using schema fields
3796 const { offset, limit, sort, order : sortOrder } = parsed . data ;
3897
@@ -49,15 +108,25 @@ export const listCreators: RequestHandler = async (req, res) => {
49108 sort : sortOptions ,
50109 } ) ;
51110
52- // Send success response
111+ const response = wrapPublicCreatorListResponse ( creators , meta ) ;
112+
113+ const filteredItems = Array . isArray ( response . items )
114+ ? response . items . map ( ( item ) =>
115+ pickFields ( item as Record < string , unknown > , selectedFields )
116+ )
117+ : response . items ;
118+
53119 return sendSuccess (
54120 res ,
55- wrapPublicCreatorListResponse ( creators , meta ) ,
121+ {
122+ ...response ,
123+ items : filteredItems ,
124+ } ,
56125 200 ,
57126 'Creators retrieved successfully'
58127 ) ;
59128 } catch ( error ) {
60129 console . error ( 'Error listing creators:' , error ) ;
61130 return sendError ( res , 500 , ErrorCode . INTERNAL_ERROR , 'Failed to retrieve creators' ) ;
62131 }
63- } ;
132+ } ;
0 commit comments