Files
vuelato/server/utils/wikidata.ts
Alejandro Martinez b8906efc80
Some checks failed
ci / ci (22, ubuntu-latest) (push) Has been cancelled
Initial commit: Vuelato - buscador de vuelos
Nuxt 4 + Supabase + Flightics API. Incluye búsqueda de vuelos,
inspiraciones, watchlist, tracking de precios y mapa interactivo.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 23:37:06 +02:00

63 lines
1.9 KiB
TypeScript

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<WikidataAirline[]> {
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<string, { value: string }>[] } }>(
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<string, WikidataAirline>()
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())
}