Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add random card/set/serie endpoint #484

Merged
merged 1 commit into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .bruno/random/Random Card.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
meta {
name: Random Card
type: http
seq: 1
}

get {
url: {{BASE_URL}}/v2/en/random/card?name=furret
body: none
auth: none
}

query {
name: furret
}

assert {
res.status: eq 200
res.body.name: contains Furret
}
19 changes: 19 additions & 0 deletions .bruno/random/Random Serie.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
meta {
name: Random Serie
type: http
seq: 3
}

get {
url: {{BASE_URL}}/v2/en/random/serie?name=p
body: none
auth: none
}

query {
name: p
}

assert {
res.status: eq 200
}
20 changes: 20 additions & 0 deletions .bruno/random/Random Set.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
meta {
name: Random Set
type: http
seq: 2
}

get {
url: {{BASE_URL}}/v2/en/random/set?name=sword
body: none
auth: none
}

query {
name: sword
}

assert {
res.status: eq 200
res.body.name: contains Sword
}
57 changes: 47 additions & 10 deletions server/src/V2/endpoints/jsonEndpoints.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import { objectKeys, objectLoop } from '@dzeio/object-util'
import { Card as SDKCard } from '@tcgdex/sdk'
import apicache from 'apicache'
import express from 'express'
import express, { Request } from 'express'
import { Query } from '../../interfaces'
import { betterSorter, checkLanguage, sendError, unique } from '../../util'
import Card from '../Components/Card'
import Serie from '../Components/Serie'
import Set from '../Components/Set'

type CustomRequest = Request & {
/**
* disable caching
*/
DO_NOT_CACHE?: boolean
advQuery?: Query<any>
}

const server = express.Router()

const endpointToField: Record<string, keyof SDKCard> = {
Expand All @@ -31,7 +39,7 @@ const endpointToField: Record<string, keyof SDKCard> = {

server
// Midleware that handle caching only in production and on GET requests
.use(apicache.middleware('1 day', (req: Request, res: Response) => res.status < 400 && process.env.NODE_ENV === 'production' && req.method === 'GET', {}))
.use(apicache.middleware('1 day', (req: CustomRequest, res: Response) => !req.DO_NOT_CACHE && res.status < 400 && process.env.NODE_ENV === 'production' && req.method === 'GET', {}))

// .get('/cache/performance', (req, res) => {
// res.json(apicache.getPerformance())
Expand All @@ -43,14 +51,14 @@ server
// })

// Midleware that handle url transformation
.use((req, _, next) => {
.use((req: CustomRequest, _, next) => {
// this is ugly BUT it fix the problem with + not becoming spaces
req.url = req.url.replace(/\+/g, ' ')
next()
})

// handle Query builder
.use((req, _, next) => {
.use((req: CustomRequest, _, next) => {
// handle no query
if (!req.query) {
next()
Expand All @@ -77,22 +85,51 @@ server

})

// @ts-expect-error normal behavior
req.advQuery = items

next()
})

/**
* Allows the user to fetch a random card/set/serie from the database
*/
.get('/:lang/random/:what', (req: CustomRequest, res): void => {
const { lang, what } = req.params

if (!checkLanguage(lang)) {
return sendError('LanguageNotFoundError', res, lang)
}

const query: Query = req.advQuery!

let data: Array<Card | Set | Serie> = []
switch (what.toLowerCase()) {
case 'card':
data = Card.find(lang, query)
break
case 'set':
data = Set.find(lang, query)
break
case 'serie':
data = Serie.find(lang, query)
break
default:
return sendError('EndpointNotFoundError', res, what)
}
const item = Math.min(data.length - 1, Math.max(0, Math.round(Math.random() * data.length)))
req.DO_NOT_CACHE = true
res.json(data[item])
})


/**
* Listing Endpoint
* ex: /v2/en/cards
*/
.get('/:lang/:endpoint', (req, res): void => {
.get('/:lang/:endpoint', (req: CustomRequest, res): void => {
let { lang, endpoint } = req.params

// @ts-expect-error normal behavior
const query: Query = req.advQuery
const query: Query = req.advQuery!

if (endpoint.endsWith('.json')) {
endpoint = endpoint.replace('.json', '')
Expand Down Expand Up @@ -170,7 +207,7 @@ server
* Listing Endpoint
* ex: /v2/en/cards/base1-1
*/
.get('/:lang/:endpoint/:id', (req, res) => {
.get('/:lang/:endpoint/:id', (req: CustomRequest, res) => {
let { id, lang, endpoint } = req.params

if (id.endsWith('.json')) {
Expand Down Expand Up @@ -223,7 +260,7 @@ server
* sub id Endpoint (for the set endpoint only currently)
* ex: /v2/en/sets/base1/1
*/
.get('/:lang/:endpoint/:id/:subid', (req, res) => {
.get('/:lang/:endpoint/:id/:subid', (req: CustomRequest, res) => {
let { id, lang, endpoint, subid } = req.params

if (subid.endsWith('.json')) {
Expand Down
Loading