mirror of
https://github.com/tcgdex/cards-database.git
synced 2025-04-25 20:32:11 +00:00
fix: Invalid card when searching using the set and localid (#472)
This commit is contained in:
parent
8684fb14e4
commit
33007d83bc
22
.bruno/fixes/471-invalid-set-sorting.bru
Normal file
22
.bruno/fixes/471-invalid-set-sorting.bru
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
meta {
|
||||||
|
name: 471-invalid-set-sorting
|
||||||
|
type: http
|
||||||
|
seq: 2
|
||||||
|
}
|
||||||
|
|
||||||
|
get {
|
||||||
|
url: {{BASE_URL}}/v2/en/sets/swsh12/10
|
||||||
|
body: none
|
||||||
|
auth: none
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
res.body.id: eq swsh12-010
|
||||||
|
res.status: eq 200
|
||||||
|
}
|
||||||
|
|
||||||
|
docs {
|
||||||
|
Validate the issue seen in
|
||||||
|
|
||||||
|
https://github.com/tcgdex/cards-database/issues/471
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"compile": "bun compiler/index.ts",
|
"compile": "bun compiler/index.ts",
|
||||||
"dev": "bun --watch --hot src/index.ts",
|
"dev": "bun --watch src/index.ts",
|
||||||
"validate": "tsc --noEmit --project ./tsconfig.json",
|
"validate": "tsc --noEmit --project ./tsconfig.json",
|
||||||
"start": "bun src/index.ts"
|
"start": "bun src/index.ts"
|
||||||
},
|
},
|
||||||
|
@ -69,7 +69,7 @@ export default class Card implements LocalCard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static findOne(lang: SupportedLanguages, query: Query<SDKCard>) {
|
public static findOne(lang: SupportedLanguages, query: Query<SDKCard>) {
|
||||||
const res = handleValidation(this.getAll(lang), query)
|
const res = handleSort(handleValidation(this.getAll(lang), query), query)
|
||||||
if (res.length === 0) {
|
if (res.length === 0) {
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,8 @@ const endpointToField: Record<string, keyof SDKCard> = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
server
|
server
|
||||||
// Midleware that handle caching
|
// Midleware that handle caching only in production and on GET requests
|
||||||
.use(apicache.middleware('1 day', (req: Request) => req.method === 'GET', {}))
|
.use(apicache.middleware('1 day', (req: Request) => process.env.NODE_ENV === 'production' && req.method === 'GET', {}))
|
||||||
|
|
||||||
// .get('/cache/performance', (req, res) => {
|
// .get('/cache/performance', (req, res) => {
|
||||||
// res.json(apicache.getPerformance())
|
// res.json(apicache.getPerformance())
|
||||||
@ -186,23 +186,23 @@ server
|
|||||||
let result: any | undefined
|
let result: any | undefined
|
||||||
switch (endpoint) {
|
switch (endpoint) {
|
||||||
case 'cards':
|
case 'cards':
|
||||||
result = Card.findOne(lang, { filters: { id }})?.full()
|
result = Card.findOne(lang, { filters: { id }, strict: true })?.full()
|
||||||
if (!result) {
|
if (!result) {
|
||||||
result = Card.findOne(lang, { filters: { name: id }})?.full()
|
result = Card.findOne(lang, { filters: { name: id }, strict: true })?.full()
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'sets':
|
case 'sets':
|
||||||
result = Set.findOne(lang, { filters: { id }})?.full()
|
result = Set.findOne(lang, { filters: { id }, strict: true })?.full()
|
||||||
if (!result) {
|
if (!result) {
|
||||||
result = Set.findOne(lang, {filters: { name: id }})?.full()
|
result = Set.findOne(lang, {filters: { name: id }, strict: true })?.full()
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'series':
|
case 'series':
|
||||||
result = Serie.findOne(lang, { filters: { id }})?.full()
|
result = Serie.findOne(lang, { filters: { id }, strict: true })?.full()
|
||||||
if (!result) {
|
if (!result) {
|
||||||
result = Serie.findOne(lang, { filters: { name: id }})?.full()
|
result = Serie.findOne(lang, { filters: { name: id }, strict: true })?.full()
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
@ -242,7 +242,7 @@ server
|
|||||||
switch (endpoint) {
|
switch (endpoint) {
|
||||||
case 'sets':
|
case 'sets':
|
||||||
result = Card
|
result = Card
|
||||||
.findOne(lang, { filters: { localId: subid, set: id }})?.full()
|
.findOne(lang, { filters: { localId: subid, set: id }, strict: true})?.full()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
4
server/src/interfaces.d.ts
vendored
4
server/src/interfaces.d.ts
vendored
@ -28,6 +28,10 @@ export interface Query<T extends {} = {}> {
|
|||||||
*/
|
*/
|
||||||
filters?: Partial<{ [Key in keyof T]: T[Key] extends object ? string | number | Array<string | number> : T[Key] | Array<T[Key]> }>
|
filters?: Partial<{ [Key in keyof T]: T[Key] extends object ? string | number | Array<string | number> : T[Key] | Array<T[Key]> }>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* instead of filtering text search it will search using the full string
|
||||||
|
*/
|
||||||
|
strict?: boolean
|
||||||
/**
|
/**
|
||||||
* data sorting
|
* data sorting
|
||||||
*
|
*
|
||||||
|
@ -59,9 +59,15 @@ export function betterSorter(a: string, b: string) {
|
|||||||
*
|
*
|
||||||
* @param validator the validation object
|
* @param validator the validation object
|
||||||
* @param value the value to validate
|
* @param value the value to validate
|
||||||
|
* @param strict change how the results are fetched
|
||||||
* @returns `true` if valid else `false`
|
* @returns `true` if valid else `false`
|
||||||
*/
|
*/
|
||||||
export function validateItem(validator: any | Array<any>, value: any): boolean {
|
export function validateItem(validator: any | Array<any>, value: any, strict: boolean = false): boolean {
|
||||||
|
// convert to number is possible
|
||||||
|
if (/^\d+$/.test(validator)) {
|
||||||
|
validator = parseInt(validator)
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof value === 'object') {
|
if (typeof value === 'object') {
|
||||||
// invert signal so that an early exit mean that a match was found!
|
// invert signal so that an early exit mean that a match was found!
|
||||||
return !objectLoop(value, (v) => {
|
return !objectLoop(value, (v) => {
|
||||||
@ -69,14 +75,14 @@ export function validateItem(validator: any | Array<any>, value: any): boolean {
|
|||||||
if (typeof v === 'object') return true
|
if (typeof v === 'object') return true
|
||||||
|
|
||||||
// check for each childs until one match
|
// check for each childs until one match
|
||||||
return !validateItem(validator, v)
|
return !validateItem(validator, v, strict)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop to validate for an array
|
// loop to validate for an array
|
||||||
if (Array.isArray(validator)) {
|
if (Array.isArray(validator)) {
|
||||||
for (const sub of validator) {
|
for (const sub of validator) {
|
||||||
const res = validateItem(sub, value)
|
const res = validateItem(sub, value, strict)
|
||||||
if (res) {
|
if (res) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -84,8 +90,12 @@ export function validateItem(validator: any | Array<any>, value: any): boolean {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (typeof validator === 'string') {
|
if (typeof validator === 'string') {
|
||||||
// run a string validation
|
// run a strict string validation
|
||||||
return value.toString().toLowerCase().includes(validator.toLowerCase())
|
if (strict) {
|
||||||
|
return value.toString().toLowerCase() === validator.toLowerCase()
|
||||||
|
} else {
|
||||||
|
return value.toString().toLowerCase().includes(validator.toLowerCase())
|
||||||
|
}
|
||||||
} else if (typeof validator === 'number') {
|
} else if (typeof validator === 'number') {
|
||||||
// run a number validation
|
// run a number validation
|
||||||
if (typeof value === 'number') {
|
if (typeof value === 'number') {
|
||||||
@ -197,6 +207,6 @@ export function handleValidation(data: Array<any>, query: Query) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return data.filter((v) => objectLoop(filters, (valueToValidate, key) => {
|
return data.filter((v) => objectLoop(filters, (valueToValidate, key) => {
|
||||||
return validateItem(valueToValidate, v[key])
|
return validateItem(valueToValidate, v[key], query.strict)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user