diff --git a/src/index.ts b/src/index.ts index 8a8cd53..89ec31d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,12 +9,42 @@ export { WikipediaApi }; export * from "./simpleEntity"; export * from "./types"; +const getAllEntities = async (params: WikiEntitiesParams) => { + const entities = await getWikidataEntities(params); + const titles = params.titles || []; + if (params.redirect === "no" || !titles.length || params.ids) return entities; + const lang = params.language || "en"; + const notFoundTitle = titles.find( + (title) => + !Object.entries(entities).find(([, entity]) => { + return ( + !entity.sitelinks || + !entity.sitelinks[lang] || + entity.sitelinks[lang] !== title + ); + }) + ); + if (notFoundTitle.length === 0) return entities; + + const redirects = await mapRedirects(titles, lang); + const redirectTitles = [...new Set(Object.values(redirects))]; + if (redirectTitles.length === 0) return entities; + + const redirectEntities = await getWikidataEntities({ + ...params, + ids: undefined, + titles: redirectTitles + }); + + return { ...entities, ...redirectEntities }; +}; + export async function getEntities( params: WikiEntitiesParams ): Promise { const lang = params.language || "en"; - const entities = await getWikidataEntities(params); + const entities = await getAllEntities(params); const ids = Object.keys(entities).filter((id) => isValidWikiId(id)); @@ -96,3 +126,27 @@ export async function getEntities( .map((id) => entities[id]) .filter((it) => !!it); } + +export async function mapRedirects( + titles: string[], + lang: string +): Promise> { + const wikiApi = new WikipediaApi(); + return wikiApi + .redirects() + .query(lang, { + titles: titles.map((it) => it.replace(/\s+/g, "_")).join("|"), + redirects: "yes" + }) + .then((apiResults) => { + const result: Record = {}; + apiResults.forEach((r) => { + if (r.redirects?.length) { + const it = r.redirects.find((it) => titles.includes(it)); + if (it && it !== r.title) result[it] = r.title; + } + }); + + return result; + }); +} diff --git a/src/wikidata/get_entity_types.ts b/src/wikidata/get_entity_types.ts index 1bc379e..9f406e1 100644 --- a/src/wikidata/get_entity_types.ts +++ b/src/wikidata/get_entity_types.ts @@ -51,9 +51,9 @@ function dbpediaTypes(name: string): Promise { timeout: 30 * 1000 }) .then((data) => data.results && data.results.bindings) - .catch((error) => { + .catch((error: Error) => { console.error(`${error.message}: ${url}`); - return []; + return [] as any[]; }); } diff --git a/src/wikidata/index.ts b/src/wikidata/index.ts index 5a5e87d..b502633 100644 --- a/src/wikidata/index.ts +++ b/src/wikidata/index.ts @@ -83,7 +83,7 @@ function exploreEntitiesProperties( } }); }); - return null; + return entities; }); } diff --git a/src/wikipedia/api.ts b/src/wikipedia/api.ts index 7add875..2997d32 100644 --- a/src/wikipedia/api.ts +++ b/src/wikipedia/api.ts @@ -46,22 +46,22 @@ export class Api { if (data && data.query && data.query.pages) { return Object.keys(data.query.pages) .map((id) => data.query.pages[id]) - .map((data) => { + .map((page) => { const item: ApiResult = { - pageid: data.pageid, - title: data.title + pageid: page.pageid, + title: page.title }; - if (data["categories"]) { - item.categories = data["categories"].map((it: any) => it.title); + if (page["categories"]) { + item.categories = page["categories"].map((it: any) => it.title); } - if (data["redirects"]) { - item.redirects = data["redirects"].map((it: any) => it.title); + if (page["redirects"]) { + item.redirects = page["redirects"].map((it: any) => it.title); } - if (data["extract"]) { - item.extract = data["extract"]; + if (page["extract"]) { + item.extract = page["extract"]; } return item; diff --git a/test/redirects.js b/test/redirects.js index 4c573a2..f599472 100644 --- a/test/redirects.js +++ b/test/redirects.js @@ -57,4 +57,23 @@ describe("redirects", function () { assert.equal(results[0].pageid, 3198752); }); }); + + it("redirect Brashov to Brașov", function () { + return index + .getEntities({ + language: "ro", + titles: ["Brashov"], + redirects: true + }) + .then(function (results) { + assert.equal(results[0].id, "Q82174"); + }); + }); + + it("mapRedirects Brashov to Brașov", function () { + return index.mapRedirects(["Brashov"], "ro").then(function (results) { + assert.equal(Object.keys(results).length, 1); + assert.equal(results["Brashov"], "Brașov"); + }); + }); });