diff --git a/README.md b/README.md index 155123c4..d1536753 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,7 @@ type Item = { - `emoteCategory`: Filter results by `EmoteCategory`. Possible values: `dance`, `stunt`, `greetings`, `fun`, `poses`, `reactions`, `horror`, `miscellaneous`. - `emoteGender`: Filter results by `GenderFilterOption`. It supports multiple values by adding the query param multiple times. Possible values: `male`, `female`, `unisex`. - `emotePlayMode`: Filter results by `EmotePlayMode`. It supports multiple values by adding the query param multiple times. Possible values: `simple`, `loop` +- `id`: Filter results by id. It supports multiple values by adding the query param multiple times. Type: `contractAddress-itemId`. - `contractAddress`: Filter results by contract address. It supports multiple values by adding the query param multiple times. Type: `address`. - `itemId`: Filter results by `itemId`. Type: `string`. - `minPrice`: Return only sales with a price higher than this. Type `number`. diff --git a/package-lock.json b/package-lock.json index 4115c10b..9940b53d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "Apache-2.0", "dependencies": { - "@dcl/schemas": "^6.13.2", + "@dcl/schemas": "^6.14.0", "@well-known-components/env-config-provider": "^1.2.0", "@well-known-components/http-requests-logger-component": "^2.1.0", "@well-known-components/http-server": "^1.1.6", @@ -615,9 +615,9 @@ } }, "node_modules/@dcl/schemas": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@dcl/schemas/-/schemas-6.13.2.tgz", - "integrity": "sha512-PbgfjyMGbZxSHeOW/kD1m8siAXDPlhhjPdozv1KX9S9BOMxJjEkacW59j3u8BYhIu4vD1kaAG+qnOnaFxXxVFA==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@dcl/schemas/-/schemas-6.14.0.tgz", + "integrity": "sha512-ZBzYwAJ6tOxYx1kF8pqr1Ybc99ww0UnGneVhKg6bXXIop6ItWuxXy15voU5ctcjtbG+/f327EquTkD4rBfi3Tg==", "dependencies": { "ajv": "^8.11.0", "ajv-errors": "^3.0.0", @@ -10054,9 +10054,9 @@ } }, "@dcl/schemas": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@dcl/schemas/-/schemas-6.13.2.tgz", - "integrity": "sha512-PbgfjyMGbZxSHeOW/kD1m8siAXDPlhhjPdozv1KX9S9BOMxJjEkacW59j3u8BYhIu4vD1kaAG+qnOnaFxXxVFA==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@dcl/schemas/-/schemas-6.14.0.tgz", + "integrity": "sha512-ZBzYwAJ6tOxYx1kF8pqr1Ybc99ww0UnGneVhKg6bXXIop6ItWuxXy15voU5ctcjtbG+/f327EquTkD4rBfi3Tg==", "requires": { "ajv": "^8.11.0", "ajv-errors": "^3.0.0", diff --git a/package.json b/package.json index 7a1b5b1c..730a3c59 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "printWidth": 80 }, "dependencies": { - "@dcl/schemas": "^6.13.2", + "@dcl/schemas": "^6.14.0", "@well-known-components/env-config-provider": "^1.2.0", "@well-known-components/http-requests-logger-component": "^2.1.0", "@well-known-components/http-server": "^1.1.6", diff --git a/src/adapters/handlers/items.ts b/src/adapters/handlers/items.ts index 659c5d8b..3daf2bcb 100644 --- a/src/adapters/handlers/items.ts +++ b/src/adapters/handlers/items.ts @@ -12,7 +12,7 @@ import { import { IHttpServerComponent } from '@well-known-components/interfaces' import { AppComponents, Context } from '../../types' import { Params } from '../../logic/http/params' -import { asJSON } from '../../logic/http/response' +import { asJSON, HttpError } from '../../logic/http/response' export function createItemsHandler( components: Pick @@ -53,6 +53,7 @@ export function createItemsHandler( 'emotePlayMode', EmotePlayMode ) + const ids = params.getList('id') const contractAddresses = params.getList('contractAddress') const itemId = params.getString('itemId') const network = params.getValue('network', Network) @@ -60,8 +61,18 @@ export function createItemsHandler( const minPrice = params.getString('minPrice') const urns = params.getList('urn') - return asJSON(() => - items.fetchAndCount({ + return asJSON(() => { + if ( + ids?.length > 0 && + (contractAddresses?.length > 0 || itemId || urns?.length > 0) + ) { + throw new HttpError( + 'Ids cannot be set with contractAddress, itemId, or urn.', + 400 + ) + } + + return items.fetchAndCount({ first, skip, sortBy, @@ -78,6 +89,7 @@ export function createItemsHandler( emoteCategory, emoteGenders, emotePlayMode, + ids, contractAddresses, itemId, isWearableSmart, @@ -90,6 +102,6 @@ export function createItemsHandler( : undefined, urns, }) - ) + }) } } diff --git a/src/ports/items/utils.spec.ts b/src/ports/items/utils.spec.ts index 305722ad..028baafc 100644 --- a/src/ports/items/utils.spec.ts +++ b/src/ports/items/utils.spec.ts @@ -85,6 +85,23 @@ describe("#getItemsQuery", () => { }) }) + describe('when ids is defined', () => { + it('should check ids in the received list by params', () => { + expect( + getItemsQuery({ + ids: [ + '0x00a4b2e743c609256ade1cf99b8e69ecdf27ab8c-0', + '0x00a4b2e743c609256ade1cf99b8e69ecdf27ab8c-1', + ], + }) + ).toEqual( + expect.stringContaining( + 'id_in: ["0x00a4b2e743c609256ade1cf99b8e69ecdf27ab8c-0","0x00a4b2e743c609256ade1cf99b8e69ecdf27ab8c-1"]' + ) + ) + }) + }) + describe('when urns is defined', () => { it('should check urns in the list of urns received by params', () => { expect( diff --git a/src/ports/items/utils.ts b/src/ports/items/utils.ts index 4cd3419b..22dd8670 100644 --- a/src/ports/items/utils.ts +++ b/src/ports/items/utils.ts @@ -151,6 +151,7 @@ export function getItemsQuery(filters: ItemFilters, isCount = false) { wearableGenders, emoteCategory, emoteGenders, + ids, contractAddresses, itemId, minPrice, @@ -214,6 +215,14 @@ export function getItemsQuery(filters: ItemFilters, isCount = false) { where.push(`price_gte: "${minPrice}"`) } + if (ids && ids.length > 0) { + where.push( + `id_in: [${ids + .map((id) => `"${id}"`) + .join(',')}]` + ) + } + if (contractAddresses && contractAddresses.length > 0) { where.push( `collection_in: [${contractAddresses