mirror of
https://github.com/tcgdex/cards-database.git
synced 2025-04-23 19:32:11 +00:00
125 lines
3.2 KiB
TypeScript
125 lines
3.2 KiB
TypeScript
import { exec } from 'node:child_process'
|
|
import { glob } from 'glob'
|
|
import { Card, Set } from '../../../interfaces'
|
|
import * as legals from '../../../meta/legals'
|
|
|
|
interface fileCacheInterface {
|
|
[key: string]: any
|
|
}
|
|
|
|
export const DB_PATH = "../"
|
|
|
|
const fileCache: fileCacheInterface = {}
|
|
|
|
/**
|
|
* Fetch a JSON file from a remote location
|
|
* @param url the URL to fetch
|
|
* @returns the JSON file content
|
|
*/
|
|
export async function fetchRemoteFile<T = any>(url: string): Promise<T> {
|
|
if (!fileCache[url]) {
|
|
const signal = new AbortController()
|
|
|
|
const finished = setTimeout(() => {
|
|
signal.abort()
|
|
}, 60 * 1000);
|
|
|
|
const resp = await fetch(url, {
|
|
signal: signal.signal
|
|
})
|
|
clearTimeout(finished)
|
|
fileCache[url] = resp.json()
|
|
}
|
|
return fileCache[url]
|
|
}
|
|
|
|
const globCache: Record<string, Array<string>> = {}
|
|
|
|
export async function smartGlob(query: string): Promise<Array<string>> {
|
|
if (!globCache[query]) {
|
|
globCache[query] = await glob(query)
|
|
}
|
|
return globCache[query]
|
|
}
|
|
|
|
/**
|
|
* Check if a card is currently Legal
|
|
* @param type the type of legality
|
|
* @param card the card to check
|
|
* @param localId the card localid
|
|
* @returns {boolean} if the card is currently in the legal type
|
|
*/
|
|
export function cardIsLegal(type: 'standard' | 'expanded', card: Card, localId: string): boolean {
|
|
const legal = legals[type]
|
|
if (
|
|
legal.includes.series.includes(card.set.serie.id) ||
|
|
legal.includes.sets.includes(card.set.id) ||
|
|
card.regulationMark && legal.includes.regulationMark.includes(card.regulationMark)
|
|
) {
|
|
return !(
|
|
legal.excludes.sets.includes(card.set.id) ||
|
|
legal.excludes.cards.includes(`${card.set.id}-${localId}`)
|
|
)
|
|
}
|
|
return false
|
|
}
|
|
|
|
/**
|
|
* Check if a set is currently Legal
|
|
* @param type the type of legality
|
|
* @param set the set to check
|
|
* @returns {boolean} if the set is currently in the legal type
|
|
*/
|
|
export function setIsLegal(type: 'standard' | 'expanded', set: Set): boolean {
|
|
const legal = legals[type]
|
|
if (
|
|
legal.includes.series.includes(set.serie.id) ||
|
|
legal.includes.sets.includes(set.id)
|
|
) {
|
|
return !legal.excludes.sets.includes(set.id)
|
|
}
|
|
return false
|
|
}
|
|
|
|
function runCommand(command: string): Promise<string> {
|
|
return new Promise<string>((res, rej) => {
|
|
exec(command, (err, out) => {
|
|
if (err) {
|
|
rej(err)
|
|
return
|
|
}
|
|
res(out)
|
|
})
|
|
})
|
|
}
|
|
|
|
let lastEditsCache: Record<string, string> = {}
|
|
export async function loadLastEdits() {
|
|
const firstCommand = 'git ls-tree -r --name-only HEAD ../data'
|
|
const files = (await runCommand(firstCommand)).split('\n')
|
|
console.log('Loaded files tree', files.length, 'files')
|
|
console.log('Loading their last edit time')
|
|
let processed = 0
|
|
for (let file of files) {
|
|
file = file.replace(/"/g, '').replace("\\303\\251", "é")
|
|
try {
|
|
lastEditsCache[file] = await runCommand(`git log -1 --pretty="format:%cd" --date=iso-strict "${file}"`)
|
|
} catch {
|
|
console.warn('could not load file', file, 'hope it does not break everything else lol')
|
|
}
|
|
processed++
|
|
if (processed % 1000 === 0) {
|
|
console.log('loaded', processed, 'out of', files.length, 'files')
|
|
}
|
|
}
|
|
console.log('done loading files')
|
|
}
|
|
|
|
export function getLastEdit(path: string): string {
|
|
const date = lastEditsCache[path]
|
|
if (!date) {
|
|
throw new Error(`edit date not found for file ${path}`)
|
|
}
|
|
return date
|
|
}
|