Skip to content

Commit 3844054

Browse files
authored
Merge pull request #109 from khanavi272-spec/feat/creator-select-fields-103
feat: add select-fields query support for creator list (#103)
2 parents 32350ed + 38e470c commit 3844054

File tree

1 file changed

+72
-3
lines changed

1 file changed

+72
-3
lines changed

src/modules/creator/creator.controller.ts

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,53 @@ import { normalizeCreatorListPage } from './creator-list-page.guard';
2020
// Legacy query schema
2121
import { 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
2471
export 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

Comments
 (0)