|
1 | | -import { Entity } from '@dcl/schemas' |
| 1 | +import { Entity, Network } from '@dcl/schemas' |
2 | 2 | import { fetchThirdPartyWearablesFromThirdPartyName } from '../../logic/fetch-elements/fetch-third-party-wearables' |
3 | 3 | import { fetchAndPaginate, paginationObject } from '../../logic/pagination' |
4 | 4 | import { createCombinedSorting } from '../../logic/sorting' |
@@ -41,10 +41,12 @@ export type MixedWearableResponse = Omit<MixedWearable, 'minTransferredAt' | 'ma |
41 | 41 |
|
42 | 42 | export type MixedWearableTrimmedResponse = { |
43 | 43 | entity: ExplorerWearableEntity |
| 44 | + amount?: number |
44 | 45 | } |
45 | 46 |
|
46 | 47 | export type WearableFilters = { |
47 | 48 | isSmartWearable: boolean |
| 49 | + network?: Network |
48 | 50 | } |
49 | 51 |
|
50 | 52 | async function fetchCombinedElements( |
@@ -85,9 +87,17 @@ async function fetchCombinedElements( |
85 | 87 | } |
86 | 88 |
|
87 | 89 | async function fetchOnChainWearables(): Promise<MixedOnChainWearable[]> { |
| 90 | + let itemType: 'wearable' | 'smartWearable' = 'wearable' |
| 91 | + |
| 92 | + if (filters.isSmartWearable) { |
| 93 | + itemType = 'smartWearable' |
| 94 | + } |
| 95 | + |
88 | 96 | const { elements } = await components.wearablesFetcher.fetchOwnedElements(address, undefined, { |
89 | | - itemType: filters.isSmartWearable ? 'smartWearable' : 'wearable' |
| 97 | + itemType, |
| 98 | + network: filters.network |
90 | 99 | }) |
| 100 | + |
91 | 101 | if (!elements.length) { |
92 | 102 | return [] |
93 | 103 | } |
@@ -148,9 +158,13 @@ async function fetchCombinedElements( |
148 | 158 | } |
149 | 159 |
|
150 | 160 | const [baseItems, nftItems, thirdPartyItems] = await Promise.all([ |
151 | | - filters.isSmartWearable ? [] : collectionTypes.includes(BASE_WEARABLE) ? fetchBaseWearables() : [], |
| 161 | + filters.isSmartWearable || filters.network |
| 162 | + ? [] |
| 163 | + : collectionTypes.includes(BASE_WEARABLE) |
| 164 | + ? fetchBaseWearables() |
| 165 | + : [], |
152 | 166 | collectionTypes.includes(ON_CHAIN) ? fetchOnChainWearables() : [], |
153 | | - filters.isSmartWearable |
| 167 | + filters.isSmartWearable || filters.network |
154 | 168 | ? [] |
155 | 169 | : collectionTypes.includes(THIRD_PARTY) |
156 | 170 | ? fetchThirdPartyWearables(thirdPartyCollectionId) |
@@ -185,23 +199,37 @@ export async function explorerHandler( |
185 | 199 | const isTrimmed = trimmedParam === 'true' || trimmedParam === '1' |
186 | 200 | const isSmartWearableParam = context.url.searchParams.get('isSmartWearable') |
187 | 201 | const isSmartWearable = isSmartWearableParam === 'true' || isSmartWearableParam === '1' |
| 202 | + const networkParam = context.url.searchParams.get('network') |
| 203 | + // Validate network parameter - only allow valid Network enum values (ETHEREUM or MATIC) |
| 204 | + const network = networkParam === Network.ETHEREUM || networkParam === Network.MATIC ? networkParam : undefined |
| 205 | + const includeAmountParam = context.url.searchParams.get('includeAmount') |
| 206 | + const includeAmount = includeAmountParam === 'true' || includeAmountParam === '1' |
188 | 207 |
|
189 | 208 | if (collectionTypes.some((type) => !VALID_COLLECTION_TYPES.includes(type))) { |
190 | 209 | throw new InvalidRequestError(`Invalid collection type. Valid types are: ${VALID_COLLECTION_TYPES.join(', ')}.`) |
191 | 210 | } |
192 | 211 |
|
193 | 212 | const page = await fetchAndPaginate<MixedWearable>( |
194 | 213 | () => |
195 | | - fetchCombinedElements(context.components, collectionTypes, thirdPartyCollectionIds, address, { isSmartWearable }), |
| 214 | + fetchCombinedElements(context.components, collectionTypes, thirdPartyCollectionIds, address, { |
| 215 | + isSmartWearable, |
| 216 | + network |
| 217 | + }), |
196 | 218 | pagination, |
197 | 219 | filter, |
198 | 220 | sorting |
199 | 221 | ) |
200 | 222 |
|
201 | 223 | if (isTrimmed) { |
202 | | - const results: MixedWearableTrimmedResponse[] = page.elements.map((wearable) => ({ |
203 | | - entity: buildTrimmedEntity(wearable.entity) |
204 | | - })) |
| 224 | + const results: MixedWearableTrimmedResponse[] = page.elements.map((wearable) => { |
| 225 | + const result: MixedWearableTrimmedResponse = { |
| 226 | + entity: buildTrimmedEntity(wearable.entity) |
| 227 | + } |
| 228 | + if (includeAmount) { |
| 229 | + result.amount = wearable.individualData?.length || 0 |
| 230 | + } |
| 231 | + return result |
| 232 | + }) |
205 | 233 |
|
206 | 234 | return { |
207 | 235 | status: 200, |
|
0 commit comments