diff --git a/.bruno/fixes/467-options-not-working-correctly.bru b/.bruno/fixes/467-options-not-working-correctly.bru index 8443c4d58..c402cf4fa 100644 --- a/.bruno/fixes/467-options-not-working-correctly.bru +++ b/.bruno/fixes/467-options-not-working-correctly.bru @@ -1,7 +1,7 @@ meta { name: 467 - Validate that we can run OPTIONS type: http - seq: 3 + seq: 2 } options { diff --git a/.bruno/fixes/471-invalid-set-sorting.bru b/.bruno/fixes/471-invalid-set-sorting.bru index c2a0457a1..e8f3d7fa7 100644 --- a/.bruno/fixes/471-invalid-set-sorting.bru +++ b/.bruno/fixes/471-invalid-set-sorting.bru @@ -1,7 +1,7 @@ meta { name: 471 - Invalid Set Sorting type: http - seq: 2 + seq: 3 } get { diff --git a/.bruno/fixes/475-ability-query-subfields.bru b/.bruno/fixes/475-ability-query-subfields.bru new file mode 100644 index 000000000..d7b801e99 --- /dev/null +++ b/.bruno/fixes/475-ability-query-subfields.bru @@ -0,0 +1,25 @@ +meta { + name: 475 - Ability to query subfileds + type: http + seq: 4 +} + +get { + url: {{BASE_URL}}/v2/en/cards?legal.standard=true + body: none + auth: none +} + +query { + legal.standard: true +} + +assert { + res.status: eq 200 +} + +docs { + Validate the issue seen in + + https://github.com/tcgdex/cards-database/issues/474 +} diff --git a/server/src/util.ts b/server/src/util.ts index 45001b1d9..972b1f7ae 100644 --- a/server/src/util.ts +++ b/server/src/util.ts @@ -1,4 +1,4 @@ -import { objectLoop } from '@dzeio/object-util' +import { mustBeObject, objectLoop } from '@dzeio/object-util' import { SupportedLanguages } from '@tcgdex/sdk' import { Response } from 'express' import { Query } from './interfaces' @@ -211,11 +211,41 @@ export function handleValidation(data: Array, query: Query) { return data } - return data.filter((v) => objectLoop(filters, (valueToValidate, key) => { - return validateItem(valueToValidate, v[key], query.strict) + return data.filter((v) => objectLoop(filters, (valueToValidate, key: string) => { + let value: any + // handle subfields + if (key.includes('.')) { + value = objectGet(v, key.split('.')) + } else { + value = v[key] + } + return validateItem(valueToValidate, value, query.strict) })) } +/** + * go through an object to get a specific value + * @param obj the object to go through + * @param path the path to follow + * @returns the value or undefined + */ +function objectGet(obj: object, path: Array): any | undefined { + mustBeObject(obj) + let pointer: object = obj; + for (let index = 0; index < path.length; index++) { + const key = path[index]; + const nextIndex = index + 1; + if (!Object.prototype.hasOwnProperty.call(pointer, key) && nextIndex < path.length) { + return undefined + } + // if last index + if (nextIndex === path.length) { + return (pointer as any)[key] + } + // move pointer to new key + pointer = (pointer as any)[key] + } +} /** * validate that the value is null or undefined @@ -225,4 +255,3 @@ export function handleValidation(data: Array, query: Query) { function isNull(value: any): value is (undefined | null) { return typeof value === 'undefined' || value === null } -