Initial commit: Vuelato - buscador de vuelos
Some checks failed
ci / ci (22, ubuntu-latest) (push) Has been cancelled
Some checks failed
ci / ci (22, ubuntu-latest) (push) Has been cancelled
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>
This commit is contained in:
62
server/utils/wikidata.ts
Normal file
62
server/utils/wikidata.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
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())
|
||||
}
|
||||
Reference in New Issue
Block a user