mirror of
https://github.com/tcgdex/cards-database.git
synced 2025-08-15 01:41:59 +00:00
Compare commits
4 Commits
v2.16.1
...
feat-prepa
Author | SHA1 | Date | |
---|---|---|---|
79455823c9 | |||
df154e6b9b | |||
c7b3267ca2 | |||
14418b0c94 |
1
.github/workflows/test.yml
vendored
1
.github/workflows/test.yml
vendored
@@ -24,6 +24,7 @@ jobs:
|
|||||||
bun install --frozen-lockfile
|
bun install --frozen-lockfile
|
||||||
cd server
|
cd server
|
||||||
bun install --frozen-lockfile
|
bun install --frozen-lockfile
|
||||||
|
bun run compile
|
||||||
|
|
||||||
- name: Validate the data & the server
|
- name: Validate the data & the server
|
||||||
run: |
|
run: |
|
||||||
|
41
interfaces.d.ts
vendored
41
interfaces.d.ts
vendored
@@ -12,42 +12,7 @@ export interface Serie {
|
|||||||
energies?: Array<Types>
|
energies?: Array<Types>
|
||||||
}
|
}
|
||||||
|
|
||||||
interface variants {
|
type Variants = 'Standard' | 'Parallel Foil' | 'Standard Foil' | 'First Edition' | 'Jumbo' | 'Pre-Release' | 'W-Promo'
|
||||||
/**
|
|
||||||
* Card base version
|
|
||||||
*/
|
|
||||||
normal?: boolean
|
|
||||||
/**
|
|
||||||
* Holo Reverse
|
|
||||||
* (colored Background holographic)
|
|
||||||
*/
|
|
||||||
reverse?: boolean
|
|
||||||
/**
|
|
||||||
* Holo Card
|
|
||||||
* (illustration holographic)
|
|
||||||
*/
|
|
||||||
holo?: boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* can have a first Edition stamp
|
|
||||||
*/
|
|
||||||
firstEdition?: boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Can be found in Jumob Format
|
|
||||||
*/
|
|
||||||
jumbo?: boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Card has a pre-release stamp
|
|
||||||
*/
|
|
||||||
preRelease?: boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Card has a W stamp
|
|
||||||
*/
|
|
||||||
wPromo?: true
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Types = 'Colorless' | 'Darkness' | 'Dragon' |
|
export type Types = 'Colorless' | 'Darkness' | 'Dragon' |
|
||||||
'Fairy' | 'Fighting' | 'Fire' |
|
'Fairy' | 'Fighting' | 'Fire' |
|
||||||
@@ -133,9 +98,9 @@ export interface Card {
|
|||||||
category: 'Pokemon' | 'Trainer' | 'Energy'
|
category: 'Pokemon' | 'Trainer' | 'Energy'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Card Variants (Override Set Variants)
|
* Card Variants
|
||||||
*/
|
*/
|
||||||
variants?: variants
|
variants?: Array<Variants>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Card Set
|
* Card Set
|
||||||
|
@@ -27,7 +27,7 @@ type Query {
|
|||||||
|
|
||||||
"""Find one card (using the id and set is deprecated)"""
|
"""Find one card (using the id and set is deprecated)"""
|
||||||
card(
|
card(
|
||||||
id: ID!,
|
id: ID,
|
||||||
set: String,
|
set: String,
|
||||||
"""The new way to filter"""
|
"""The new way to filter"""
|
||||||
filters: CardsFilters
|
filters: CardsFilters
|
||||||
@@ -35,14 +35,14 @@ type Query {
|
|||||||
|
|
||||||
"""Find one set (using the id is deprecated)"""
|
"""Find one set (using the id is deprecated)"""
|
||||||
set(
|
set(
|
||||||
id: ID!,
|
id: ID,
|
||||||
"""The new way to filter"""
|
"""The new way to filter"""
|
||||||
filters: SetFilters
|
filters: SetFilters
|
||||||
): Set
|
): Set
|
||||||
|
|
||||||
"""Find one serie (using the id is deprecated)"""
|
"""Find one serie (using the id is deprecated)"""
|
||||||
serie(
|
serie(
|
||||||
id: ID!,
|
id: ID,
|
||||||
"""The new way to filter"""
|
"""The new way to filter"""
|
||||||
filters: SerieFilters
|
filters: SerieFilters
|
||||||
): Serie
|
): Serie
|
||||||
|
@@ -1,34 +1,33 @@
|
|||||||
{
|
{
|
||||||
"__comment__": "Missing All :(",
|
|
||||||
"$schema": "./schema.json",
|
"$schema": "./schema.json",
|
||||||
"abilityType": {
|
"abilityType": {
|
||||||
"Ability": "Ability",
|
"Ability": "Habilidade",
|
||||||
"Ancient Trait": "Ancient Trait",
|
"Ancient Trait": "Ancient Trait",
|
||||||
"Poke-BODY": "Poke-BODY",
|
"Poke-BODY": "Poke-BODY",
|
||||||
"Poke-POWER": "Poke-POWER",
|
"Poke-POWER": "Poke-POWER",
|
||||||
"Pokemon Power": "Pokemon Power"
|
"Pokemon Power": "Pokemon Power"
|
||||||
},
|
},
|
||||||
"category": {
|
"category": {
|
||||||
"Energy": "Energy",
|
"Energy": "Energia",
|
||||||
"Pokemon": "Pokemon",
|
"Pokemon": "Pokemon",
|
||||||
"Trainer": "Trainer"
|
"Trainer": "Treinador"
|
||||||
},
|
},
|
||||||
"energyType": {
|
"energyType": {
|
||||||
"Normal": "Normal",
|
"Normal": "Normal",
|
||||||
"Special": "Special"
|
"Special": "Especial"
|
||||||
},
|
},
|
||||||
"rarity": {
|
"rarity": {
|
||||||
"ACE SPEC Rare": "ACE SPEC Raro",
|
"ACE SPEC Rare": "ACE SPEC Raro",
|
||||||
"Amazing Rare": "Amazing",
|
"Amazing Rare": "Raras Incríveis",
|
||||||
"Classic Collection": "Colección Clásica",
|
"Classic Collection": "Coleção Clásica",
|
||||||
"Common": "Comum",
|
"Common": "Comum",
|
||||||
"Double rare": "Rara Dupla",
|
"Double rare": "Rara Dupla",
|
||||||
"Full Art Trainer": "Formador de arte completa",
|
"Full Art Trainer": "Arte Completa de Treinador",
|
||||||
"Holo Rare": "Rara Holo",
|
"Holo Rare": "Rara Holo",
|
||||||
"Holo Rare V": "Rara Holo V",
|
"Holo Rare V": "Rara Holo V",
|
||||||
"Holo Rare VMAX": "Rara Holo VMAX",
|
"Holo Rare VMAX": "Rara Holo VMAX",
|
||||||
"Holo Rare VSTAR": "Rara Holo VSTAR",
|
"Holo Rare VSTAR": "Rara Holo VSTAR",
|
||||||
"Hyper rare": "Rara Hiper",
|
"Hyper rare": "Hiper rara",
|
||||||
"Illustration rare": "Ilustração Rara",
|
"Illustration rare": "Ilustração Rara",
|
||||||
"LEGEND": "LEGEND",
|
"LEGEND": "LEGEND",
|
||||||
"None": "None",
|
"None": "None",
|
||||||
@@ -37,24 +36,24 @@
|
|||||||
"Rare Holo": "Rara Holo",
|
"Rare Holo": "Rara Holo",
|
||||||
"Rare Holo LV.X": "Rara Holo LV.X",
|
"Rare Holo LV.X": "Rara Holo LV.X",
|
||||||
"Rare PRIME": "Rara Prime",
|
"Rare PRIME": "Rara Prime",
|
||||||
"Secret Rare": "Secret Rare",
|
"Secret Rare": "Rare Secreta",
|
||||||
"Shiny rare": "Shiny rare",
|
"Shiny rare": "Shiny rara",
|
||||||
"Shiny rare V": "Shiny rare V",
|
"Shiny rare V": "Shiny rara V",
|
||||||
"Shiny rare VMAX": "Shiny rare VMAX",
|
"Shiny rare VMAX": "Shiny rara VMAX",
|
||||||
"Shiny Ultra Rare": "Brilhante Ultra Raro",
|
"Shiny Ultra Rare": "Brilhante Ultra Rara",
|
||||||
"Special illustration rare": "Ilustração Rara Especial",
|
"Special illustration rare": "Ilustração Rara Especial",
|
||||||
"Ultra Rare": "Rara Ultra",
|
"Ultra Rare": "Ultra Rara",
|
||||||
"Uncommon": "Incomum"
|
"Uncommon": "Incomum"
|
||||||
},
|
},
|
||||||
"stage": {
|
"stage": {
|
||||||
"Baby": "Bebê",
|
"Baby": "Bebê",
|
||||||
"Basic": "Basic",
|
"Basic": "Básico",
|
||||||
"BREAK": "TURBO",
|
"BREAK": "TURBO",
|
||||||
"LEVEL-UP": "LEVEL-UP",
|
"LEVEL-UP": "LEVEL-UP",
|
||||||
"MEGA": "MEGA",
|
"MEGA": "MEGA",
|
||||||
"RESTORED": "RESTORED",
|
"RESTORED": "RESTORED",
|
||||||
"Stage1": "Stage 1",
|
"Stage1": "Estágio 1",
|
||||||
"Stage2": "Stage 2",
|
"Stage2": "Estágio 2",
|
||||||
"V-UNION": "V-UNION",
|
"V-UNION": "V-UNION",
|
||||||
"VMAX": "VMAX",
|
"VMAX": "VMAX",
|
||||||
"VSTAR": "V-ASTRO"
|
"VSTAR": "V-ASTRO"
|
||||||
@@ -73,22 +72,22 @@
|
|||||||
"Goldenrod Game Corner": "Goldenrod Game Corner",
|
"Goldenrod Game Corner": "Goldenrod Game Corner",
|
||||||
"Item": "Item",
|
"Item": "Item",
|
||||||
"Rocket's Secret Machine": "Rocket's Secret Machine",
|
"Rocket's Secret Machine": "Rocket's Secret Machine",
|
||||||
"Stadium": "Stadium",
|
"Stadium": "Estádio",
|
||||||
"Supporter": "Supporter",
|
"Supporter": "Apoiador",
|
||||||
"Technical Machine": "Technical Machine",
|
"Technical Machine": "Technical Machine",
|
||||||
"Tool": "Tool"
|
"Tool": "Ferramenta"
|
||||||
},
|
},
|
||||||
"types": {
|
"types": {
|
||||||
"Colorless": "Colorless",
|
"Colorless": "Incolor",
|
||||||
"Darkness": "Darkness",
|
"Darkness": "Sombrio",
|
||||||
"Dragon": "Dragon",
|
"Dragon": "Dragão",
|
||||||
"Fairy": "Fairy",
|
"Fairy": "Fada",
|
||||||
"Fighting": "Fighting",
|
"Fighting": "Lutador",
|
||||||
"Fire": "Fire",
|
"Fire": "Fogo",
|
||||||
"Grass": "Grass",
|
"Grass": "Planta",
|
||||||
"Lightning": "Lightning",
|
"Lightning": "Elétrico",
|
||||||
"Metal": "Metal",
|
"Metal": "Metal",
|
||||||
"Psychic": "Psychic",
|
"Psychic": "Psíquico",
|
||||||
"Water": "Water"
|
"Water": "Água"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
server/bun.lockb
Normal file → Executable file
BIN
server/bun.lockb
Normal file → Executable file
Binary file not shown.
@@ -1,9 +1,8 @@
|
|||||||
/* eslint-disable max-statements */
|
/* eslint-disable max-statements */
|
||||||
import { FileFunction } from './compilerInterfaces'
|
|
||||||
import { promises as fs } from 'fs'
|
import { promises as fs } from 'fs'
|
||||||
import { fetchRemoteFile } from './utils/util'
|
|
||||||
import { objectValues } from '@dzeio/object-util'
|
|
||||||
import { SupportedLanguages } from '../../interfaces'
|
import { SupportedLanguages } from '../../interfaces'
|
||||||
|
import { FileFunction } from './compilerInterfaces'
|
||||||
|
import { fetchRemoteFile } from './utils/util'
|
||||||
|
|
||||||
const LANGS: Array<SupportedLanguages> = ['en', 'fr', 'es', 'it', 'pt', 'de']
|
const LANGS: Array<SupportedLanguages> = ['en', 'fr', 'es', 'it', 'pt', 'de']
|
||||||
|
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
|
import { glob } from 'glob'
|
||||||
import { Card, Set } from '../../../interfaces'
|
import { Card, Set } from '../../../interfaces'
|
||||||
import glob from 'glob'
|
|
||||||
import fetch from 'node-fetch'
|
|
||||||
import * as legals from '../../../meta/legals'
|
import * as legals from '../../../meta/legals'
|
||||||
|
|
||||||
interface fileCacheInterface {
|
interface fileCacheInterface {
|
||||||
@@ -18,9 +17,16 @@ const fileCache: fileCacheInterface = {}
|
|||||||
*/
|
*/
|
||||||
export async function fetchRemoteFile<T = any>(url: string): Promise<T> {
|
export async function fetchRemoteFile<T = any>(url: string): Promise<T> {
|
||||||
if (!fileCache[url]) {
|
if (!fileCache[url]) {
|
||||||
|
const signal = new AbortController()
|
||||||
|
|
||||||
|
const finished = setTimeout(() => {
|
||||||
|
signal.abort()
|
||||||
|
}, 60 * 1000);
|
||||||
|
|
||||||
const resp = await fetch(url, {
|
const resp = await fetch(url, {
|
||||||
timeout: 60 * 1000
|
signal: signal.signal
|
||||||
})
|
})
|
||||||
|
clearTimeout(finished)
|
||||||
fileCache[url] = resp.json()
|
fileCache[url] = resp.json()
|
||||||
}
|
}
|
||||||
return fileCache[url]
|
return fileCache[url]
|
||||||
@@ -30,9 +36,7 @@ const globCache: Record<string, Array<string>> = {}
|
|||||||
|
|
||||||
export async function smartGlob(query: string): Promise<Array<string>> {
|
export async function smartGlob(query: string): Promise<Array<string>> {
|
||||||
if (!globCache[query]) {
|
if (!globCache[query]) {
|
||||||
globCache[query] = await new Promise((res) => {
|
globCache[query] = await glob(query)
|
||||||
glob(query, (_, matches) => res(matches))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return globCache[query]
|
return globCache[query]
|
||||||
}
|
}
|
||||||
|
@@ -16,19 +16,15 @@
|
|||||||
"@tcgdex/sdk": "^2",
|
"@tcgdex/sdk": "^2",
|
||||||
"apicache": "^1",
|
"apicache": "^1",
|
||||||
"express": "^4",
|
"express": "^4",
|
||||||
"express-graphql": "^0.12.0",
|
"graphql": "^15",
|
||||||
"graphql": "^15"
|
"graphql-http": "^1.22.1",
|
||||||
|
"ruru": "^2.0.0-beta.11"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/apicache": "^1",
|
"@types/apicache": "^1",
|
||||||
"@types/express": "^4",
|
"@types/express": "^4",
|
||||||
"@types/glob": "^8",
|
"@types/node": "^20",
|
||||||
"@types/node": "^18",
|
"glob": "^10",
|
||||||
"@types/node-fetch": "^2",
|
"typescript": "^5"
|
||||||
"glob": "^8",
|
|
||||||
"node-fetch": "^2",
|
|
||||||
"ts-node": "^10",
|
|
||||||
"ts-node-dev": "^2",
|
|
||||||
"typescript": "^4"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,15 @@
|
|||||||
import express from 'express'
|
import express from 'express'
|
||||||
import { graphqlHTTP } from 'express-graphql'
|
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import { buildSchema, formatError, GraphQLError } from 'graphql'
|
import { buildSchema, GraphQLError } from 'graphql'
|
||||||
|
import { createHandler } from 'graphql-http/lib/use/express'
|
||||||
|
import { type ruruHTML as RuruHTML } from 'ruru/dist/server'
|
||||||
|
/** @ts-expect-error typing is not correctly mapped (real type at ruru/dist/server.d.ts) */
|
||||||
|
import { makeHTMLParts, ruruHTML as tmp } from 'ruru/server'
|
||||||
import resolver from './resolver'
|
import resolver from './resolver'
|
||||||
|
|
||||||
|
|
||||||
|
const ruruHTML: typeof RuruHTML = tmp
|
||||||
|
|
||||||
// Init Express Router
|
// Init Express Router
|
||||||
const router = express.Router()
|
const router = express.Router()
|
||||||
|
|
||||||
@@ -14,11 +20,19 @@ const router = express.Router()
|
|||||||
const schema = buildSchema(fs.readFileSync('./public/v2/graphql.gql', 'utf-8'))
|
const schema = buildSchema(fs.readFileSync('./public/v2/graphql.gql', 'utf-8'))
|
||||||
|
|
||||||
// Error Logging for debugging
|
// Error Logging for debugging
|
||||||
function graphQLErrorHandle(error: GraphQLError) {
|
function graphQLErrorHandle(error: Readonly<GraphQLError | Error>) {
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
if (error.source) {
|
if (!('source' in error)) {
|
||||||
|
const columns = (process?.stdout?.columns ?? 32) - 7
|
||||||
|
const dashes = ''.padEnd(columns / 2, '-')
|
||||||
|
|
||||||
|
console.error(`\x1b[91m${dashes} ERROR ${dashes}\x1b[0m`)
|
||||||
|
console.error('GraphQL Error')
|
||||||
|
console.error(error.message)
|
||||||
|
console.error(`\x1b[91m${dashes} ERROR ${dashes}\x1b[0m`)
|
||||||
|
} else if (error.source) {
|
||||||
const columns = (process?.stdout?.columns ?? 32) - 7
|
const columns = (process?.stdout?.columns ?? 32) - 7
|
||||||
const dashes = ''.padEnd(columns / 2, '-')
|
const dashes = ''.padEnd(columns / 2, '-')
|
||||||
|
|
||||||
@@ -28,18 +42,24 @@ function graphQLErrorHandle(error: GraphQLError) {
|
|||||||
console.error(error.source?.body)
|
console.error(error.source?.body)
|
||||||
console.error(`\x1b[91m${dashes} ERROR ${dashes}\x1b[0m`)
|
console.error(`\x1b[91m${dashes} ERROR ${dashes}\x1b[0m`)
|
||||||
}
|
}
|
||||||
return formatError(error)
|
return error
|
||||||
}
|
}
|
||||||
|
|
||||||
const graphql = graphqlHTTP({
|
const graphql = createHandler({
|
||||||
schema,
|
schema: schema,
|
||||||
rootValue: resolver,
|
rootValue: resolver,
|
||||||
graphiql: true,
|
formatError: graphQLErrorHandle
|
||||||
customFormatErrorFn: graphQLErrorHandle
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Add graphql to the route
|
// Add graphql to the route
|
||||||
router.get('/', graphql)
|
router.get('/', (_, res) => {
|
||||||
|
res.type('html')
|
||||||
|
|
||||||
|
res.end(ruruHTML({ endpoint: '/v2/graphql' }, {
|
||||||
|
...makeHTMLParts(),
|
||||||
|
titleTag: '<title>GraphiQL - TCGdex API V2</title>'
|
||||||
|
}))
|
||||||
|
})
|
||||||
router.post('/', graphql)
|
router.post('/', graphql)
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
Reference in New Issue
Block a user