diff --git a/.bruno/random/Random Card.bru b/.bruno/random/Random Card.bru new file mode 100644 index 000000000..48f2ea7b2 --- /dev/null +++ b/.bruno/random/Random Card.bru @@ -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 +} diff --git a/.bruno/random/Random Serie.bru b/.bruno/random/Random Serie.bru new file mode 100644 index 000000000..7368eff5c --- /dev/null +++ b/.bruno/random/Random Serie.bru @@ -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 +} diff --git a/.bruno/random/Random Set.bru b/.bruno/random/Random Set.bru new file mode 100644 index 000000000..a21399761 --- /dev/null +++ b/.bruno/random/Random Set.bru @@ -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 +} diff --git a/server/src/V2/endpoints/jsonEndpoints.ts b/server/src/V2/endpoints/jsonEndpoints.ts index 711c97c03..1594ff63b 100644 --- a/server/src/V2/endpoints/jsonEndpoints.ts +++ b/server/src/V2/endpoints/jsonEndpoints.ts @@ -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 +} + const server = express.Router() const endpointToField: Record = { @@ -31,7 +39,7 @@ const endpointToField: Record = { 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()) @@ -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() @@ -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 = [] + 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', '') @@ -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')) { @@ -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')) {