mtgjson-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/booster/simulator.ts","../src/cache.ts","../src/config.ts","../src/connection.ts","../src/sql-builder.ts","../src/queries/cards.ts","../src/queries/sets.ts","../src/queries/tokens.ts","../src/queries/prices.ts","../src/queries/legalities.ts","../src/queries/identifiers.ts","../src/queries/decks.ts","../src/queries/sealed.ts","../src/queries/skus.ts","../src/queries/enums.ts","../src/client.ts"],"sourcesContent":["export { MtgjsonSDK } from \"./client.js\";\nexport type { MtgjsonSDKOptions } from \"./client.js\";\n\nexport {\n\tCardQuery,\n\tSetQuery,\n\tTokenQuery,\n\tPriceQuery,\n\tLegalityQuery,\n\tIdentifierQuery,\n\tDeckQuery,\n\tSealedQuery,\n\tSkuQuery,\n\tEnumQuery,\n} from \"./queries/index.js\";\n\nexport { BoosterSimulator } from \"./booster/simulator.js\";\nexport { SQLBuilder } from \"./sql-builder.js\";\nexport { Connection } from \"./connection.js\";\nexport { CacheManager } from \"./cache.js\";\nexport type { ProgressCallback } from \"./cache.js\";\n\nexport type {\n\t// Sub-models\n\tForeignData,\n\tForeignDataIdentifiers,\n\tIdentifiers,\n\tLeadershipSkills,\n\tLegalities,\n\tPurchaseUrls,\n\tRelatedCards,\n\tRulings,\n\tSourceProducts,\n\tMeta,\n\tTranslations,\n\tTcgplayerSkus,\n\tBoosterSheet,\n\tBoosterPack,\n\tBoosterConfig,\n\tPricePoints,\n\tPriceList,\n\tPriceFormats,\n\tSealedProductCard,\n\tSealedProductDeck,\n\tSealedProductOther,\n\tSealedProductPack,\n\tSealedProductSealed,\n\tSealedProductContents,\n\tKeywords,\n\tCardType,\n\tCardTypes,\n\t// Card models\n\tCardSetDeck,\n\tCardToken,\n\tCardAtomic,\n\tCardSet,\n\tCardDeck,\n\t// Set models\n\tDeckSet,\n\tSetList,\n\tMtgSet,\n\tSealedProduct,\n\tDeckList,\n\tDeck,\n\t// File models\n\tAllPricesFile,\n\tAllPrintingsFile,\n\tCardTypesFile,\n\tDeckListFile,\n\tKeywordsFile,\n\tSetListFile,\n\tTcgplayerSkusFile,\n} from \"./types/index.js\";\n","import type { Connection } from \"../connection.js\";\nimport type {\n\tBoosterConfig,\n\tBoosterPack,\n\tBoosterSheet,\n\tCardSet,\n} from \"../types/index.js\";\n\nexport class BoosterSimulator {\n\tprivate _conn: Connection;\n\n\tconstructor(conn: Connection) {\n\t\tthis._conn = conn;\n\t}\n\n\tprivate async _ensure(): Promise<void> {\n\t\tawait this._conn.ensureViews(\"sets\", \"cards\");\n\t}\n\n\tprivate async _getBoosterConfig(\n\t\tsetCode: string,\n\t): Promise<Record<string, BoosterConfig> | null> {\n\t\tawait this._ensure();\n\t\ttry {\n\t\t\tconst rows = await this._conn.execute(\n\t\t\t\t\"SELECT booster FROM sets WHERE code = $1\",\n\t\t\t\t[setCode.toUpperCase()],\n\t\t\t);\n\t\t\tif (!rows.length || !rows[0].booster) return null;\n\t\t\treturn rows[0].booster as Record<string, BoosterConfig>;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync availableTypes(setCode: string): Promise<string[]> {\n\t\tconst config = await this._getBoosterConfig(setCode);\n\t\tif (!config) return [];\n\t\treturn Object.keys(config);\n\t}\n\n\tasync openPack(setCode: string, boosterType = \"draft\"): Promise<CardSet[]> {\n\t\tconst configs = await this._getBoosterConfig(setCode);\n\t\tif (!configs || !(boosterType in configs)) {\n\t\t\tthrow new Error(\n\t\t\t\t`No booster config for set '${setCode}' type '${boosterType}'. ` +\n\t\t\t\t\t`Available: ${configs ? Object.keys(configs) : []}`,\n\t\t\t);\n\t\t}\n\n\t\tconst config = configs[boosterType];\n\t\tconst packTemplate = pickPack(config.boosters);\n\t\tconst sheets = config.sheets;\n\n\t\tconst cardUuids: string[] = [];\n\t\tfor (const [sheetName, count] of Object.entries(packTemplate.contents)) {\n\t\t\tif (!(sheetName in sheets)) continue;\n\t\t\tconst sheet = sheets[sheetName];\n\t\t\tconst picked = pickFromSheet(sheet, count);\n\t\t\tcardUuids.push(...picked);\n\t\t}\n\n\t\tif (cardUuids.length === 0) return [];\n\n\t\tawait this._conn.ensureViews(\"cards\");\n\t\tconst placeholders = cardUuids.map((_, i) => `$${i + 1}`).join(\", \");\n\t\tconst sql = `SELECT * FROM cards WHERE uuid IN (${placeholders})`;\n\t\tconst rows = await this._conn.execute(sql, cardUuids);\n\n\t\t// Preserve pack order\n\t\tconst uuidToRow = new Map<string, Record<string, unknown>>();\n\t\tfor (const r of rows) {\n\t\t\tuuidToRow.set(r.uuid as string, r);\n\t\t}\n\t\tconst ordered: Record<string, unknown>[] = [];\n\t\tfor (const u of cardUuids) {\n\t\t\tconst row = uuidToRow.get(u);\n\t\t\tif (row) ordered.push(row);\n\t\t}\n\t\treturn ordered as CardSet[];\n\t}\n\n\tasync openBox(\n\t\tsetCode: string,\n\t\tboosterType = \"draft\",\n\t\tpacks = 36,\n\t): Promise<CardSet[][]> {\n\t\tconst results: CardSet[][] = [];\n\t\tfor (let i = 0; i < packs; i++) {\n\t\t\tresults.push(await this.openPack(setCode, boosterType));\n\t\t}\n\t\treturn results;\n\t}\n\n\tasync sheetContents(\n\t\tsetCode: string,\n\t\tboosterType: string,\n\t\tsheetName: string,\n\t): Promise<Record<string, number> | null> {\n\t\tconst configs = await this._getBoosterConfig(setCode);\n\t\tif (!configs || !(boosterType in configs)) return null;\n\t\tconst sheets = configs[boosterType].sheets ?? {};\n\t\tconst sheet = sheets[sheetName];\n\t\tif (!sheet) return null;\n\t\treturn sheet.cards;\n\t}\n}\n\nfunction pickPack(boosters: BoosterPack[]): BoosterPack {\n\tconst weights = boosters.map((b) => b.weight);\n\treturn weightedChoice(boosters, weights);\n}\n\nfunction pickFromSheet(sheet: BoosterSheet, count: number): string[] {\n\tconst cards = sheet.cards;\n\tconst uuids = Object.keys(cards);\n\tconst weights = Object.values(cards);\n\tconst allowDuplicates = sheet.allowDuplicates ?? false;\n\n\tif (allowDuplicates) {\n\t\tconst picked: string[] = [];\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tpicked.push(weightedChoice(uuids, weights));\n\t\t}\n\t\treturn picked;\n\t}\n\n\tif (count >= uuids.length) {\n\t\tconst result = [...uuids];\n\t\tshuffle(result);\n\t\treturn result;\n\t}\n\n\t// Pick without replacement\n\tconst picked: string[] = [];\n\tconst remainingUuids = [...uuids];\n\tconst remainingWeights = [...weights];\n\n\tfor (let i = 0; i < Math.min(count, remainingUuids.length); i++) {\n\t\tconst choice = weightedChoice(remainingUuids, remainingWeights);\n\t\tpicked.push(choice);\n\t\tconst idx = remainingUuids.indexOf(choice);\n\t\tremainingUuids.splice(idx, 1);\n\t\tremainingWeights.splice(idx, 1);\n\t}\n\treturn picked;\n}\n\nfunction weightedChoice<T>(items: T[], weights: number[]): T {\n\tconst totalWeight = weights.reduce((a, b) => a + b, 0);\n\tlet random = Math.random() * totalWeight;\n\tfor (let i = 0; i < items.length; i++) {\n\t\trandom -= weights[i];\n\t\tif (random <= 0) return items[i];\n\t}\n\treturn items[items.length - 1];\n}\n\nfunction shuffle<T>(array: T[]): void {\n\tfor (let i = array.length - 1; i > 0; i--) {\n\t\tconst j = Math.floor(Math.random() * (i + 1));\n\t\t[array[i], array[j]] = [array[j], array[i]];\n\t}\n}\n","import { createWriteStream } from \"node:fs\";\nimport { existsSync } from \"node:fs\";\nimport {\n\tmkdir,\n\treadFile,\n\trename,\n\trm,\n\tunlink,\n\twriteFile,\n} from \"node:fs/promises\";\nimport { get as httpsGet } from \"node:https\";\nimport { join } from \"node:path\";\nimport { pipeline } from \"node:stream/promises\";\nimport { createGunzip } from \"node:zlib\";\nimport {\n\tCDN_BASE,\n\tJSON_FILES,\n\tMETA_URL,\n\tPARQUET_FILES,\n\tdefaultCacheDir,\n} from \"./config.js\";\n\nexport type ProgressCallback = (\n\tfilename: string,\n\tbytesDownloaded: number,\n\ttotalBytes: number | null,\n) => void;\n\nexport class CacheManager {\n\treadonly cacheDir: string;\n\treadonly offline: boolean;\n\treadonly timeout: number;\n\tprivate _remoteVersion: string | null = null;\n\tprivate _onProgress: ProgressCallback | null;\n\n\tconstructor(options?: {\n\t\tcacheDir?: string;\n\t\toffline?: boolean;\n\t\ttimeout?: number;\n\t\tonProgress?: ProgressCallback;\n\t}) {\n\t\tthis.cacheDir = options?.cacheDir ?? defaultCacheDir();\n\t\tthis.offline = options?.offline ?? false;\n\t\tthis.timeout = options?.timeout ?? 120_000;\n\t\tthis._onProgress = options?.onProgress ?? null;\n\t}\n\n\tasync init(): Promise<void> {\n\t\tawait mkdir(this.cacheDir, { recursive: true });\n\t}\n\n\tclose(): void {\n\t\t// No persistent HTTP client to close in Node\n\t}\n\n\tprivate async _localVersion(): Promise<string | null> {\n\t\tconst versionFile = join(this.cacheDir, \"version.txt\");\n\t\ttry {\n\t\t\treturn (await readFile(versionFile, \"utf-8\")).trim();\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprivate async _saveVersion(version: string): Promise<void> {\n\t\tawait writeFile(join(this.cacheDir, \"version.txt\"), version, \"utf-8\");\n\t}\n\n\tasync remoteVersion(): Promise<string | null> {\n\t\tif (this._remoteVersion) return this._remoteVersion;\n\t\tif (this.offline) return null;\n\t\ttry {\n\t\t\tconst resp = await fetch(META_URL, {\n\t\t\t\tsignal: AbortSignal.timeout(this.timeout),\n\t\t\t});\n\t\t\tif (!resp.ok) return null;\n\t\t\tconst data = (await resp.json()) as Record<\n\t\t\t\tstring,\n\t\t\t\tRecord<string, string>\n\t\t\t>;\n\t\t\tthis._remoteVersion = data?.data?.version ?? data?.meta?.version ?? null;\n\t\t\treturn this._remoteVersion;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync isStale(): Promise<boolean> {\n\t\tconst local = await this._localVersion();\n\t\tconst remote = await this.remoteVersion();\n\t\t// If we can't reach remote (offline), not stale\n\t\tif (remote === null) return false;\n\t\t// No local version but remote available → stale\n\t\tif (local === null) return true;\n\t\treturn local !== remote;\n\t}\n\n\tprivate async _downloadFile(filename: string, dest: string): Promise<void> {\n\t\tconst url = `${CDN_BASE}/${filename}`;\n\t\tconst dir = join(dest, \"..\");\n\t\tawait mkdir(dir, { recursive: true });\n\t\tconst tmpDest = `${dest}.tmp`;\n\n\t\ttry {\n\t\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\t\thttpsGet(url, { timeout: this.timeout }, (res) => {\n\t\t\t\t\t// Follow redirects\n\t\t\t\t\tif (\n\t\t\t\t\t\tres.statusCode &&\n\t\t\t\t\t\tres.statusCode >= 300 &&\n\t\t\t\t\t\tres.statusCode < 400 &&\n\t\t\t\t\t\tres.headers.location\n\t\t\t\t\t) {\n\t\t\t\t\t\thttpsGet(\n\t\t\t\t\t\t\tres.headers.location,\n\t\t\t\t\t\t\t{ timeout: this.timeout },\n\t\t\t\t\t\t\t(res2) => {\n\t\t\t\t\t\t\t\tthis._handleDownloadResponse(\n\t\t\t\t\t\t\t\t\tres2,\n\t\t\t\t\t\t\t\t\ttmpDest,\n\t\t\t\t\t\t\t\t\tfilename,\n\t\t\t\t\t\t\t\t\tresolve,\n\t\t\t\t\t\t\t\t\treject,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t).on(\"error\", reject);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis._handleDownloadResponse(res, tmpDest, filename, resolve, reject);\n\t\t\t\t}).on(\"error\", reject);\n\t\t\t});\n\t\t\tawait rename(tmpDest, dest);\n\t\t} catch (err) {\n\t\t\ttry {\n\t\t\t\tawait unlink(tmpDest);\n\t\t\t} catch {\n\t\t\t\t// ignore cleanup errors\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tprivate _handleDownloadResponse(\n\t\tres: import(\"node:http\").IncomingMessage,\n\t\ttmpDest: string,\n\t\tfilename: string,\n\t\tresolve: () => void,\n\t\treject: (err: Error) => void,\n\t): void {\n\t\tif (res.statusCode && res.statusCode >= 400) {\n\t\t\treject(new Error(`HTTP ${res.statusCode} downloading ${filename}`));\n\t\t\tres.resume();\n\t\t\treturn;\n\t\t}\n\t\tconst total = res.headers[\"content-length\"]\n\t\t\t? Number.parseInt(res.headers[\"content-length\"], 10)\n\t\t\t: null;\n\t\tlet downloaded = 0;\n\t\tconst ws = createWriteStream(tmpDest);\n\n\t\tres.on(\"data\", (chunk: Buffer) => {\n\t\t\tdownloaded += chunk.length;\n\t\t\tif (this._onProgress) {\n\t\t\t\tthis._onProgress(filename, downloaded, total);\n\t\t\t}\n\t\t});\n\n\t\tres.pipe(ws);\n\t\tws.on(\"finish\", resolve);\n\t\tws.on(\"error\", reject);\n\t\tres.on(\"error\", reject);\n\t}\n\n\tasync ensureParquet(viewName: string): Promise<string> {\n\t\tconst filename = PARQUET_FILES[viewName];\n\t\tif (!filename) throw new Error(`Unknown parquet view: ${viewName}`);\n\t\tconst localPath = join(this.cacheDir, filename);\n\n\t\tif (!existsSync(localPath) || (await this.isStale())) {\n\t\t\tif (this.offline) {\n\t\t\t\tif (existsSync(localPath)) return localPath;\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Parquet file ${filename} not cached and offline mode is enabled`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait this._downloadFile(filename, localPath);\n\t\t\tconst version = await this.remoteVersion();\n\t\t\tif (version) await this._saveVersion(version);\n\t\t}\n\t\treturn localPath;\n\t}\n\n\tasync ensureJson(name: string): Promise<string> {\n\t\tconst filename = JSON_FILES[name];\n\t\tif (!filename) throw new Error(`Unknown JSON file: ${name}`);\n\t\tconst localPath = join(this.cacheDir, filename);\n\n\t\tif (!existsSync(localPath) || (await this.isStale())) {\n\t\t\tif (this.offline) {\n\t\t\t\tif (existsSync(localPath)) return localPath;\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`JSON file ${filename} not cached and offline mode is enabled`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait this._downloadFile(filename, localPath);\n\t\t\tconst version = await this.remoteVersion();\n\t\t\tif (version) await this._saveVersion(version);\n\t\t}\n\t\treturn localPath;\n\t}\n\n\tasync loadJson(name: string): Promise<Record<string, unknown>> {\n\t\tconst path = await this.ensureJson(name);\n\t\ttry {\n\t\t\tif (path.endsWith(\".gz\")) {\n\t\t\t\tconst compressed = await readFile(path);\n\t\t\t\tconst decompressed = await new Promise<Buffer>((resolve, reject) => {\n\t\t\t\t\tconst gunzip = createGunzip();\n\t\t\t\t\tconst chunks: Buffer[] = [];\n\t\t\t\t\tgunzip.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n\t\t\t\t\tgunzip.on(\"end\", () => resolve(Buffer.concat(chunks)));\n\t\t\t\t\tgunzip.on(\"error\", reject);\n\t\t\t\t\tgunzip.end(compressed);\n\t\t\t\t});\n\t\t\t\treturn JSON.parse(decompressed.toString(\"utf-8\"));\n\t\t\t}\n\t\t\tconst text = await readFile(path, \"utf-8\");\n\t\t\treturn JSON.parse(text);\n\t\t} catch (err) {\n\t\t\ttry {\n\t\t\t\tawait unlink(path);\n\t\t\t} catch {\n\t\t\t\t// ignore\n\t\t\t}\n\t\t\tthrow new Error(\n\t\t\t\t`Cache file '${path}' was corrupt and has been removed. Retry to re-download. Original error: ${err}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tasync clear(): Promise<void> {\n\t\ttry {\n\t\t\tawait rm(this.cacheDir, { recursive: true, force: true });\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t\tawait mkdir(this.cacheDir, { recursive: true });\n\t}\n}\n","import { homedir, platform } from \"node:os\";\nimport { join } from \"node:path\";\n\n/** Base URL for the MTGJSON v5 API / CDN. */\nexport const CDN_BASE = \"https://mtgjson.com/api/v5\";\n\n/** Mapping of logical view names to CDN parquet file paths. */\nexport const PARQUET_FILES: Record<string, string> = {\n\t// Flat normalized tables\n\tcards: \"parquet/cards.parquet\",\n\ttokens: \"parquet/tokens.parquet\",\n\tsets: \"parquet/sets.parquet\",\n\tcard_identifiers: \"parquet/cardIdentifiers.parquet\",\n\tcard_legalities: \"parquet/cardLegalities.parquet\",\n\tcard_foreign_data: \"parquet/cardForeignData.parquet\",\n\tcard_rulings: \"parquet/cardRulings.parquet\",\n\tcard_purchase_urls: \"parquet/cardPurchaseUrls.parquet\",\n\tset_translations: \"parquet/setTranslations.parquet\",\n\ttoken_identifiers: \"parquet/tokenIdentifiers.parquet\",\n\t// Booster tables\n\tset_booster_content_weights: \"parquet/setBoosterContentWeights.parquet\",\n\tset_booster_contents: \"parquet/setBoosterContents.parquet\",\n\tset_booster_sheet_cards: \"parquet/setBoosterSheetCards.parquet\",\n\tset_booster_sheets: \"parquet/setBoosterSheets.parquet\",\n\t// Full nested\n\tall_printings: \"parquet/AllPrintings.parquet\",\n\t// Prices and SKUs\n\tall_prices_today: \"parquet/AllPricesToday.parquet\",\n\tall_prices: \"parquet/AllPrices.parquet\",\n\ttcgplayer_skus: \"parquet/TcgplayerSkus.parquet\",\n};\n\n/** Mapping of logical data names to CDN JSON file paths. */\nexport const JSON_FILES: Record<string, string> = {\n\tkeywords: \"Keywords.json\",\n\tcard_types: \"CardTypes.json\",\n\tdeck_list: \"DeckList.json\",\n\tenum_values: \"EnumValues.json\",\n\tmeta: \"Meta.json\",\n};\n\n/** URL for the MTGJSON version metadata endpoint. */\nexport const META_URL = `${CDN_BASE}/Meta.json`;\n\n/** Platform-appropriate cache directory. */\nexport function defaultCacheDir(): string {\n\tconst sys = platform();\n\tlet base: string;\n\tif (sys === \"win32\") {\n\t\tbase = join(homedir(), \"AppData\", \"Local\");\n\t} else if (sys === \"darwin\") {\n\t\tbase = join(homedir(), \"Library\", \"Caches\");\n\t} else {\n\t\tbase = join(homedir(), \".cache\");\n\t}\n\treturn join(base, \"mtgjson-sdk\");\n}\n","import { unlinkSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { DuckDBInstance } from \"@duckdb/node-api\";\nimport type { CacheManager } from \"./cache.js\";\n\ntype DuckDBConnection = Awaited<ReturnType<DuckDBInstance[\"connect\"]>>;\n\n/** Known list columns that don't follow the plural naming convention. */\nconst STATIC_LIST_COLUMNS: Record<string, ReadonlySet<string>> = {\n\tcards: new Set([\n\t\t\"artistIds\",\n\t\t\"attractionLights\",\n\t\t\"availability\",\n\t\t\"boosterTypes\",\n\t\t\"cardParts\",\n\t\t\"colorIdentity\",\n\t\t\"colorIndicator\",\n\t\t\"colors\",\n\t\t\"finishes\",\n\t\t\"frameEffects\",\n\t\t\"keywords\",\n\t\t\"originalPrintings\",\n\t\t\"otherFaceIds\",\n\t\t\"printings\",\n\t\t\"producedMana\",\n\t\t\"promoTypes\",\n\t\t\"rebalancedPrintings\",\n\t\t\"subsets\",\n\t\t\"subtypes\",\n\t\t\"supertypes\",\n\t\t\"types\",\n\t\t\"variations\",\n\t]),\n\ttokens: new Set([\n\t\t\"artistIds\",\n\t\t\"availability\",\n\t\t\"boosterTypes\",\n\t\t\"colorIdentity\",\n\t\t\"colorIndicator\",\n\t\t\"colors\",\n\t\t\"finishes\",\n\t\t\"frameEffects\",\n\t\t\"keywords\",\n\t\t\"otherFaceIds\",\n\t\t\"producedMana\",\n\t\t\"promoTypes\",\n\t\t\"reverseRelated\",\n\t\t\"subtypes\",\n\t\t\"supertypes\",\n\t\t\"types\",\n\t]),\n};\n\n/** VARCHAR columns that are NOT lists, even if they match the plural-name heuristic. */\nconst IGNORED_COLUMNS = new Set([\n\t\"text\",\n\t\"originalText\",\n\t\"flavorText\",\n\t\"printedText\",\n\t\"identifiers\",\n\t\"legalities\",\n\t\"leadershipSkills\",\n\t\"purchaseUrls\",\n\t\"relatedCards\",\n\t\"rulings\",\n\t\"sourceProducts\",\n\t\"foreignData\",\n\t\"translations\",\n\t\"toughness\",\n\t\"status\",\n\t\"format\",\n\t\"uris\",\n\t\"scryfallUri\",\n]);\n\n/** VARCHAR columns containing JSON strings to cast to DuckDB JSON type. */\nconst JSON_CAST_COLUMNS = new Set([\n\t\"identifiers\",\n\t\"legalities\",\n\t\"leadershipSkills\",\n\t\"purchaseUrls\",\n\t\"relatedCards\",\n\t\"rulings\",\n\t\"sourceProducts\",\n\t\"foreignData\",\n\t\"translations\",\n]);\n\nexport class Connection {\n\tprivate _conn!: DuckDBConnection;\n\tprivate _instance!: DuckDBInstance;\n\t_registeredViews = new Set<string>();\n\tcache: CacheManager;\n\n\tprivate constructor(cache: CacheManager) {\n\t\tthis.cache = cache;\n\t}\n\n\tstatic async create(cache: CacheManager): Promise<Connection> {\n\t\tconst conn = new Connection(cache);\n\t\tconn._instance = await DuckDBInstance.create(\":memory:\");\n\t\tconn._conn = await conn._instance.connect();\n\t\treturn conn;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tif (this._conn) {\n\t\t\tthis._conn.closeSync();\n\t\t}\n\t}\n\n\tprivate async _ensureView(viewName: string): Promise<void> {\n\t\tif (this._registeredViews.has(viewName)) return;\n\t\tconst path = await this.cache.ensureParquet(viewName);\n\t\tconst pathStr = path.replace(/\\\\/g, \"/\");\n\n\t\tif (viewName === \"card_legalities\") {\n\t\t\tawait this._registerLegalitiesView(pathStr);\n\t\t\treturn;\n\t\t}\n\n\t\tconst replaceClause = await this._buildCsvReplace(pathStr, viewName);\n\t\tawait this._run(\n\t\t\t`CREATE OR REPLACE VIEW ${viewName} AS SELECT *${replaceClause} FROM read_parquet('${pathStr}')`,\n\t\t);\n\t\tthis._registeredViews.add(viewName);\n\t}\n\n\tprivate async _buildCsvReplace(\n\t\tpathStr: string,\n\t\tviewName: string,\n\t): Promise<string> {\n\t\tconst reader = await this._conn.runAndReadAll(\n\t\t\t`SELECT column_name, column_type FROM (DESCRIBE SELECT * FROM read_parquet('${pathStr}'))`,\n\t\t);\n\t\tconst rows = reader.getRowObjects() as Array<{\n\t\t\tcolumn_name: string;\n\t\t\tcolumn_type: string;\n\t\t}>;\n\t\tconst schema = new Map<string, string>();\n\t\tfor (const row of rows) {\n\t\t\tschema.set(row.column_name, row.column_type);\n\t\t}\n\n\t\tconst candidates = new Set<string>();\n\n\t\t// Layer 1: Static baseline\n\t\tif (STATIC_LIST_COLUMNS[viewName]) {\n\t\t\tfor (const col of STATIC_LIST_COLUMNS[viewName]) {\n\t\t\t\tcandidates.add(col);\n\t\t\t}\n\t\t}\n\n\t\t// Layer 2: Dynamic heuristic\n\t\tfor (const [col, dtype] of schema) {\n\t\t\tif (dtype !== \"VARCHAR\") continue;\n\t\t\tif (IGNORED_COLUMNS.has(col)) continue;\n\t\t\tif (col.endsWith(\"s\")) candidates.add(col);\n\t\t}\n\n\t\t// Filter to columns that actually exist as VARCHAR\n\t\tconst finalCols = [...candidates]\n\t\t\t.filter((col) => schema.get(col) === \"VARCHAR\")\n\t\t\t.sort();\n\n\t\tconst exprs: string[] = [];\n\t\tfor (const col of finalCols) {\n\t\t\texprs.push(\n\t\t\t\t`CASE WHEN \"${col}\" IS NULL OR TRIM(\"${col}\") = '' THEN []::VARCHAR[] ELSE string_split(\"${col}\", ', ') END AS \"${col}\"`,\n\t\t\t);\n\t\t}\n\n\t\t// Layer 4: JSON casting\n\t\tconst jsonCols = [...JSON_CAST_COLUMNS].sort();\n\t\tfor (const col of jsonCols) {\n\t\t\tif (schema.get(col) === \"VARCHAR\") {\n\t\t\t\texprs.push(`TRY_CAST(\"${col}\" AS JSON) AS \"${col}\"`);\n\t\t\t}\n\t\t}\n\n\t\tif (exprs.length === 0) return \"\";\n\t\treturn ` REPLACE (${exprs.join(\", \")})`;\n\t}\n\n\tprivate async _registerLegalitiesView(pathStr: string): Promise<void> {\n\t\tconst reader = await this._conn.runAndReadAll(\n\t\t\t`SELECT column_name FROM (DESCRIBE SELECT * FROM read_parquet('${pathStr}'))`,\n\t\t);\n\t\tconst allCols = (\n\t\t\treader.getRowObjects() as Array<{ column_name: string }>\n\t\t).map((r) => r.column_name);\n\n\t\tconst staticCols = new Set([\"uuid\"]);\n\t\tconst formatCols = allCols.filter((c) => !staticCols.has(c));\n\n\t\tif (formatCols.length === 0) {\n\t\t\tawait this._run(\n\t\t\t\t`CREATE OR REPLACE VIEW card_legalities AS SELECT * FROM read_parquet('${pathStr}')`,\n\t\t\t);\n\t\t} else {\n\t\t\tconst colsSql = formatCols.map((c) => `\"${c}\"`).join(\", \");\n\t\t\tawait this._run(\n\t\t\t\t`CREATE OR REPLACE VIEW card_legalities AS SELECT uuid, format, status FROM ( UNPIVOT (SELECT * FROM read_parquet('${pathStr}')) ON ${colsSql} INTO NAME format VALUE status) WHERE status IS NOT NULL`,\n\t\t\t);\n\t\t}\n\t\tthis._registeredViews.add(\"card_legalities\");\n\t}\n\n\tasync registerTableFromData(\n\t\ttableName: string,\n\t\tdata: Record<string, unknown>[],\n\t): Promise<void> {\n\t\tif (data.length === 0) return;\n\t\tawait this._run(`DROP TABLE IF EXISTS ${tableName}`);\n\t\tconst tmpPath = join(tmpdir(), `mtgjson_${tableName}_${Date.now()}.json`);\n\t\ttry {\n\t\t\twriteFileSync(tmpPath, JSON.stringify(data), \"utf-8\");\n\t\t\tconst fwd = tmpPath.replace(/\\\\/g, \"/\");\n\t\t\tawait this._run(\n\t\t\t\t`CREATE TABLE ${tableName} AS SELECT * FROM read_json_auto('${fwd}')`,\n\t\t\t);\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tunlinkSync(tmpPath);\n\t\t\t} catch {\n\t\t\t\t// ignore\n\t\t\t}\n\t\t}\n\t\tthis._registeredViews.add(tableName);\n\t}\n\n\tasync registerTableFromNdjson(\n\t\ttableName: string,\n\t\tndjsonPath: string,\n\t): Promise<void> {\n\t\tawait this._run(`DROP TABLE IF EXISTS ${tableName}`);\n\t\tconst fwd = ndjsonPath.replace(/\\\\/g, \"/\");\n\t\tawait this._run(\n\t\t\t`CREATE TABLE ${tableName} AS SELECT * FROM read_json_auto('${fwd}', format='newline_delimited')`,\n\t\t);\n\t\tthis._registeredViews.add(tableName);\n\t}\n\n\tasync ensureViews(...viewNames: string[]): Promise<void> {\n\t\tfor (const name of viewNames) {\n\t\t\tawait this._ensureView(name);\n\t\t}\n\t}\n\n\tasync execute(\n\t\tsql: string,\n\t\tparams?: unknown[],\n\t): Promise<Record<string, unknown>[]> {\n\t\tconst reader = await this._runWithParams(sql, params);\n\t\tconst rows = reader.getRowObjects() as Record<string, unknown>[];\n\t\treturn rows.map((row) => coerceValues(row) as Record<string, unknown>);\n\t}\n\n\tasync executeJson(sql: string, params?: unknown[]): Promise<string> {\n\t\tconst wrapped = `SELECT to_json(list(sub)) FROM (${sql}) sub`;\n\t\tconst reader = await this._runWithParams(wrapped, params);\n\t\tconst rows = reader.getRows();\n\t\tif (!rows || rows.length === 0 || rows[0][0] == null) return \"[]\";\n\t\treturn String(rows[0][0]);\n\t}\n\n\tasync executeScalar(sql: string, params?: unknown[]): Promise<unknown> {\n\t\tconst reader = await this._runWithParams(sql, params);\n\t\tconst rows = reader.getRows();\n\t\tif (!rows || rows.length === 0) return null;\n\t\tconst val = rows[0][0] ?? null;\n\t\t// DuckDB COUNT(*) returns BIGINT → JS BigInt; coerce to Number\n\t\tif (typeof val === \"bigint\") return Number(val);\n\t\treturn val;\n\t}\n\n\tget raw(): DuckDBConnection {\n\t\treturn this._conn;\n\t}\n\n\tprivate async _run(sql: string): Promise<void> {\n\t\tawait this._conn.run(sql);\n\t}\n\n\tprivate async _runWithParams(sql: string, params?: unknown[]) {\n\t\tif (params && params.length > 0) {\n\t\t\tconst stmt = await this._conn.prepare(sql);\n\t\t\tfor (let i = 0; i < params.length; i++) {\n\t\t\t\tconst val = params[i];\n\t\t\t\tif (typeof val === \"string\") {\n\t\t\t\t\tstmt.bindVarchar(i + 1, val);\n\t\t\t\t} else if (typeof val === \"number\") {\n\t\t\t\t\tif (Number.isInteger(val)) {\n\t\t\t\t\t\tstmt.bindInteger(i + 1, val);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstmt.bindDouble(i + 1, val);\n\t\t\t\t\t}\n\t\t\t\t} else if (typeof val === \"boolean\") {\n\t\t\t\t\tstmt.bindBoolean(i + 1, val);\n\t\t\t\t} else if (val === null || val === undefined) {\n\t\t\t\t\tstmt.bindNull(i + 1);\n\t\t\t\t} else {\n\t\t\t\t\tstmt.bindVarchar(i + 1, String(val));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn await stmt.runAndReadAll();\n\t\t}\n\t\treturn await this._conn.runAndReadAll(sql);\n\t}\n}\n\nfunction coerceValues(val: unknown): unknown {\n\tif (val instanceof Date) {\n\t\treturn val.toISOString();\n\t}\n\tif (typeof val === \"bigint\") {\n\t\treturn Number(val);\n\t}\n\tif (Array.isArray(val)) {\n\t\treturn val.map(coerceValues);\n\t}\n\tif (val !== null && typeof val === \"object\") {\n\t\tconst obj = val as Record<string, unknown>;\n\t\t// DuckDB LIST types come back as { items: [...] } with null prototype\n\t\tif (\"items\" in obj && Array.isArray(obj.items)) {\n\t\t\treturn (obj.items as unknown[]).map(coerceValues);\n\t\t}\n\t\t// DuckDB DATE type comes back as { days: number } (days since Unix epoch)\n\t\tif (\"days\" in obj && typeof obj.days === \"number\" && Object.keys(obj).length === 1) {\n\t\t\tconst ms = (obj.days as number) * 86400000;\n\t\t\treturn new Date(ms).toISOString().slice(0, 10);\n\t\t}\n\t\t// DuckDB TIMESTAMP type comes back as { micros: bigint }\n\t\tif (\"micros\" in obj && typeof obj.micros === \"bigint\" && Object.keys(obj).length === 1) {\n\t\t\tconst ms = Number(obj.micros / 1000n);\n\t\t\treturn new Date(ms).toISOString();\n\t\t}\n\t\tconst out: Record<string, unknown> = {};\n\t\tfor (const [k, v] of Object.entries(obj)) {\n\t\t\tout[k] = coerceValues(v);\n\t\t}\n\t\treturn out;\n\t}\n\treturn val;\n}\n","/** SQL builder with parameterized query construction. */\n\nexport class SQLBuilder {\n\tprivate _select: string[] = [\"*\"];\n\tprivate _distinct = false;\n\tprivate _from: string;\n\tprivate _joins: string[] = [];\n\t/** WHERE clauses (public for direct manipulation by query modules). */\n\t_where: string[] = [];\n\t/** Bound parameter values (public for direct manipulation by query modules). */\n\t_params: unknown[] = [];\n\tprivate _groupBy: string[] = [];\n\tprivate _having: string[] = [];\n\tprivate _orderBy: string[] = [];\n\tprivate _limit: number | null = null;\n\tprivate _offset: number | null = null;\n\n\tconstructor(baseTable: string) {\n\t\tthis._from = baseTable;\n\t}\n\n\tselect(...columns: string[]): this {\n\t\tthis._select = columns;\n\t\treturn this;\n\t}\n\n\tdistinct(): this {\n\t\tthis._distinct = true;\n\t\treturn this;\n\t}\n\n\tjoin(clause: string): this {\n\t\tthis._joins.push(clause);\n\t\treturn this;\n\t}\n\n\twhere(condition: string, ...params: unknown[]): this {\n\t\tconst offset = this._params.length;\n\t\tlet remapped = condition;\n\t\tfor (let i = params.length; i >= 1; i--) {\n\t\t\tremapped = remapped.replaceAll(`$${i}`, `$${offset + i}`);\n\t\t}\n\t\tthis._where.push(remapped);\n\t\tthis._params.push(...params);\n\t\treturn this;\n\t}\n\n\twhereLike(column: string, value: string): this {\n\t\tconst idx = this._params.length + 1;\n\t\tthis._where.push(`LOWER(${column}) LIKE LOWER($${idx})`);\n\t\tthis._params.push(value);\n\t\treturn this;\n\t}\n\n\twhereIn(column: string, values: unknown[]): this {\n\t\tif (values.length === 0) {\n\t\t\tthis._where.push(\"FALSE\");\n\t\t\treturn this;\n\t\t}\n\t\tconst placeholders: string[] = [];\n\t\tfor (const v of values) {\n\t\t\tconst idx = this._params.length + 1;\n\t\t\tplaceholders.push(`$${idx}`);\n\t\t\tthis._params.push(v);\n\t\t}\n\t\tthis._where.push(`${column} IN (${placeholders.join(\", \")})`);\n\t\treturn this;\n\t}\n\n\twhereEq(column: string, value: unknown): this {\n\t\tconst idx = this._params.length + 1;\n\t\tthis._where.push(`${column} = $${idx}`);\n\t\tthis._params.push(value);\n\t\treturn this;\n\t}\n\n\twhereGte(column: string, value: unknown): this {\n\t\tconst idx = this._params.length + 1;\n\t\tthis._where.push(`${column} >= $${idx}`);\n\t\tthis._params.push(value);\n\t\treturn this;\n\t}\n\n\twhereLte(column: string, value: unknown): this {\n\t\tconst idx = this._params.length + 1;\n\t\tthis._where.push(`${column} <= $${idx}`);\n\t\tthis._params.push(value);\n\t\treturn this;\n\t}\n\n\twhereRegex(column: string, pattern: string): this {\n\t\tconst idx = this._params.length + 1;\n\t\tthis._where.push(`regexp_matches(${column}, $${idx})`);\n\t\tthis._params.push(pattern);\n\t\treturn this;\n\t}\n\n\twhereFuzzy(column: string, value: string, threshold = 0.8): this {\n\t\tif (typeof threshold !== \"number\" || threshold < 0 || threshold > 1) {\n\t\t\tthrow new Error(\n\t\t\t\t`threshold must be a number between 0 and 1, got ${threshold}`,\n\t\t\t);\n\t\t}\n\t\tconst idx = this._params.length + 1;\n\t\tthis._where.push(\n\t\t\t`jaro_winkler_similarity(${column}, $${idx}) > ${threshold}`,\n\t\t);\n\t\tthis._params.push(value);\n\t\treturn this;\n\t}\n\n\twhereOr(...conditions: [string, unknown][]): this {\n\t\tif (conditions.length === 0) return this;\n\t\tconst orParts: string[] = [];\n\t\tfor (const [cond, param] of conditions) {\n\t\t\tconst idx = this._params.length + 1;\n\t\t\tconst remapped = cond.replaceAll(\"$1\", `$${idx}`);\n\t\t\torParts.push(remapped);\n\t\t\tthis._params.push(param);\n\t\t}\n\t\tthis._where.push(`(${orParts.join(\" OR \")})`);\n\t\treturn this;\n\t}\n\n\tgroupBy(...columns: string[]): this {\n\t\tthis._groupBy.push(...columns);\n\t\treturn this;\n\t}\n\n\thaving(condition: string, ...params: unknown[]): this {\n\t\tconst offset = this._params.length;\n\t\tlet remapped = condition;\n\t\tfor (let i = params.length; i >= 1; i--) {\n\t\t\tremapped = remapped.replaceAll(`$${i}`, `$${offset + i}`);\n\t\t}\n\t\tthis._having.push(remapped);\n\t\tthis._params.push(...params);\n\t\treturn this;\n\t}\n\n\torderBy(...clauses: string[]): this {\n\t\tthis._orderBy.push(...clauses);\n\t\treturn this;\n\t}\n\n\tlimit(n: number): this {\n\t\tif (!Number.isInteger(n) || n < 0) {\n\t\t\tthrow new TypeError(`limit must be a non-negative integer, got ${n}`);\n\t\t}\n\t\tthis._limit = n;\n\t\treturn this;\n\t}\n\n\toffset(n: number): this {\n\t\tif (!Number.isInteger(n) || n < 0) {\n\t\t\tthrow new TypeError(`offset must be a non-negative integer, got ${n}`);\n\t\t}\n\t\tthis._offset = n;\n\t\treturn this;\n\t}\n\n\tbuild(): [string, unknown[]] {\n\t\tconst distinctStr = this._distinct ? \"DISTINCT \" : \"\";\n\t\tconst parts = [\n\t\t\t`SELECT ${distinctStr}${this._select.join(\", \")}`,\n\t\t\t`FROM ${this._from}`,\n\t\t];\n\n\t\tfor (const j of this._joins) {\n\t\t\tparts.push(j);\n\t\t}\n\n\t\tif (this._where.length > 0) {\n\t\t\tparts.push(`WHERE ${this._where.join(\" AND \")}`);\n\t\t}\n\n\t\tif (this._groupBy.length > 0) {\n\t\t\tparts.push(`GROUP BY ${this._groupBy.join(\", \")}`);\n\t\t}\n\n\t\tif (this._having.length > 0) {\n\t\t\tparts.push(`HAVING ${this._having.join(\" AND \")}`);\n\t\t}\n\n\t\tif (this._orderBy.length > 0) {\n\t\t\tparts.push(`ORDER BY ${this._orderBy.join(\", \")}`);\n\t\t}\n\n\t\tif (this._limit !== null) {\n\t\t\tparts.push(`LIMIT ${this._limit}`);\n\t\t}\n\n\t\tif (this._offset !== null) {\n\t\t\tparts.push(`OFFSET ${this._offset}`);\n\t\t}\n\n\t\treturn [parts.join(\"\\n\"), this._params];\n\t}\n}\n","import type { Connection } from \"../connection.js\";\nimport { SQLBuilder } from \"../sql-builder.js\";\nimport type { CardAtomic, CardSet } from \"../types/index.js\";\n\nexport class CardQuery {\n\tprivate _conn: Connection;\n\n\tconstructor(conn: Connection) {\n\t\tthis._conn = conn;\n\t}\n\n\tprivate async _ensure(): Promise<void> {\n\t\tawait this._conn.ensureViews(\"cards\");\n\t}\n\n\tasync getByUuid(uuid: string): Promise<CardSet | null> {\n\t\tawait this._ensure();\n\t\tconst rows = await this._conn.execute(\n\t\t\t\"SELECT * FROM cards WHERE uuid = $1\",\n\t\t\t[uuid],\n\t\t);\n\t\treturn (rows[0] as CardSet) ?? null;\n\t}\n\n\tasync getByUuids(uuids: string[]): Promise<CardSet[]> {\n\t\tif (uuids.length === 0) return [];\n\t\tawait this._ensure();\n\t\tconst q = new SQLBuilder(\"cards\").whereIn(\"uuid\", uuids);\n\t\tconst [sql, params] = q.build();\n\t\treturn (await this._conn.execute(sql, params)) as CardSet[];\n\t}\n\n\tasync getByName(\n\t\tname: string,\n\t\toptions?: { setCode?: string },\n\t): Promise<CardSet[]> {\n\t\tawait this._ensure();\n\t\tconst q = new SQLBuilder(\"cards\").whereEq(\"name\", name);\n\t\tif (options?.setCode) q.whereEq(\"setCode\", options.setCode);\n\t\tq.orderBy(\"setCode DESC\", \"number ASC\");\n\t\tconst [sql, params] = q.build();\n\t\treturn (await this._conn.execute(sql, params)) as CardSet[];\n\t}\n\n\tasync search(options?: {\n\t\tname?: string;\n\t\tfuzzyName?: string;\n\t\tlocalizedName?: string;\n\t\tsetCode?: string;\n\t\tcolors?: string[];\n\t\tcolorIdentity?: string[];\n\t\ttypes?: string;\n\t\trarity?: string;\n\t\tlegalIn?: string;\n\t\tmanaValue?: number;\n\t\tmanaValueLte?: number;\n\t\tmanaValueGte?: number;\n\t\ttext?: string;\n\t\ttextRegex?: string;\n\t\tpower?: string;\n\t\ttoughness?: string;\n\t\tartist?: string;\n\t\tkeyword?: string;\n\t\tisPromo?: boolean;\n\t\tavailability?: string;\n\t\tlanguage?: string;\n\t\tlayout?: string;\n\t\tsetType?: string;\n\t\tlimit?: number;\n\t\toffset?: number;\n\t}): Promise<CardSet[]> {\n\t\tawait this._ensure();\n\t\tconst q = new SQLBuilder(\"cards\");\n\t\tconst opts = options ?? {};\n\t\tconst limit = opts.limit ?? 100;\n\t\tconst offset = opts.offset ?? 0;\n\n\t\tif (opts.name) {\n\t\t\tif (opts.name.includes(\"%\")) {\n\t\t\t\tq.whereLike(\"name\", opts.name);\n\t\t\t} else {\n\t\t\t\tq.whereEq(\"name\", opts.name);\n\t\t\t}\n\t\t}\n\t\tif (opts.fuzzyName) {\n\t\t\tq.whereFuzzy(\"cards.name\", opts.fuzzyName, 0.8);\n\t\t}\n\t\tif (opts.setCode) q.whereEq(\"setCode\", opts.setCode);\n\t\tif (opts.rarity) q.whereEq(\"rarity\", opts.rarity);\n\t\tif (opts.manaValue !== undefined) q.whereEq(\"manaValue\", opts.manaValue);\n\t\tif (opts.manaValueLte !== undefined)\n\t\t\tq.whereLte(\"manaValue\", opts.manaValueLte);\n\t\tif (opts.manaValueGte !== undefined)\n\t\t\tq.whereGte(\"manaValue\", opts.manaValueGte);\n\t\tif (opts.text) q.whereLike(\"text\", `%${opts.text}%`);\n\t\tif (opts.textRegex) q.whereRegex(\"text\", opts.textRegex);\n\t\tif (opts.types) q.whereLike(\"type\", `%${opts.types}%`);\n\t\tif (opts.power) q.whereEq(\"power\", opts.power);\n\t\tif (opts.toughness) q.whereEq(\"toughness\", opts.toughness);\n\t\tif (opts.artist) q.whereLike(\"artist\", `%${opts.artist}%`);\n\t\tif (opts.language) q.whereEq(\"language\", opts.language);\n\t\tif (opts.layout) q.whereEq(\"layout\", opts.layout);\n\t\tif (opts.isPromo !== undefined) q.whereEq(\"isPromo\", opts.isPromo);\n\n\t\tif (opts.colors) {\n\t\t\tfor (const color of opts.colors) {\n\t\t\t\tconst idx = q._params.length + 1;\n\t\t\t\tq._where.push(`list_contains(colors, $${idx})`);\n\t\t\t\tq._params.push(color);\n\t\t\t}\n\t\t}\n\t\tif (opts.colorIdentity) {\n\t\t\tfor (const color of opts.colorIdentity) {\n\t\t\t\tconst idx = q._params.length + 1;\n\t\t\t\tq._where.push(`list_contains(colorIdentity, $${idx})`);\n\t\t\t\tq._params.push(color);\n\t\t\t}\n\t\t}\n\t\tif (opts.keyword) {\n\t\t\tconst idx = q._params.length + 1;\n\t\t\tq._where.push(`list_contains(keywords, $${idx})`);\n\t\t\tq._params.push(opts.keyword);\n\t\t}\n\t\tif (opts.availability) {\n\t\t\tconst idx = q._params.length + 1;\n\t\t\tq._where.push(`list_contains(availability, $${idx})`);\n\t\t\tq._params.push(opts.availability);\n\t\t}\n\n\t\tif (opts.localizedName) {\n\t\t\tawait this._conn.ensureViews(\"card_foreign_data\");\n\t\t\tq.select(\"cards.*\");\n\t\t\tq.join(\"JOIN card_foreign_data cfd ON cards.uuid = cfd.uuid\");\n\t\t\tif (opts.localizedName.includes(\"%\")) {\n\t\t\t\tq.whereLike(\"cfd.name\", opts.localizedName);\n\t\t\t} else {\n\t\t\t\tq.whereEq(\"cfd.name\", opts.localizedName);\n\t\t\t}\n\t\t}\n\n\t\tif (opts.legalIn) {\n\t\t\tawait this._conn.ensureViews(\"card_legalities\");\n\t\t\tq.join(\"JOIN card_legalities cl ON cards.uuid = cl.uuid\");\n\t\t\tq.whereEq(\"cl.format\", opts.legalIn);\n\t\t\tq.whereEq(\"cl.status\", \"Legal\");\n\t\t}\n\n\t\tif (opts.setType) {\n\t\t\tawait this._conn.ensureViews(\"sets\");\n\t\t\tq.select(\"cards.*\");\n\t\t\tq.join(\"JOIN sets s ON cards.setCode = s.code\");\n\t\t\tq.whereEq(\"s.type\", opts.setType);\n\t\t}\n\n\t\tif (opts.fuzzyName) {\n\t\t\tconst simIdx = q._params.length + 1;\n\t\t\tq._params.push(opts.fuzzyName);\n\t\t\tq.orderBy(\n\t\t\t\t`jaro_winkler_similarity(cards.name, $${simIdx}) DESC`,\n\t\t\t\t\"cards.number ASC\",\n\t\t\t);\n\t\t} else {\n\t\t\tq.orderBy(\"cards.name ASC\", \"cards.number ASC\");\n\t\t}\n\n\t\tq.limit(limit).offset(offset);\n\t\tconst [sql, params] = q.build();\n\t\treturn (await this._conn.execute(sql, params)) as CardSet[];\n\t}\n\n\tasync getPrintings(name: string): Promise<CardSet[]> {\n\t\treturn this.getByName(name);\n\t}\n\n\tasync getAtomic(name: string): Promise<CardAtomic[]> {\n\t\tawait this._ensure();\n\t\tconst atomicCols = [\n\t\t\t\"name\",\n\t\t\t\"asciiName\",\n\t\t\t\"faceName\",\n\t\t\t\"type\",\n\t\t\t\"types\",\n\t\t\t\"subtypes\",\n\t\t\t\"supertypes\",\n\t\t\t\"colors\",\n\t\t\t\"colorIdentity\",\n\t\t\t\"colorIndicator\",\n\t\t\t\"producedMana\",\n\t\t\t\"manaCost\",\n\t\t\t\"text\",\n\t\t\t\"layout\",\n\t\t\t\"side\",\n\t\t\t\"power\",\n\t\t\t\"toughness\",\n\t\t\t\"loyalty\",\n\t\t\t\"keywords\",\n\t\t\t\"isFunny\",\n\t\t\t\"edhrecSaltiness\",\n\t\t\t\"subsets\",\n\t\t\t\"manaValue\",\n\t\t\t\"faceConvertedManaCost\",\n\t\t\t\"faceManaValue\",\n\t\t\t\"defense\",\n\t\t\t\"hand\",\n\t\t\t\"life\",\n\t\t\t\"edhrecRank\",\n\t\t\t\"hasAlternativeDeckLimit\",\n\t\t\t\"isReserved\",\n\t\t\t\"isGameChanger\",\n\t\t\t\"printings\",\n\t\t\t\"leadershipSkills\",\n\t\t\t\"relatedCards\",\n\t\t];\n\n\t\tconst q = new SQLBuilder(\"cards\");\n\t\tq.select(...atomicCols);\n\t\tq.whereEq(\"name\", name);\n\t\tq.orderBy(\n\t\t\t\"isFunny ASC NULLS FIRST\",\n\t\t\t\"isOnlineOnly ASC NULLS FIRST\",\n\t\t\t\"side ASC NULLS FIRST\",\n\t\t);\n\t\tconst [sql, params] = q.build();\n\t\tlet rows = await this._conn.execute(sql, params);\n\n\t\t// Fallback: search by faceName for split/adventure/MDFC cards\n\t\tif (rows.length === 0) {\n\t\t\tconst q2 = new SQLBuilder(\"cards\");\n\t\t\tq2.select(...atomicCols);\n\t\t\tq2.where(\"CAST(faceName AS VARCHAR) = $1\", name);\n\t\t\tq2.orderBy(\n\t\t\t\t\"isFunny ASC NULLS FIRST\",\n\t\t\t\t\"isOnlineOnly ASC NULLS FIRST\",\n\t\t\t\t\"side ASC NULLS FIRST\",\n\t\t\t);\n\t\t\tconst [sql2, params2] = q2.build();\n\t\t\trows = await this._conn.execute(sql2, params2);\n\t\t}\n\n\t\tif (rows.length === 0) return [];\n\n\t\t// De-duplicate by name+faceName\n\t\tconst seen = new Set<string>();\n\t\tconst unique: Record<string, unknown>[] = [];\n\t\tfor (const r of rows) {\n\t\t\tconst key = `${r.name ?? \"\"}|${r.faceName ?? \"\"}`;\n\t\t\tif (!seen.has(key)) {\n\t\t\t\tseen.add(key);\n\t\t\t\tunique.push(r);\n\t\t\t}\n\t\t}\n\t\treturn unique as CardAtomic[];\n\t}\n\n\tasync findByScryfallId(scryfallId: string): Promise<CardSet[]> {\n\t\tawait this._conn.ensureViews(\"cards\", \"card_identifiers\");\n\t\tconst sql =\n\t\t\t\"SELECT c.* FROM cards c \" +\n\t\t\t\"JOIN card_identifiers ci ON c.uuid = ci.uuid \" +\n\t\t\t\"WHERE ci.scryfallId = $1\";\n\t\treturn (await this._conn.execute(sql, [scryfallId])) as CardSet[];\n\t}\n\n\tasync random(count = 1): Promise<CardSet[]> {\n\t\tawait this._ensure();\n\t\tconst sql = `SELECT * FROM cards USING SAMPLE ${count}`;\n\t\treturn (await this._conn.execute(sql)) as CardSet[];\n\t}\n\n\tasync count(filters?: Record<string, unknown>): Promise<number> {\n\t\tawait this._ensure();\n\t\tif (!filters || Object.keys(filters).length === 0) {\n\t\t\treturn (\n\t\t\t\t((await this._conn.executeScalar(\n\t\t\t\t\t\"SELECT COUNT(*) FROM cards\",\n\t\t\t\t)) as number) ?? 0\n\t\t\t);\n\t\t}\n\t\tconst q = new SQLBuilder(\"cards\").select(\"COUNT(*)\");\n\t\tfor (const [col, val] of Object.entries(filters)) {\n\t\t\tq.whereEq(col, val);\n\t\t}\n\t\tconst [sql, params] = q.build();\n\t\treturn ((await this._conn.executeScalar(sql, params)) as number) ?? 0;\n\t}\n}\n","import type { Connection } from \"../connection.js\";\nimport { SQLBuilder } from \"../sql-builder.js\";\nimport type { SetList } from \"../types/index.js\";\n\nexport class SetQuery {\n\tprivate _conn: Connection;\n\n\tconstructor(conn: Connection) {\n\t\tthis._conn = conn;\n\t}\n\n\tprivate async _ensure(): Promise<void> {\n\t\tawait this._conn.ensureViews(\"sets\");\n\t}\n\n\tasync get(code: string): Promise<SetList | null> {\n\t\tawait this._ensure();\n\t\tconst rows = await this._conn.execute(\n\t\t\t\"SELECT * FROM sets WHERE code = $1\",\n\t\t\t[code.toUpperCase()],\n\t\t);\n\t\treturn (rows[0] as SetList) ?? null;\n\t}\n\n\tasync list(options?: {\n\t\tsetType?: string;\n\t\tname?: string;\n\t\tlimit?: number;\n\t\toffset?: number;\n\t}): Promise<SetList[]> {\n\t\tawait this._ensure();\n\t\tconst q = new SQLBuilder(\"sets\");\n\n\t\tif (options?.setType) q.whereEq(\"type\", options.setType);\n\t\tif (options?.name) {\n\t\t\tif (options.name.includes(\"%\")) {\n\t\t\t\tq.whereLike(\"name\", options.name);\n\t\t\t} else {\n\t\t\t\tq.whereEq(\"name\", options.name);\n\t\t\t}\n\t\t}\n\n\t\tq.orderBy(\"releaseDate DESC\");\n\t\tq.limit(options?.limit ?? 1000).offset(options?.offset ?? 0);\n\n\t\tconst [sql, params] = q.build();\n\t\treturn (await this._conn.execute(sql, params)) as SetList[];\n\t}\n\n\tasync search(options?: {\n\t\tname?: string;\n\t\tsetType?: string;\n\t\tblock?: string;\n\t\treleaseYear?: number;\n\t\tlimit?: number;\n\t}): Promise<SetList[]> {\n\t\tawait this._ensure();\n\t\tconst q = new SQLBuilder(\"sets\");\n\n\t\tif (options?.name) q.whereLike(\"name\", `%${options.name}%`);\n\t\tif (options?.setType) q.whereEq(\"type\", options.setType);\n\t\tif (options?.block) q.whereLike(\"block\", `%${options.block}%`);\n\t\tif (options?.releaseYear) {\n\t\t\tconst idx = q._params.length + 1;\n\t\t\tq._where.push(`EXTRACT(YEAR FROM CAST(releaseDate AS DATE)) = $${idx}`);\n\t\t\tq._params.push(options.releaseYear);\n\t\t}\n\n\t\tq.orderBy(\"releaseDate DESC\");\n\t\tq.limit(options?.limit ?? 100);\n\n\t\tconst [sql, params] = q.build();\n\t\treturn (await this._conn.execute(sql, params)) as SetList[];\n\t}\n\n\tasync getFinancialSummary(\n\t\tsetCode: string,\n\t\toptions?: {\n\t\t\tprovider?: string;\n\t\t\tcurrency?: string;\n\t\t\tfinish?: string;\n\t\t\tpriceType?: string;\n\t\t},\n\t): Promise<Record<string, unknown> | null> {\n\t\tawait this._conn.ensureViews(\"cards\", \"all_prices_today\");\n\n\t\tconst provider = options?.provider ?? \"tcgplayer\";\n\t\tconst currency = options?.currency ?? \"USD\";\n\t\tconst finish = options?.finish ?? \"normal\";\n\t\tconst priceType = options?.priceType ?? \"retail\";\n\n\t\tconst sql = `\n\t\t\tSELECT\n\t\t\t\tCOUNT(DISTINCT c.uuid) AS card_count,\n\t\t\t\tROUND(SUM(p.price), 2) AS total_value,\n\t\t\t\tROUND(AVG(p.price), 2) AS avg_value,\n\t\t\t\tMIN(p.price) AS min_value,\n\t\t\t\tMAX(p.price) AS max_price,\n\t\t\t\tMAX(p.date) AS date\n\t\t\tFROM cards c\n\t\t\tJOIN all_prices_today p ON c.uuid = p.uuid\n\t\t\tWHERE c.setCode = $1\n\t\t\t AND p.provider = $2\n\t\t\t AND p.currency = $3\n\t\t\t AND p.finish = $4\n\t\t\t AND p.price_type = $5\n\t\t\t AND p.date = (SELECT MAX(p2.date) FROM all_prices_today p2)\n\t\t`;\n\t\tconst rows = await this._conn.execute(sql, [\n\t\t\tsetCode.toUpperCase(),\n\t\t\tprovider,\n\t\t\tcurrency,\n\t\t\tfinish,\n\t\t\tpriceType,\n\t\t]);\n\t\tif (!rows.length || (rows[0].card_count as number) === 0) return null;\n\t\treturn rows[0];\n\t}\n\n\tasync count(): Promise<number> {\n\t\tawait this._ensure();\n\t\treturn (\n\t\t\t((await this._conn.executeScalar(\n\t\t\t\t\"SELECT COUNT(*) FROM sets\",\n\t\t\t)) as number) ?? 0\n\t\t);\n\t}\n}\n","import type { Connection } from \"../connection.js\";\nimport { SQLBuilder } from \"../sql-builder.js\";\nimport type { CardToken } from \"../types/index.js\";\n\nexport class TokenQuery {\n\tprivate _conn: Connection;\n\n\tconstructor(conn: Connection) {\n\t\tthis._conn = conn;\n\t}\n\n\tprivate async _ensure(): Promise<void> {\n\t\tawait this._conn.ensureViews(\"tokens\");\n\t}\n\n\tasync getByUuid(uuid: string): Promise<CardToken | null> {\n\t\tawait this._ensure();\n\t\tconst rows = await this._conn.execute(\n\t\t\t\"SELECT * FROM tokens WHERE uuid = $1\",\n\t\t\t[uuid],\n\t\t);\n\t\treturn (rows[0] as CardToken) ?? null;\n\t}\n\n\tasync getByUuids(uuids: string[]): Promise<CardToken[]> {\n\t\tif (uuids.length === 0) return [];\n\t\tawait this._ensure();\n\t\tconst q = new SQLBuilder(\"tokens\").whereIn(\"uuid\", uuids);\n\t\tconst [sql, params] = q.build();\n\t\treturn (await this._conn.execute(sql, params)) as CardToken[];\n\t}\n\n\tasync getByName(\n\t\tname: string,\n\t\toptions?: { setCode?: string },\n\t): Promise<CardToken[]> {\n\t\tawait this._ensure();\n\t\tconst q = new SQLBuilder(\"tokens\").whereEq(\"name\", name);\n\t\tif (options?.setCode) q.whereEq(\"setCode\", options.setCode);\n\t\tq.orderBy(\"setCode DESC\", \"number ASC\");\n\t\tconst [sql, params] = q.build();\n\t\treturn (await this._conn.execute(sql, params)) as CardToken[];\n\t}\n\n\tasync search(options?: {\n\t\tname?: string;\n\t\tsetCode?: string;\n\t\tcolors?: string[];\n\t\ttypes?: string;\n\t\tartist?: string;\n\t\tlimit?: number;\n\t\toffset?: number;\n\t}): Promise<CardToken[]> {\n\t\tawait this._ensure();\n\t\tconst q = new SQLBuilder(\"tokens\");\n\n\t\tif (options?.name) {\n\t\t\tif (options.name.includes(\"%\")) {\n\t\t\t\tq.whereLike(\"name\", options.name);\n\t\t\t} else {\n\t\t\t\tq.whereEq(\"name\", options.name);\n\t\t\t}\n\t\t}\n\t\tif (options?.setCode) q.whereEq(\"setCode\", options.setCode);\n\t\tif (options?.types) q.whereLike(\"type\", `%${options.types}%`);\n\t\tif (options?.artist) q.whereLike(\"artist\", `%${options.artist}%`);\n\n\t\tif (options?.colors) {\n\t\t\tfor (const color of options.colors) {\n\t\t\t\tconst idx = q._params.length + 1;\n\t\t\t\tq._where.push(`list_contains(colors, $${idx})`);\n\t\t\t\tq._params.push(color);\n\t\t\t}\n\t\t}\n\n\t\tq.orderBy(\"name ASC\", \"number ASC\");\n\t\tq.limit(options?.limit ?? 100).offset(options?.offset ?? 0);\n\n\t\tconst [sql, params] = q.build();\n\t\treturn (await this._conn.execute(sql, params)) as CardToken[];\n\t}\n\n\tasync forSet(setCode: string): Promise<CardToken[]> {\n\t\treturn this.search({ setCode, limit: 1000 });\n\t}\n\n\tasync count(filters?: Record<string, unknown>): Promise<number> {\n\t\tawait this._ensure();\n\t\tif (!filters || Object.keys(filters).length === 0) {\n\t\t\treturn (\n\t\t\t\t((await this._conn.executeScalar(\n\t\t\t\t\t\"SELECT COUNT(*) FROM tokens\",\n\t\t\t\t)) as number) ?? 0\n\t\t\t);\n\t\t}\n\t\tconst q = new SQLBuilder(\"tokens\").select(\"COUNT(*)\");\n\t\tfor (const [col, val] of Object.entries(filters)) {\n\t\t\tq.whereEq(col, val);\n\t\t}\n\t\tconst [sql, params] = q.build();\n\t\treturn ((await this._conn.executeScalar(sql, params)) as number) ?? 0;\n\t}\n}\n","import type { Connection } from \"../connection.js\";\n\nexport class PriceQuery {\n\tprivate _conn: Connection;\n\n\tconstructor(conn: Connection) {\n\t\tthis._conn = conn;\n\t}\n\n\tprivate async _ensure(): Promise<void> {\n\t\tawait this._conn.ensureViews(\"all_prices_today\");\n\t}\n\n\tasync get(uuid: string): Promise<Record<string, unknown> | null> {\n\t\tawait this._ensure();\n\t\tconst rows = await this._conn.execute(\n\t\t\t\"SELECT * FROM all_prices_today WHERE uuid = $1 ORDER BY source, provider, price_type, finish, date\",\n\t\t\t[uuid],\n\t\t);\n\t\tif (rows.length === 0) return null;\n\t\tconst result: Record<string, unknown> = {};\n\t\tfor (const r of rows) {\n\t\t\tconst srcKey = r.source as string;\n\t\t\tif (!result[srcKey]) result[srcKey] = {};\n\t\t\tconst src = result[srcKey] as Record<string, unknown>;\n\n\t\t\tconst provKey = r.provider as string;\n\t\t\tif (!src[provKey]) src[provKey] = { currency: r.currency ?? \"USD\" };\n\t\t\tconst prov = src[provKey] as Record<string, unknown>;\n\n\t\t\tconst catKey = r.price_type as string;\n\t\t\tif (!prov[catKey]) prov[catKey] = {};\n\t\t\tconst cat = prov[catKey] as Record<string, unknown>;\n\n\t\t\tconst finKey = r.finish as string;\n\t\t\tif (!cat[finKey]) cat[finKey] = {};\n\t\t\tconst fin = cat[finKey] as Record<string, unknown>;\n\n\t\t\tfin[r.date as string] = r.price;\n\t\t}\n\t\treturn result;\n\t}\n\n\tasync today(\n\t\tuuid: string,\n\t\toptions?: {\n\t\t\tprovider?: string;\n\t\t\tfinish?: string;\n\t\t\tpriceType?: string;\n\t\t},\n\t): Promise<Record<string, unknown>[]> {\n\t\tawait this._ensure();\n\t\tconst parts = [\n\t\t\t\"SELECT * FROM all_prices_today\",\n\t\t\t\"WHERE uuid = $1\",\n\t\t\t\"AND date = (SELECT MAX(p2.date) FROM all_prices_today p2 WHERE p2.uuid = $1)\",\n\t\t];\n\t\tconst params: unknown[] = [uuid];\n\t\tlet idx = 2;\n\t\tif (options?.provider) {\n\t\t\tparts.push(`AND provider = $${idx}`);\n\t\t\tparams.push(options.provider);\n\t\t\tidx++;\n\t\t}\n\t\tif (options?.finish) {\n\t\t\tparts.push(`AND finish = $${idx}`);\n\t\t\tparams.push(options.finish);\n\t\t\tidx++;\n\t\t}\n\t\tif (options?.priceType) {\n\t\t\tparts.push(`AND price_type = $${idx}`);\n\t\t\tparams.push(options.priceType);\n\t\t\tidx++;\n\t\t}\n\t\treturn this._conn.execute(parts.join(\" \"), params);\n\t}\n\n\tasync history(\n\t\tuuid: string,\n\t\toptions?: {\n\t\t\tprovider?: string;\n\t\t\tfinish?: string;\n\t\t\tpriceType?: string;\n\t\t\tdateFrom?: string;\n\t\t\tdateTo?: string;\n\t\t},\n\t): Promise<Record<string, unknown>[]> {\n\t\tawait this._conn.ensureViews(\"all_prices\");\n\t\tconst parts = [\"SELECT * FROM all_prices WHERE uuid = $1\"];\n\t\tconst params: unknown[] = [uuid];\n\t\tlet idx = 2;\n\t\tif (options?.provider) {\n\t\t\tparts.push(`AND provider = $${idx}`);\n\t\t\tparams.push(options.provider);\n\t\t\tidx++;\n\t\t}\n\t\tif (options?.finish) {\n\t\t\tparts.push(`AND finish = $${idx}`);\n\t\t\tparams.push(options.finish);\n\t\t\tidx++;\n\t\t}\n\t\tif (options?.priceType) {\n\t\t\tparts.push(`AND price_type = $${idx}`);\n\t\t\tparams.push(options.priceType);\n\t\t\tidx++;\n\t\t}\n\t\tif (options?.dateFrom) {\n\t\t\tparts.push(`AND date >= $${idx}`);\n\t\t\tparams.push(options.dateFrom);\n\t\t\tidx++;\n\t\t}\n\t\tif (options?.dateTo) {\n\t\t\tparts.push(`AND date <= $${idx}`);\n\t\t\tparams.push(options.dateTo);\n\t\t\tidx++;\n\t\t}\n\t\tparts.push(\"ORDER BY date ASC\");\n\t\treturn this._conn.execute(parts.join(\" \"), params);\n\t}\n\n\tasync priceTrend(\n\t\tuuid: string,\n\t\toptions?: {\n\t\t\tprovider?: string;\n\t\t\tfinish?: string;\n\t\t\tpriceType?: string;\n\t\t},\n\t): Promise<Record<string, unknown> | null> {\n\t\tawait this._conn.ensureViews(\"all_prices\");\n\t\tconst priceType = options?.priceType ?? \"retail\";\n\t\tconst parts = [\n\t\t\t\"SELECT\",\n\t\t\t\" MIN(price) AS min_price,\",\n\t\t\t\" MAX(price) AS max_price,\",\n\t\t\t\" ROUND(AVG(price), 2) AS avg_price,\",\n\t\t\t\" MIN(date) AS first_date,\",\n\t\t\t\" MAX(date) AS last_date,\",\n\t\t\t\" COUNT(*) AS data_points\",\n\t\t\t\"FROM all_prices\",\n\t\t\t\"WHERE uuid = $1 AND price_type = $2\",\n\t\t];\n\t\tconst params: unknown[] = [uuid, priceType];\n\t\tlet idx = 3;\n\t\tif (options?.provider) {\n\t\t\tparts.push(`AND provider = $${idx}`);\n\t\t\tparams.push(options.provider);\n\t\t\tidx++;\n\t\t}\n\t\tif (options?.finish) {\n\t\t\tparts.push(`AND finish = $${idx}`);\n\t\t\tparams.push(options.finish);\n\t\t\tidx++;\n\t\t}\n\t\tconst rows = await this._conn.execute(parts.join(\" \"), params);\n\t\tif (!rows.length || (rows[0].data_points as number) === 0) return null;\n\t\treturn rows[0];\n\t}\n\n\tasync cheapestPrinting(\n\t\tname: string,\n\t\toptions?: {\n\t\t\tprovider?: string;\n\t\t\tfinish?: string;\n\t\t\tpriceType?: string;\n\t\t},\n\t): Promise<Record<string, unknown> | null> {\n\t\tawait this._ensure();\n\t\tawait this._conn.ensureViews(\"cards\");\n\t\tconst provider = options?.provider ?? \"tcgplayer\";\n\t\tconst finish = options?.finish ?? \"normal\";\n\t\tconst priceType = options?.priceType ?? \"retail\";\n\t\tconst sql =\n\t\t\t\"SELECT c.uuid, c.setCode, c.number, p.price, p.date \" +\n\t\t\t\"FROM cards c \" +\n\t\t\t\"JOIN all_prices_today p ON c.uuid = p.uuid \" +\n\t\t\t\"WHERE c.name = $1 AND p.provider = $2 \" +\n\t\t\t\"AND p.finish = $3 AND p.price_type = $4 \" +\n\t\t\t\"AND p.date = (SELECT MAX(p2.date) FROM all_prices_today p2 \" +\n\t\t\t\"WHERE p2.uuid = c.uuid AND p2.provider = $2 \" +\n\t\t\t\"AND p2.finish = $3 AND p2.price_type = $4) \" +\n\t\t\t\"ORDER BY p.price ASC \" +\n\t\t\t\"LIMIT 1\";\n\t\tconst rows = await this._conn.execute(sql, [\n\t\t\tname,\n\t\t\tprovider,\n\t\t\tfinish,\n\t\t\tpriceType,\n\t\t]);\n\t\treturn rows[0] ?? null;\n\t}\n\n\tasync cheapestPrintings(options?: {\n\t\tprovider?: string;\n\t\tfinish?: string;\n\t\tpriceType?: string;\n\t\tlimit?: number;\n\t\toffset?: number;\n\t}): Promise<Record<string, unknown>[]> {\n\t\tawait this._ensure();\n\t\tawait this._conn.ensureViews(\"cards\");\n\t\tconst provider = options?.provider ?? \"tcgplayer\";\n\t\tconst finish = options?.finish ?? \"normal\";\n\t\tconst priceType = options?.priceType ?? \"retail\";\n\t\tconst limit = options?.limit ?? 100;\n\t\tconst offset = options?.offset ?? 0;\n\t\tconst sql = `SELECT c.name, arg_min(c.setCode, p.price) AS cheapest_set, arg_min(c.number, p.price) AS cheapest_number, arg_min(c.uuid, p.price) AS cheapest_uuid, MIN(p.price) AS min_price FROM cards c JOIN all_prices_today p ON c.uuid = p.uuid WHERE p.provider = $1 AND p.finish = $2 AND p.price_type = $3 AND p.date = (SELECT MAX(date) FROM all_prices_today) GROUP BY c.name ORDER BY min_price ASC LIMIT ${limit} OFFSET ${offset}`;\n\t\treturn this._conn.execute(sql, [provider, finish, priceType]);\n\t}\n\n\tasync mostExpensivePrintings(options?: {\n\t\tprovider?: string;\n\t\tfinish?: string;\n\t\tpriceType?: string;\n\t\tlimit?: number;\n\t\toffset?: number;\n\t}): Promise<Record<string, unknown>[]> {\n\t\tawait this._ensure();\n\t\tawait this._conn.ensureViews(\"cards\");\n\t\tconst provider = options?.provider ?? \"tcgplayer\";\n\t\tconst finish = options?.finish ?? \"normal\";\n\t\tconst priceType = options?.priceType ?? \"retail\";\n\t\tconst limit = options?.limit ?? 100;\n\t\tconst offset = options?.offset ?? 0;\n\t\tconst sql = `SELECT c.name, arg_max(c.setCode, p.price) AS priciest_set, arg_max(c.number, p.price) AS priciest_number, arg_max(c.uuid, p.price) AS priciest_uuid, MAX(p.price) AS max_price FROM cards c JOIN all_prices_today p ON c.uuid = p.uuid WHERE p.provider = $1 AND p.finish = $2 AND p.price_type = $3 AND p.date = (SELECT MAX(date) FROM all_prices_today) GROUP BY c.name ORDER BY max_price DESC LIMIT ${limit} OFFSET ${offset}`;\n\t\treturn this._conn.execute(sql, [provider, finish, priceType]);\n\t}\n}\n","import type { Connection } from \"../connection.js\";\nimport type { CardSet } from \"../types/index.js\";\n\nexport class LegalityQuery {\n\tprivate _conn: Connection;\n\n\tconstructor(conn: Connection) {\n\t\tthis._conn = conn;\n\t}\n\n\tprivate async _ensure(): Promise<void> {\n\t\tawait this._conn.ensureViews(\"card_legalities\");\n\t}\n\n\tprivate async _cardsByStatus(\n\t\tformatName: string,\n\t\tstatus: string,\n\t\toptions?: { limit?: number; offset?: number },\n\t): Promise<Record<string, unknown>[]> {\n\t\tawait this._ensure();\n\t\tawait this._conn.ensureViews(\"cards\");\n\t\tconst limit = options?.limit ?? 100;\n\t\tconst offset = options?.offset ?? 0;\n\t\treturn this._conn.execute(\n\t\t\t`SELECT c.name, c.uuid FROM cards c JOIN card_legalities cl ON c.uuid = cl.uuid WHERE cl.format = $1 AND cl.status = $2 ORDER BY c.name ASC LIMIT ${limit} OFFSET ${offset}`,\n\t\t\t[formatName, status],\n\t\t);\n\t}\n\n\tasync formatsForCard(uuid: string): Promise<Record<string, string>> {\n\t\tawait this._ensure();\n\t\tconst rows = await this._conn.execute(\n\t\t\t\"SELECT format, status FROM card_legalities WHERE uuid = $1\",\n\t\t\t[uuid],\n\t\t);\n\t\tconst result: Record<string, string> = {};\n\t\tfor (const r of rows) {\n\t\t\tresult[r.format as string] = r.status as string;\n\t\t}\n\t\treturn result;\n\t}\n\n\tasync legalIn(\n\t\tformatName: string,\n\t\toptions?: { limit?: number; offset?: number },\n\t): Promise<CardSet[]> {\n\t\tawait this._conn.ensureViews(\"cards\", \"card_legalities\");\n\t\tconst limit = options?.limit ?? 100;\n\t\tconst offset = options?.offset ?? 0;\n\t\tconst sql = `SELECT DISTINCT c.* FROM cards c JOIN card_legalities cl ON c.uuid = cl.uuid WHERE cl.format = $1 AND cl.status = 'Legal' ORDER BY c.name ASC LIMIT ${limit} OFFSET ${offset}`;\n\t\treturn (await this._conn.execute(sql, [formatName])) as CardSet[];\n\t}\n\n\tasync isLegal(uuid: string, formatName: string): Promise<boolean> {\n\t\tawait this._ensure();\n\t\tconst result = await this._conn.executeScalar(\n\t\t\t\"SELECT COUNT(*) FROM card_legalities \" +\n\t\t\t\t\"WHERE uuid = $1 AND format = $2 AND status = 'Legal'\",\n\t\t\t[uuid, formatName],\n\t\t);\n\t\treturn ((result as number) ?? 0) > 0;\n\t}\n\n\tasync bannedIn(\n\t\tformatName: string,\n\t\toptions?: { limit?: number; offset?: number },\n\t): Promise<Record<string, unknown>[]> {\n\t\treturn this._cardsByStatus(formatName, \"Banned\", options);\n\t}\n\n\tasync restrictedIn(\n\t\tformatName: string,\n\t\toptions?: { limit?: number; offset?: number },\n\t): Promise<Record<string, unknown>[]> {\n\t\treturn this._cardsByStatus(formatName, \"Restricted\", options);\n\t}\n\n\tasync suspendedIn(\n\t\tformatName: string,\n\t\toptions?: { limit?: number; offset?: number },\n\t): Promise<Record<string, unknown>[]> {\n\t\treturn this._cardsByStatus(formatName, \"Suspended\", options);\n\t}\n\n\tasync notLegalIn(\n\t\tformatName: string,\n\t\toptions?: { limit?: number; offset?: number },\n\t): Promise<Record<string, unknown>[]> {\n\t\treturn this._cardsByStatus(formatName, \"Not Legal\", options);\n\t}\n}\n","import type { Connection } from \"../connection.js\";\nimport type { CardSet } from \"../types/index.js\";\n\nconst KNOWN_ID_COLUMNS = new Set([\n\t\"cardKingdomEtchedId\",\n\t\"cardKingdomFoilId\",\n\t\"cardKingdomId\",\n\t\"cardsphereId\",\n\t\"cardsphereFoilId\",\n\t\"mcmId\",\n\t\"mcmMetaId\",\n\t\"mtgArenaId\",\n\t\"mtgoFoilId\",\n\t\"mtgoId\",\n\t\"multiverseId\",\n\t\"scryfallId\",\n\t\"scryfallIllustrationId\",\n\t\"scryfallOracleId\",\n\t\"tcgplayerEtchedProductId\",\n\t\"tcgplayerProductId\",\n]);\n\nexport class IdentifierQuery {\n\tprivate _conn: Connection;\n\n\tconstructor(conn: Connection) {\n\t\tthis._conn = conn;\n\t}\n\n\tprivate async _ensure(): Promise<void> {\n\t\tawait this._conn.ensureViews(\"cards\", \"card_identifiers\");\n\t}\n\n\tprivate async _findBy(idColumn: string, value: string): Promise<CardSet[]> {\n\t\tawait this._ensure();\n\t\tconst sql = `SELECT c.* FROM cards c JOIN card_identifiers ci ON c.uuid = ci.uuid WHERE ci.${idColumn} = $1`;\n\t\treturn (await this._conn.execute(sql, [value])) as CardSet[];\n\t}\n\n\tasync findBy(idType: string, value: string): Promise<CardSet[]> {\n\t\tif (!KNOWN_ID_COLUMNS.has(idType)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Unknown identifier type '${idType}'. Known types: ${[...KNOWN_ID_COLUMNS].sort().join(\", \")}`,\n\t\t\t);\n\t\t}\n\t\treturn this._findBy(idType, value);\n\t}\n\n\tasync findByScryfallId(scryfallId: string): Promise<CardSet[]> {\n\t\treturn this._findBy(\"scryfallId\", scryfallId);\n\t}\n\n\tasync findByScryfallOracleId(oracleId: string): Promise<CardSet[]> {\n\t\treturn this._findBy(\"scryfallOracleId\", oracleId);\n\t}\n\n\tasync findByScryfallIllustrationId(\n\t\tillustrationId: string,\n\t): Promise<CardSet[]> {\n\t\treturn this._findBy(\"scryfallIllustrationId\", illustrationId);\n\t}\n\n\tasync findByTcgplayerId(tcgplayerId: string): Promise<CardSet[]> {\n\t\treturn this._findBy(\"tcgplayerProductId\", tcgplayerId);\n\t}\n\n\tasync findByTcgplayerEtchedId(tcgplayerEtchedId: string): Promise<CardSet[]> {\n\t\treturn this._findBy(\"tcgplayerEtchedProductId\", tcgplayerEtchedId);\n\t}\n\n\tasync findByMtgoId(mtgoId: string): Promise<CardSet[]> {\n\t\treturn this._findBy(\"mtgoId\", mtgoId);\n\t}\n\n\tasync findByMtgoFoilId(mtgoFoilId: string): Promise<CardSet[]> {\n\t\treturn this._findBy(\"mtgoFoilId\", mtgoFoilId);\n\t}\n\n\tasync findByMtgArenaId(arenaId: string): Promise<CardSet[]> {\n\t\treturn this._findBy(\"mtgArenaId\", arenaId);\n\t}\n\n\tasync findByMultiverseId(multiverseId: string): Promise<CardSet[]> {\n\t\treturn this._findBy(\"multiverseId\", multiverseId);\n\t}\n\n\tasync findByMcmId(mcmId: string): Promise<CardSet[]> {\n\t\treturn this._findBy(\"mcmId\", mcmId);\n\t}\n\n\tasync findByMcmMetaId(mcmMetaId: string): Promise<CardSet[]> {\n\t\treturn this._findBy(\"mcmMetaId\", mcmMetaId);\n\t}\n\n\tasync findByCardKingdomId(ckId: string): Promise<CardSet[]> {\n\t\treturn this._findBy(\"cardKingdomId\", ckId);\n\t}\n\n\tasync findByCardKingdomFoilId(ckFoilId: string): Promise<CardSet[]> {\n\t\treturn this._findBy(\"cardKingdomFoilId\", ckFoilId);\n\t}\n\n\tasync findByCardKingdomEtchedId(ckEtchedId: string): Promise<CardSet[]> {\n\t\treturn this._findBy(\"cardKingdomEtchedId\", ckEtchedId);\n\t}\n\n\tasync findByCardsphereId(csId: string): Promise<CardSet[]> {\n\t\treturn this._findBy(\"cardsphereId\", csId);\n\t}\n\n\tasync findByCardsphereFoilId(csFoilId: string): Promise<CardSet[]> {\n\t\treturn this._findBy(\"cardsphereFoilId\", csFoilId);\n\t}\n\n\tasync getIdentifiers(uuid: string): Promise<Record<string, unknown> | null> {\n\t\tawait this._conn.ensureViews(\"card_identifiers\");\n\t\tconst rows = await this._conn.execute(\n\t\t\t\"SELECT * FROM card_identifiers WHERE uuid = $1\",\n\t\t\t[uuid],\n\t\t);\n\t\treturn rows[0] ?? null;\n\t}\n}\n","import type { CacheManager } from \"../cache.js\";\nimport type { DeckList } from \"../types/index.js\";\n\nexport class DeckQuery {\n\tprivate _cache: CacheManager;\n\tprivate _data: Record<string, unknown>[] | null = null;\n\n\tconstructor(cache: CacheManager) {\n\t\tthis._cache = cache;\n\t}\n\n\tprivate async _ensure(): Promise<void> {\n\t\tif (this._data !== null) return;\n\t\ttry {\n\t\t\tconst raw = await this._cache.loadJson(\"deck_list\");\n\t\t\tthis._data = (raw.data as Record<string, unknown>[]) ?? [];\n\t\t} catch {\n\t\t\tthis._data = [];\n\t\t}\n\t}\n\n\tasync list(options?: {\n\t\tsetCode?: string;\n\t\tdeckType?: string;\n\t}): Promise<DeckList[]> {\n\t\tawait this._ensure();\n\t\tlet results = this._data!;\n\n\t\tif (options?.setCode) {\n\t\t\tconst codeUpper = options.setCode.toUpperCase();\n\t\t\tresults = results.filter(\n\t\t\t\t(d) => ((d.code as string) ?? \"\").toUpperCase() === codeUpper,\n\t\t\t);\n\t\t}\n\t\tif (options?.deckType) {\n\t\t\tresults = results.filter((d) => d.type === options.deckType);\n\t\t}\n\t\treturn results as DeckList[];\n\t}\n\n\tasync search(options?: {\n\t\tname?: string;\n\t\tsetCode?: string;\n\t}): Promise<DeckList[]> {\n\t\tawait this._ensure();\n\t\tlet results = this._data!;\n\n\t\tif (options?.name) {\n\t\t\tconst nameLower = options.name.toLowerCase();\n\t\t\tresults = results.filter((d) =>\n\t\t\t\t((d.name as string) ?? \"\").toLowerCase().includes(nameLower),\n\t\t\t);\n\t\t}\n\t\tif (options?.setCode) {\n\t\t\tconst codeUpper = options.setCode.toUpperCase();\n\t\t\tresults = results.filter(\n\t\t\t\t(d) => ((d.code as string) ?? \"\").toUpperCase() === codeUpper,\n\t\t\t);\n\t\t}\n\t\treturn results as DeckList[];\n\t}\n\n\tasync count(): Promise<number> {\n\t\tawait this._ensure();\n\t\treturn this._data!.length;\n\t}\n}\n","import type { Connection } from \"../connection.js\";\nimport { SQLBuilder } from \"../sql-builder.js\";\n\nexport class SealedQuery {\n\tprivate _conn: Connection;\n\n\tconstructor(conn: Connection) {\n\t\tthis._conn = conn;\n\t}\n\n\tprivate async _ensure(): Promise<void> {\n\t\tawait this._conn.ensureViews(\"sets\");\n\t}\n\n\tasync list(options?: {\n\t\tsetCode?: string;\n\t\tcategory?: string;\n\t\tlimit?: number;\n\t}): Promise<Record<string, unknown>[]> {\n\t\tawait this._ensure();\n\t\ttry {\n\t\t\tconst q = new SQLBuilder(\"sets\");\n\t\t\tq.select(\"code\", \"name AS setName\", \"sealedProduct\");\n\n\t\t\tif (options?.setCode) {\n\t\t\t\tq.whereEq(\"code\", options.setCode.toUpperCase());\n\t\t\t}\n\t\t\tq.limit(options?.limit ?? 100);\n\n\t\t\tconst [sql, params] = q.build();\n\t\t\tconst rows = await this._conn.execute(sql, params);\n\n\t\t\tconst products: Record<string, unknown>[] = [];\n\t\t\tfor (const row of rows) {\n\t\t\t\tconst sealed = row.sealedProduct;\n\t\t\t\tif (sealed && Array.isArray(sealed)) {\n\t\t\t\t\tfor (const sp of sealed) {\n\t\t\t\t\t\tif (sp && typeof sp === \"object\") {\n\t\t\t\t\t\t\tconst product = sp as Record<string, unknown>;\n\t\t\t\t\t\t\tif (options?.category && product.category !== options.category) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tproduct.setCode = row.code;\n\t\t\t\t\t\t\tproducts.push(product);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn products;\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t}\n\n\tasync get(uuid: string): Promise<Record<string, unknown> | null> {\n\t\tawait this._ensure();\n\t\ttry {\n\t\t\tconst sql =\n\t\t\t\t\"SELECT sub.code AS setCode, sub.sp \" +\n\t\t\t\t\"FROM (\" +\n\t\t\t\t\" SELECT code, UNNEST(sealedProduct) AS sp \" +\n\t\t\t\t\" FROM sets WHERE sealedProduct IS NOT NULL\" +\n\t\t\t\t\") sub \" +\n\t\t\t\t\"WHERE sub.sp.uuid = $1 \" +\n\t\t\t\t\"LIMIT 1\";\n\t\t\tconst rows = await this._conn.execute(sql, [uuid]);\n\t\t\tif (rows.length === 0) return null;\n\t\t\tconst row = rows[0];\n\t\t\tconst product = (row.sp ?? {}) as Record<string, unknown>;\n\t\t\tif (typeof product === \"object\") {\n\t\t\t\tproduct.setCode = row.setCode;\n\t\t\t\treturn product;\n\t\t\t}\n\t\t\treturn null;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n}\n","import type { Connection } from \"../connection.js\";\nimport type { TcgplayerSkus } from \"../types/index.js\";\n\nexport class SkuQuery {\n\tprivate _conn: Connection;\n\n\tconstructor(conn: Connection) {\n\t\tthis._conn = conn;\n\t}\n\n\tprivate async _ensure(): Promise<void> {\n\t\tawait this._conn.ensureViews(\"tcgplayer_skus\");\n\t}\n\n\tasync get(uuid: string): Promise<TcgplayerSkus[]> {\n\t\tawait this._ensure();\n\t\tconst rows = await this._conn.execute(\n\t\t\t\"SELECT * FROM tcgplayer_skus WHERE uuid = $1\",\n\t\t\t[uuid],\n\t\t);\n\t\treturn rows as unknown as TcgplayerSkus[];\n\t}\n\n\tasync findBySkuId(skuId: number): Promise<Record<string, unknown> | null> {\n\t\tawait this._ensure();\n\t\tconst rows = await this._conn.execute(\n\t\t\t\"SELECT * FROM tcgplayer_skus WHERE skuId = $1\",\n\t\t\t[skuId],\n\t\t);\n\t\treturn rows[0] ?? null;\n\t}\n\n\tasync findByProductId(productId: number): Promise<Record<string, unknown>[]> {\n\t\tawait this._ensure();\n\t\treturn this._conn.execute(\n\t\t\t\"SELECT * FROM tcgplayer_skus WHERE productId = $1\",\n\t\t\t[productId],\n\t\t);\n\t}\n}\n","import type { CacheManager } from \"../cache.js\";\nimport type { CardTypes, Keywords } from \"../types/index.js\";\n\nexport class EnumQuery {\n\tprivate _cache: CacheManager;\n\n\tconstructor(cache: CacheManager) {\n\t\tthis._cache = cache;\n\t}\n\n\tasync keywords(): Promise<Keywords> {\n\t\tconst raw = await this._cache.loadJson(\"keywords\");\n\t\treturn (raw.data ?? {}) as Keywords;\n\t}\n\n\tasync cardTypes(): Promise<CardTypes> {\n\t\tconst raw = await this._cache.loadJson(\"card_types\");\n\t\treturn (raw.data ?? {}) as CardTypes;\n\t}\n\n\tasync enumValues(): Promise<Record<string, unknown>> {\n\t\tconst raw = await this._cache.loadJson(\"enum_values\");\n\t\treturn (raw.data ?? {}) as Record<string, unknown>;\n\t}\n}\n","import { BoosterSimulator } from \"./booster/simulator.js\";\nimport { CacheManager, type ProgressCallback } from \"./cache.js\";\nimport { Connection } from \"./connection.js\";\nimport {\n\tCardQuery,\n\tDeckQuery,\n\tEnumQuery,\n\tIdentifierQuery,\n\tLegalityQuery,\n\tPriceQuery,\n\tSealedQuery,\n\tSetQuery,\n\tSkuQuery,\n\tTokenQuery,\n} from \"./queries/index.js\";\n\nexport interface MtgjsonSDKOptions {\n\tcacheDir?: string;\n\toffline?: boolean;\n\ttimeout?: number;\n\tonProgress?: ProgressCallback;\n}\n\nexport class MtgjsonSDK {\n\tprivate _cache: CacheManager;\n\tprivate _conn!: Connection;\n\n\tprivate _cards: CardQuery | null = null;\n\tprivate _sets: SetQuery | null = null;\n\tprivate _prices: PriceQuery | null = null;\n\tprivate _decks: DeckQuery | null = null;\n\tprivate _sealed: SealedQuery | null = null;\n\tprivate _skus: SkuQuery | null = null;\n\tprivate _identifiers: IdentifierQuery | null = null;\n\tprivate _legalities: LegalityQuery | null = null;\n\tprivate _tokens: TokenQuery | null = null;\n\tprivate _enums: EnumQuery | null = null;\n\tprivate _booster: BoosterSimulator | null = null;\n\n\tprivate constructor(options?: MtgjsonSDKOptions) {\n\t\tthis._cache = new CacheManager({\n\t\t\tcacheDir: options?.cacheDir,\n\t\t\toffline: options?.offline,\n\t\t\ttimeout: options?.timeout,\n\t\t\tonProgress: options?.onProgress,\n\t\t});\n\t}\n\n\tstatic async create(options?: MtgjsonSDKOptions): Promise<MtgjsonSDK> {\n\t\tconst sdk = new MtgjsonSDK(options);\n\t\tawait sdk._cache.init();\n\t\tsdk._conn = await Connection.create(sdk._cache);\n\t\treturn sdk;\n\t}\n\n\tget cards(): CardQuery {\n\t\tif (!this._cards) this._cards = new CardQuery(this._conn);\n\t\treturn this._cards;\n\t}\n\n\tget sets(): SetQuery {\n\t\tif (!this._sets) this._sets = new SetQuery(this._conn);\n\t\treturn this._sets;\n\t}\n\n\tget prices(): PriceQuery {\n\t\tif (!this._prices) this._prices = new PriceQuery(this._conn);\n\t\treturn this._prices;\n\t}\n\n\tget decks(): DeckQuery {\n\t\tif (!this._decks) this._decks = new DeckQuery(this._cache);\n\t\treturn this._decks;\n\t}\n\n\tget sealed(): SealedQuery {\n\t\tif (!this._sealed) this._sealed = new SealedQuery(this._conn);\n\t\treturn this._sealed;\n\t}\n\n\tget skus(): SkuQuery {\n\t\tif (!this._skus) this._skus = new SkuQuery(this._conn);\n\t\treturn this._skus;\n\t}\n\n\tget identifiers(): IdentifierQuery {\n\t\tif (!this._identifiers) this._identifiers = new IdentifierQuery(this._conn);\n\t\treturn this._identifiers;\n\t}\n\n\tget legalities(): LegalityQuery {\n\t\tif (!this._legalities) this._legalities = new LegalityQuery(this._conn);\n\t\treturn this._legalities;\n\t}\n\n\tget tokens(): TokenQuery {\n\t\tif (!this._tokens) this._tokens = new TokenQuery(this._conn);\n\t\treturn this._tokens;\n\t}\n\n\tget enums(): EnumQuery {\n\t\tif (!this._enums) this._enums = new EnumQuery(this._cache);\n\t\treturn this._enums;\n\t}\n\n\tget booster(): BoosterSimulator {\n\t\tif (!this._booster) this._booster = new BoosterSimulator(this._conn);\n\t\treturn this._booster;\n\t}\n\n\tget meta(): Promise<Record<string, unknown>> {\n\t\treturn this._cache.loadJson(\"meta\").catch(() => ({}));\n\t}\n\n\tget views(): string[] {\n\t\treturn [...this._conn._registeredViews].sort();\n\t}\n\n\tasync sql(\n\t\tquery: string,\n\t\tparams?: unknown[],\n\t): Promise<Record<string, unknown>[]> {\n\t\treturn this._conn.execute(query, params);\n\t}\n\n\tasync refresh(): Promise<boolean> {\n\t\tif (!(await this._cache.isStale())) return false;\n\t\tthis._conn._registeredViews.clear();\n\t\tthis._cards = null;\n\t\tthis._sets = null;\n\t\tthis._prices = null;\n\t\tthis._decks = null;\n\t\tthis._sealed = null;\n\t\tthis._skus = null;\n\t\tthis._identifiers = null;\n\t\tthis._legalities = null;\n\t\tthis._tokens = null;\n\t\tthis._enums = null;\n\t\tthis._booster = null;\n\t\treturn true;\n\t}\n\n\tasync exportDb(path: string): Promise<string> {\n\t\tconst pathStr = path.replace(/\\\\/g, \"/\");\n\t\tconst raw = this._conn.raw;\n\t\tawait raw.run(`ATTACH '${pathStr}' AS export_db`);\n\t\ttry {\n\t\t\tfor (const viewName of [...this._conn._registeredViews].sort()) {\n\t\t\t\tawait raw.run(\n\t\t\t\t\t`CREATE TABLE export_db.${viewName} AS SELECT * FROM ${viewName}`,\n\t\t\t\t);\n\t\t\t}\n\t\t} finally {\n\t\t\tawait raw.run(\"DETACH export_db\");\n\t\t}\n\t\treturn path;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tawait this._conn.close();\n\t\tthis._cache.close();\n\t}\n\n\t/** For `await using sdk = await MtgjsonSDK.create()` */\n\tasync [Symbol.asyncDispose](): Promise<void> {\n\t\tawait this.close();\n\t}\n}\n"],"mappings":"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","names":["picked","import_node_fs","import_node_path","httpsGet","import_node_fs","import_node_os","import_node_path"]}