const SPARQL_ENDPOINT = 'https://query.wikidata.org/sparql' export interface WikidataAirline { iata: string icao: string | null name: string logoUrl: string | null website: string | null } /** * Fetch all airlines from Wikidata via SPARQL. * Returns deduplicated list by IATA code (first logo wins). */ export async function getAirlinesFromWikidata(): Promise { const query = ` SELECT ?airlineLabel ?iata ?icao ?logo ?website WHERE { ?airline wdt:P31 wd:Q46970. ?airline wdt:P229 ?iata. OPTIONAL { ?airline wdt:P230 ?icao. } OPTIONAL { ?airline wdt:P154 ?logo. } OPTIONAL { ?airline wdt:P856 ?website. } SERVICE wikibase:label { bd:serviceParam wikibase:language "es,en". } } ` const data = await $fetch<{ results: { bindings: Record[] } }>( SPARQL_ENDPOINT, { query: { query, format: 'json' }, headers: { 'Accept': 'application/sparql-results+json', 'User-Agent': 'Vuelato/1.0 (https://github.com/vuelato; contact@vuelato.com)' } } ) // Deduplicate by IATA code (keep first entry with logo if available) const map = new Map() for (const row of data.results.bindings) { const iata = row.iata?.value if (!iata) continue const existing = map.get(iata) const logoUrl = row.logo?.value || null const website = row.website?.value || null // Keep entry with logo/website over entry without if (!existing || (!existing.logoUrl && logoUrl) || (!existing.website && website)) { map.set(iata, { iata, icao: row.icao?.value || existing?.icao || null, name: row.airlineLabel?.value || existing?.name || '', logoUrl: logoUrl || existing?.logoUrl || null, website: website || existing?.website || null }) } } return Array.from(map.values()) }