wiki-entity 0.7.0 → 1.0.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.
- package/CHANGELOG.md +172 -0
- package/LICENSE +15 -0
- package/README.md +287 -89
- package/dist/index.cjs +1312 -0
- package/dist/index.d.cts +370 -0
- package/dist/index.d.ts +370 -0
- package/dist/index.js +1296 -0
- package/package.json +59 -24
- package/data/countries.json +0 -1
- package/data/entity_types.json +0 -1
- package/lib/index.js +0 -129
- package/lib/request.js +0 -37
- package/lib/simpleEntity/convertToSimpleEntity.js +0 -53
- package/lib/simpleEntity/getEntityCountry.js +0 -25
- package/lib/simpleEntity/getEntityData.js +0 -27
- package/lib/simpleEntity/getEntityInstanceType.js +0 -32
- package/lib/simpleEntity/getEntityType.js +0 -62
- package/lib/simpleEntity/getEntityTypeByExtract.js +0 -28
- package/lib/simpleEntity/index.js +0 -7
- package/lib/simpleEntity/simpleEntity.js +0 -20
- package/lib/types.js +0 -13
- package/lib/utils.js +0 -15
- package/lib/wikidata/api.js +0 -106
- package/lib/wikidata/get_entity_types.js +0 -60
- package/lib/wikidata/index.js +0 -112
- package/lib/wikidata/simplify_claims.js +0 -100
- package/lib/wikidata/simplify_entity.js +0 -76
- package/lib/wikipedia/api.js +0 -146
- package/types/index.d.ts +0 -9
- package/types/request.d.ts +0 -5
- package/types/simpleEntity/convertToSimpleEntity.d.ts +0 -6
- package/types/simpleEntity/getEntityCountry.d.ts +0 -2
- package/types/simpleEntity/getEntityData.d.ts +0 -3
- package/types/simpleEntity/getEntityInstanceType.d.ts +0 -3
- package/types/simpleEntity/getEntityType.d.ts +0 -3
- package/types/simpleEntity/getEntityTypeByExtract.d.ts +0 -2
- package/types/simpleEntity/index.d.ts +0 -2
- package/types/simpleEntity/simpleEntity.d.ts +0 -29
- package/types/types.d.ts +0 -68
- package/types/utils.d.ts +0 -8
- package/types/wikidata/api.d.ts +0 -4
- package/types/wikidata/get_entity_types.d.ts +0 -1
- package/types/wikidata/index.d.ts +0 -3
- package/types/wikidata/simplify_claims.d.ts +0 -4
- package/types/wikidata/simplify_entity.d.ts +0 -21
- package/types/wikipedia/api.d.ts +0 -31
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here.
|
|
4
|
+
This project adheres to [Semantic Versioning](https://semver.org/).
|
|
5
|
+
|
|
6
|
+
## 1.0.0
|
|
7
|
+
|
|
8
|
+
A full modernization pass: the package is now dependency-free, dual ESM/CJS,
|
|
9
|
+
strictly typed, and covered by a real test suite. Several long-standing data
|
|
10
|
+
bugs are fixed, and the generated Wikidata tables have been rebuilt.
|
|
11
|
+
|
|
12
|
+
### Breaking changes
|
|
13
|
+
|
|
14
|
+
- **Node.js >= 20.19 is required.** `axios` is gone; the package uses the
|
|
15
|
+
platform `fetch`.
|
|
16
|
+
- **Dual ESM/CommonJS build.** The package now has an `exports` map and ships
|
|
17
|
+
from `dist/`. Deep imports such as
|
|
18
|
+
`require("wiki-entity/lib/simpleEntity/getEntityCountry")` no longer resolve.
|
|
19
|
+
- **The public API is down to 14 exports.** It had grown to 40, many of which
|
|
20
|
+
were internals with no standalone use. Removed: the array helpers (`chunk`,
|
|
21
|
+
`uniq`), the id predicates (`isItemId`, `isPropertyId`, `isEntityId`), the
|
|
22
|
+
claim renderers (`stringifyTime`, `stringifyCoordinates`), the pieces of
|
|
23
|
+
`convertToSimpleEntity` (`getEntityData`, `getEntityCountryCode`,
|
|
24
|
+
`getEntityTypeByExtract`, and the two `getEntityType` variants), the
|
|
25
|
+
low-level claim simplifiers (`simplifyClaim`, `simplifyClaims`,
|
|
26
|
+
`simplifyPropertyClaims`, `exploreEntityClaims`), the deprecated
|
|
27
|
+
`WikipediaApi` builder and its `getExtract`/`getExtracts`/`getRedirects`
|
|
28
|
+
wrappers (use `queryPages`), the singular `getEntityTypesByName` (use
|
|
29
|
+
`getEntityTypesByNames`), and the constants `KNOWN_TYPE_PREFIXES`,
|
|
30
|
+
`SIMPLE_ENTITY_TYPES` and `WIKIDATA_PROPS`.
|
|
31
|
+
- **`redirect` is now `followEntityRedirects: boolean`.** `redirect: "yes"|"no"`
|
|
32
|
+
sat one letter away from the unrelated `redirects: boolean`, which fetches
|
|
33
|
+
Wikipedia redirect titles. There is no alias; rename at the call site.
|
|
34
|
+
- **`InvalidParamsError` is gone**; bad arguments now throw a plain `TypeError`.
|
|
35
|
+
- **`WikidataPropsParam` (enum) and `WIKIDATA_PROPS` (const) are gone.** `props`
|
|
36
|
+
takes plain strings, typed by the `WikidataProp` union.
|
|
37
|
+
- **`PlainObject`, `AnyPlainObject` and `StringPlainObject` are gone** — they
|
|
38
|
+
were aliases for `Record<string, T>`. The `Raw*` claim types no longer leak
|
|
39
|
+
either; `simplifyEntity` takes the documented `WikibaseEntityJson` shape.
|
|
40
|
+
- `ApiResult` is renamed `WikipediaPage`.
|
|
41
|
+
- **`SimpleEntity.lang` and `SimpleEntity.wikiDataId` are now required.**
|
|
42
|
+
`convertToSimpleEntity` always sets both, so typing them optional forced
|
|
43
|
+
callers into null checks that could never fire.
|
|
44
|
+
- **`SimpleEntity.abbr` is removed.** Nothing in the package ever assigned it.
|
|
45
|
+
- `WikiEntityToEntityOptions` is renamed `ConvertToSimpleEntityOptions`, after
|
|
46
|
+
the function it belongs to rather than one that no longer exists.
|
|
47
|
+
- **`pageid` now always means the Wikipedia page id.** It used to fall back to
|
|
48
|
+
Wikidata's own page id whenever the Wikipedia lookup was skipped
|
|
49
|
+
(`wikiPageId: false`, no sitelink, missing article), which silently produced a
|
|
50
|
+
wrong `wikiPageId` in `SimpleEntity`. It is now left unset in those cases.
|
|
51
|
+
- **Deprecated statements are dropped** and **preferred statements sort first**,
|
|
52
|
+
so `claims[p].values[0]` is the value Wikidata recommends. Pass
|
|
53
|
+
`keepDeprecatedClaims` to `simplifyEntity` to keep them.
|
|
54
|
+
- **`wikibase-property` claim values** are now the property id (`"P31"`) rather
|
|
55
|
+
than the raw Wikibase object, which used to stringify to `"[object Object]"`.
|
|
56
|
+
- `simplifySitelinks` and friends return `{}` instead of `null` for empty input.
|
|
57
|
+
- `convertToSimpleEntity` omits empty optional fields (`categories`, `data`,
|
|
58
|
+
`types`) instead of setting them to `[]`/`{}`.
|
|
59
|
+
- `getEntityType`, `getEntityTypeByExtract` and related helpers return
|
|
60
|
+
`undefined` rather than `null` when nothing matches.
|
|
61
|
+
- `getManyEntities` returns `{}` instead of `null` when nothing was found —
|
|
62
|
+
the `null` used to crash the caller.
|
|
63
|
+
|
|
64
|
+
### Migrating
|
|
65
|
+
|
|
66
|
+
`getExtract`, `getExtracts` and `getRedirects` are replaced by `queryPages`,
|
|
67
|
+
which batches titles and follows paginated responses instead of sending one
|
|
68
|
+
request and truncating:
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
// before // now
|
|
72
|
+
getExtracts({ lang, titles, sentences: 2 }); // queryPages({ lang, titles, extract: 2 })
|
|
73
|
+
getExtract(lang, title, 2); // queryPages({ lang, titles: [title], extract: 2 })
|
|
74
|
+
getRedirects(lang, title); // queryPages({ lang, titles: [title], redirects: true })
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`queryPages` returns `{ pages, resolved, requestedTitleOf }`. `pages` is not in
|
|
78
|
+
the order the titles were given, so use `requestedTitleOf` to map a result back
|
|
79
|
+
to the title you asked for. See the README for details.
|
|
80
|
+
|
|
81
|
+
The `WikipediaApi` builder maps onto the same call:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
// before
|
|
85
|
+
new WikipediaApi().extract(2).redirects().query("en", { titles: "A|B" });
|
|
86
|
+
// now
|
|
87
|
+
queryPages({ lang: "en", titles: ["A", "B"], extract: 2, redirects: true });
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Fixed
|
|
91
|
+
|
|
92
|
+
- **Labels went missing for a large share of items.** Wikidata has been moving
|
|
93
|
+
names that are identical across languages to the `mul` ("multiple languages")
|
|
94
|
+
code and deleting the per-language duplicates, which left `label` undefined
|
|
95
|
+
for entities such as Albert Einstein, Douglas Adams and iPhone 5. Labels and
|
|
96
|
+
aliases now fall back to `mul`, and `mul` is requested automatically alongside
|
|
97
|
+
any `languages` filter.
|
|
98
|
+
- **Only the first entity got an extract.** Without `exintro`, MediaWiki
|
|
99
|
+
silently lowers `exlimit` to 1, so `getEntities({ titles: [a, b, c], extract })`
|
|
100
|
+
returned an extract for `a` only.
|
|
101
|
+
- **`languages` was ignored.** It was serialized as PHP array syntax
|
|
102
|
+
(`languages[]=en&languages[]=ru`), which MediaWiki rejects with a warning and
|
|
103
|
+
then returns _every_ language for.
|
|
104
|
+
- **BCE dates lost their sign.** `-0044-03-15` (Julius Caesar's death) rendered
|
|
105
|
+
as `0044-03-15`.
|
|
106
|
+
- **Coordinates lost integer digits.** Trailing-zero trimming turned latitude
|
|
107
|
+
`10` into `1`.
|
|
108
|
+
- **`claims: "property"` never worked.** Property entities (`P31`, …) were
|
|
109
|
+
filtered out as invalid ids, so property labels and descriptions were never
|
|
110
|
+
populated.
|
|
111
|
+
- **The `types` prefix filter was ignored.** `types: ["dbo", "schema"]` computed
|
|
112
|
+
the allowed prefixes and then never applied them.
|
|
113
|
+
- **Wikipedia results were mismatched to entities.** MediaWiki normalizes titles
|
|
114
|
+
and follows redirects, so the returned title often differs from the requested
|
|
115
|
+
one; results are now mapped back through the normalization and redirect
|
|
116
|
+
chains. Previously this attached data to the wrong entity, or threw.
|
|
117
|
+
- **Titles that are redirects found no entity.** Single-title lookups now use
|
|
118
|
+
`normalize=1`, and multi-title lookups resolve anything Wikidata missed
|
|
119
|
+
through Wikipedia's canonical title.
|
|
120
|
+
- **Romanian extract patterns never matched.** They relied on `\b`, which is
|
|
121
|
+
ASCII-only, so words ending in a diacritic (`oraș`, `cântăreț`, `comună`)
|
|
122
|
+
could never match. Patterns are now Unicode-aware; English patterns added.
|
|
123
|
+
- More than 50 Wikipedia titles are now batched instead of being sent in one
|
|
124
|
+
over-long request, and paginated (`continue`) responses are followed, so
|
|
125
|
+
`redirects` and `categories` are no longer truncated at the first page.
|
|
126
|
+
- `getEntityData` no longer throws on a structured claim value with no readable
|
|
127
|
+
rendering; it skips it.
|
|
128
|
+
- DBpedia is queried over HTTPS, with the resource IRI properly escaped.
|
|
129
|
+
|
|
130
|
+
### Added
|
|
131
|
+
|
|
132
|
+
- `getSimpleEntities(params, options?)` — `getEntities` plus
|
|
133
|
+
`convertToSimpleEntity` in one call, taking the language from `params` so it
|
|
134
|
+
cannot diverge from the language the entities were fetched in.
|
|
135
|
+
- `AbortSignal` support on every public call (`signal` param).
|
|
136
|
+
- Automatic retries with exponential backoff and jitter on 429/5xx/network
|
|
137
|
+
errors, honouring `Retry-After`.
|
|
138
|
+
- Typed error classes: `WikiEntityError`, `HttpError`, `ApiError`,
|
|
139
|
+
`InvalidParamsError`.
|
|
140
|
+
- `getEntityTypesByNames()` resolves DBpedia types for many entities in a single
|
|
141
|
+
`VALUES` query instead of one request per entity.
|
|
142
|
+
- `queryPages()` — the batching, continuation-following Wikipedia query used
|
|
143
|
+
internally, exported for direct use.
|
|
144
|
+
- `setDbpediaEndpoint()` / `getDbpediaEndpoint()` to use a DBpedia mirror.
|
|
145
|
+
- `rank` on claim values; `descriptions` map on entities; `datatype` on property
|
|
146
|
+
entities.
|
|
147
|
+
- `chunk`, `isItemId`, `isPropertyId`, `isEntityId` utilities.
|
|
148
|
+
- Unit tests (fully mocked) and an integration suite that runs against the live
|
|
149
|
+
APIs, plus ESLint, Prettier and strict TypeScript.
|
|
150
|
+
|
|
151
|
+
### Changed
|
|
152
|
+
|
|
153
|
+
- **Claim resolution is batched.** `claims: "item"` used to issue one request
|
|
154
|
+
per entity, serially; all referenced items across all entities are now fetched
|
|
155
|
+
together, 50 per request.
|
|
156
|
+
- **Regenerated `data/entity-types.json` and `data/countries.json`** from the
|
|
157
|
+
live Wikidata Query Service. The type tables dated from 2018 and missed how
|
|
158
|
+
Wikidata now models products, recurring events and administrative entities.
|
|
159
|
+
The generator expands the class graph breadth-first with batched queries, and
|
|
160
|
+
verifies known classifications before writing.
|
|
161
|
+
- The type table is delta-encoded, cutting it from 456 KB to ~130 KB and
|
|
162
|
+
expanding lazily on first use.
|
|
163
|
+
- `isValidWikiId` is deprecated in favour of `isItemId` / `isEntityId`.
|
|
164
|
+
|
|
165
|
+
## 0.7.0
|
|
166
|
+
|
|
167
|
+
- Added a default `User-Agent` built from `package.json`, plus `setUserAgent()`
|
|
168
|
+
and the `WIKI_ENTITY_USER_AGENT` environment variable.
|
|
169
|
+
|
|
170
|
+
## 0.6.0
|
|
171
|
+
|
|
172
|
+
- Added `mapRedirects()`.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2016-present, Dumitru Cantea
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
10
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
11
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
12
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
13
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
14
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
15
|
+
PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,24 +1,52 @@
|
|
|
1
1
|
# wiki-entity
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Fetch and normalize entities from **Wikidata**, **Wikipedia** and **DBpedia**.
|
|
4
|
+
|
|
5
|
+
- Zero runtime dependencies — built on `fetch`, ESM + CommonJS, fully typed.
|
|
6
|
+
- Batches, retries and rate-limit aware by default.
|
|
7
|
+
- Flattens Wikidata's deeply nested claim format into something you can read.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install wiki-entity
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Requires Node.js >= 20.19.
|
|
4
14
|
|
|
5
15
|
## Usage
|
|
6
16
|
|
|
17
|
+
```ts
|
|
18
|
+
import { getEntities, setUserAgent } from "wiki-entity";
|
|
19
|
+
|
|
20
|
+
setUserAgent("MyApp/1.0 (https://myapp.example; contact@myapp.example)");
|
|
21
|
+
|
|
22
|
+
// by Wikipedia article title
|
|
23
|
+
const [europe] = await getEntities({ language: "en", titles: ["Europe"] });
|
|
24
|
+
|
|
25
|
+
// by Wikidata id, with a Wikipedia summary and resolved claim labels
|
|
26
|
+
const [einstein] = await getEntities({
|
|
27
|
+
language: "en",
|
|
28
|
+
ids: ["Q937"],
|
|
29
|
+
extract: 2,
|
|
30
|
+
claims: "all"
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
einstein.label; // "Albert Einstein"
|
|
34
|
+
einstein.extract; // "Albert Einstein was a German-born theoretical physicist…"
|
|
35
|
+
einstein.claims.P569.label; // "date of birth"
|
|
36
|
+
einstein.claims.P569.values[0].value_string; // "1879-03-14"
|
|
7
37
|
```
|
|
8
|
-
import { getEntities } from 'wiki-entity';
|
|
9
38
|
|
|
10
|
-
|
|
11
|
-
getEntities({ language: 'en', titles: ['Europe'] }).then(entities => {});
|
|
39
|
+
CommonJS works too:
|
|
12
40
|
|
|
13
|
-
|
|
14
|
-
|
|
41
|
+
```js
|
|
42
|
+
const { getEntities } = require("wiki-entity");
|
|
15
43
|
```
|
|
16
44
|
|
|
17
45
|
## User-Agent
|
|
18
46
|
|
|
19
|
-
[Wikimedia's User-Agent policy](https://
|
|
20
|
-
|
|
21
|
-
|
|
47
|
+
[Wikimedia's User-Agent policy](https://foundation.wikimedia.org/wiki/Policy:Wikimedia_Foundation_User-Agent_Policy)
|
|
48
|
+
requires every client to identify itself. Generic agents get throttled or
|
|
49
|
+
blocked with HTTP `429`. Set yours once at startup:
|
|
22
50
|
|
|
23
51
|
```ts
|
|
24
52
|
import { setUserAgent } from "wiki-entity";
|
|
@@ -26,115 +54,285 @@ import { setUserAgent } from "wiki-entity";
|
|
|
26
54
|
setUserAgent("MyApp/1.0 (https://myapp.example; contact@myapp.example)");
|
|
27
55
|
```
|
|
28
56
|
|
|
29
|
-
|
|
57
|
+
or via the environment:
|
|
30
58
|
|
|
31
|
-
```
|
|
59
|
+
```bash
|
|
32
60
|
WIKI_ENTITY_USER_AGENT="MyApp/1.0 (https://myapp.example; contact@myapp.example)"
|
|
33
61
|
```
|
|
34
62
|
|
|
35
63
|
## API
|
|
36
64
|
|
|
37
|
-
### getEntities(params): Promise<WikiEntity[]
|
|
65
|
+
### `getEntities(params): Promise<WikiEntity[]>`
|
|
66
|
+
|
|
67
|
+
Fetches entities from Wikidata and enriches them from Wikipedia and DBpedia.
|
|
68
|
+
Results follow the order of the requested `ids`/`titles`; entities that do not
|
|
69
|
+
exist are omitted.
|
|
70
|
+
|
|
71
|
+
| Param | Type | Default | Description |
|
|
72
|
+
| ----------------------- | --------------------- | ------- | ---------------------------------------------------------------------------------------------- |
|
|
73
|
+
| `ids` | `string[]` | — | Wikidata ids, max 500. Either this or `titles` is required. |
|
|
74
|
+
| `titles` | `string[]` | — | Wikipedia article titles in `language`, max 500. |
|
|
75
|
+
| `language` | `string` | `"en"` | Language of `titles` and of the resulting `label`/`description`. |
|
|
76
|
+
| `languages` | `string[]` | — | Extra languages to populate `labels` with. |
|
|
77
|
+
| `props` | `string[]` | all | `info`, `sitelinks`, `aliases`, `labels`, `descriptions`, `claims`, `datatype`. |
|
|
78
|
+
| `claims` | `string` | `none` | `none`, `item`, `property` or `all` — how deeply to resolve claim labels. |
|
|
79
|
+
| `extract` | `number` | — | Sentences of the Wikipedia lead section to fetch. |
|
|
80
|
+
| `types` | `boolean \| string[]` | `false` | `true` for DBpedia ontology types, or an array of prefixes to keep (e.g. `["dbo", "schema"]`). |
|
|
81
|
+
| `redirects` | `boolean` | `false` | Titles of _Wikipedia articles_ that redirect to this entity. |
|
|
82
|
+
| `categories` | `boolean` | `false` | The article's non-hidden categories. |
|
|
83
|
+
| `wikiPageId` | `boolean` | `true` | Fetch the Wikipedia `pageid`. |
|
|
84
|
+
| `httpTimeout` | `number` | `15000` | Per-request timeout in milliseconds. |
|
|
85
|
+
| `signal` | `AbortSignal` | — | Cancels every underlying request. |
|
|
86
|
+
| `followEntityRedirects` | `boolean` | `true` | Resolve _Wikidata items_ that were merged into another item. |
|
|
87
|
+
|
|
88
|
+
`extract`, `redirects` and `categories` need the entity to have a sitelink for
|
|
89
|
+
`language`, so keep `sitelinks` in `props` when you narrow it.
|
|
90
|
+
|
|
91
|
+
Note `redirects` and `followEntityRedirects` are unrelated: the first fetches
|
|
92
|
+
the titles of Wikipedia articles pointing at this entity, the second controls
|
|
93
|
+
whether a merged-away Wikidata item resolves to the item that replaced it.
|
|
94
|
+
|
|
95
|
+
### `mapRedirects(titles, lang): Promise<Record<string, string>>`
|
|
96
|
+
|
|
97
|
+
Resolves Wikipedia redirect titles to the articles they point at. Only titles
|
|
98
|
+
that really are redirects appear in the result.
|
|
38
99
|
|
|
39
|
-
|
|
100
|
+
```ts
|
|
101
|
+
await mapRedirects(["Brashov"], "ro"); // { Brashov: "Brașov" }
|
|
102
|
+
```
|
|
40
103
|
|
|
41
|
-
|
|
104
|
+
### `getSimpleEntities(params, options?): Promise<SimpleEntity[]>`
|
|
42
105
|
|
|
43
|
-
|
|
106
|
+
`getEntities` followed by `convertToSimpleEntity`, in one call. Takes the same
|
|
107
|
+
params, plus an optional `{ defaultType }`.
|
|
44
108
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
- **wikiPageId**: *boolean* - get wikiPageId, Default `true`
|
|
109
|
+
```ts
|
|
110
|
+
const entities = await getSimpleEntities({
|
|
111
|
+
language: "en",
|
|
112
|
+
ids: ["Q937"],
|
|
113
|
+
types: true,
|
|
114
|
+
extract: 2
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
entities[0].name; // "Albert Einstein"
|
|
118
|
+
entities[0].type; // SimpleEntityType.PERSON
|
|
119
|
+
```
|
|
57
120
|
|
|
58
|
-
|
|
121
|
+
Prefer this over calling the two by hand: it takes the language from `params`,
|
|
122
|
+
so it cannot drift. Converting with a different language than you fetched with
|
|
123
|
+
silently mixes them — `name` and `about` come from the fetch, while
|
|
124
|
+
`wikiPageTitle` is read from the sitelinks of whichever language you passed.
|
|
59
125
|
|
|
60
|
-
|
|
126
|
+
### `convertToSimpleEntity(wikiEntity, lang, options?): SimpleEntity`
|
|
61
127
|
|
|
62
|
-
|
|
128
|
+
Flattens a single `WikiEntity` into the compact shape. Use it when you already
|
|
129
|
+
have entities from `getEntities`.
|
|
63
130
|
|
|
64
|
-
|
|
131
|
+
### Escape hatches
|
|
132
|
+
|
|
133
|
+
For what `getEntities` does not cover. Everything else in the package is an
|
|
134
|
+
implementation detail and may change without a major release.
|
|
135
|
+
|
|
136
|
+
| Export | Purpose |
|
|
137
|
+
| ------------------------------------------- | --------------------------------------------------------------- |
|
|
138
|
+
| `queryPages(options)` | Query Wikipedia articles directly — batched, continuation-safe. |
|
|
139
|
+
| `simplifyEntity(lang, raw, options?)` | Flatten a raw `wbgetentities` entity you fetched yourself. |
|
|
140
|
+
| `getEntityTypesByNames(names, options?)` | DBpedia ontology types for English Wikipedia titles. |
|
|
141
|
+
| `setDbpediaEndpoint` / `getDbpediaEndpoint` | Point type lookups at a DBpedia mirror. |
|
|
142
|
+
| `setUserAgent` / `getUserAgent` | The `User-Agent` sent with every request. |
|
|
143
|
+
|
|
144
|
+
#### `queryPages(options)`
|
|
145
|
+
|
|
146
|
+
Talks to Wikipedia only — no Wikidata lookup, no entity ids. Use it when you
|
|
147
|
+
have article titles and want their summaries, redirects or categories.
|
|
65
148
|
|
|
66
149
|
```ts
|
|
150
|
+
import { queryPages } from "wiki-entity";
|
|
67
151
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
claims?: PlainObject<WikidataProperty>;
|
|
78
|
-
types?: string[];
|
|
79
|
-
redirects?: string[];
|
|
80
|
-
categories?: string[];
|
|
81
|
-
redirectsToId?: string;
|
|
82
|
-
redirectsFromId?: string;
|
|
152
|
+
const { pages } = await queryPages({
|
|
153
|
+
lang: "en",
|
|
154
|
+
titles: ["Chișinău", "Italy"],
|
|
155
|
+
extract: 2,
|
|
156
|
+
followRedirects: true
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
for (const page of pages) {
|
|
160
|
+
console.log(page.pageid, page.title, page.extract);
|
|
83
161
|
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
| Option | Type | Description |
|
|
165
|
+
| ----------------- | ------------- | ------------------------------------------------ |
|
|
166
|
+
| `lang` | `string` | Wikipedia language code, e.g. `"en"`. Required. |
|
|
167
|
+
| `titles` | `string[]` | Article titles. Required; batched automatically. |
|
|
168
|
+
| `extract` | `number` | Sentences of the lead section to fetch. |
|
|
169
|
+
| `redirects` | `boolean` | Titles of articles redirecting to each page. |
|
|
170
|
+
| `categories` | `boolean` | Each article's non-hidden categories. |
|
|
171
|
+
| `followRedirects` | `boolean` | Resolve titles that are themselves redirects. |
|
|
172
|
+
| `httpTimeout` | `number` | Per-request timeout in milliseconds. |
|
|
173
|
+
| `signal` | `AbortSignal` | Cancels every underlying request. |
|
|
174
|
+
|
|
175
|
+
It handles the parts of the MediaWiki API that are easy to get wrong: titles are
|
|
176
|
+
batched (50 per request, or 20 when `extract` is set, since the API refuses more
|
|
177
|
+
intro extracts than that), and paginated `continue` responses are followed, so
|
|
178
|
+
long `redirects` and `categories` lists are not truncated at the first page.
|
|
179
|
+
|
|
180
|
+
**`pages` is not in the order you asked for**, and MediaWiki normalizes titles
|
|
181
|
+
and follows redirects, so the title that comes back may not be the one you sent.
|
|
182
|
+
Two maps tie the results back to your input:
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
const { pages, resolved, requestedTitleOf } = await queryPages({
|
|
186
|
+
lang: "en",
|
|
187
|
+
titles: ["Kishinev"],
|
|
188
|
+
categories: true,
|
|
189
|
+
followRedirects: true
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
pages[0].title; // "Chișinău" — the redirect target
|
|
193
|
+
resolved.get("Kishinev"); // { title: "Chișinău", redirected: true }
|
|
194
|
+
requestedTitleOf.get("Chișinău"); // "Kishinev"
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Earlier releases had `getExtract`, `getExtracts` and `getRedirects` for this.
|
|
198
|
+
They were thin wrappers that only ever handled one request's worth of titles:
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
// before // now
|
|
202
|
+
getExtracts({ lang, titles, sentences: 2 }); // queryPages({ lang, titles, extract: 2 })
|
|
203
|
+
getExtract(lang, title, 2); // queryPages({ lang, titles: [title], extract: 2 })
|
|
204
|
+
getRedirects(lang, title); // queryPages({ lang, titles: [title], redirects: true })
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
`getExtract` returned a single object or `null`; the equivalent is
|
|
208
|
+
`(await queryPages({ lang, titles: [title], extract: 2 })).pages[0] ?? null`.
|
|
209
|
+
|
|
210
|
+
### Errors
|
|
211
|
+
|
|
212
|
+
All errors extend `WikiEntityError`:
|
|
213
|
+
|
|
214
|
+
- `HttpError` — non-2xx status, network failure or timeout. `status`, `url` and
|
|
215
|
+
`retryable` describe it; 429 and 5xx are retried automatically.
|
|
216
|
+
- `ApiError` — the request succeeded but MediaWiki reported an error (`code`).
|
|
217
|
+
|
|
218
|
+
Bad arguments throw a plain `TypeError`.
|
|
219
|
+
|
|
220
|
+
DBpedia types are best-effort enrichment: if the endpoint is unreachable,
|
|
221
|
+
`types` is simply left unset instead of failing the call.
|
|
222
|
+
|
|
223
|
+
## WikiEntity
|
|
224
|
+
|
|
225
|
+
`WikiEntity` is a flattened Wikidata item, plus the extras pulled from
|
|
226
|
+
Wikipedia and DBpedia.
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
type WikiEntity = {
|
|
230
|
+
id: string;
|
|
231
|
+
label?: string;
|
|
232
|
+
labels?: Record<string, string>;
|
|
233
|
+
description?: string;
|
|
234
|
+
descriptions?: Record<string, string>;
|
|
235
|
+
aliases?: string[];
|
|
236
|
+
sitelinks?: Record<string, string>;
|
|
237
|
+
claims?: Record<string, WikidataProperty>;
|
|
238
|
+
/** Wikipedia page id (not Wikidata's). */
|
|
239
|
+
pageid?: number;
|
|
240
|
+
extract?: string;
|
|
241
|
+
types?: string[];
|
|
242
|
+
redirects?: string[];
|
|
243
|
+
categories?: string[];
|
|
244
|
+
redirectsToId?: string;
|
|
245
|
+
redirectsFromId?: string;
|
|
246
|
+
};
|
|
84
247
|
|
|
85
248
|
type WikidataProperty = {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
249
|
+
id: string;
|
|
250
|
+
label?: string;
|
|
251
|
+
description?: string;
|
|
252
|
+
values: WikidataPropertyValue[];
|
|
253
|
+
};
|
|
91
254
|
|
|
92
255
|
type WikidataPropertyValue = {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
256
|
+
datatype: string;
|
|
257
|
+
/** Scalar for simple datatypes, the raw object for time/quantity/coordinates. */
|
|
258
|
+
value: string | number | object;
|
|
259
|
+
/** Readable rendering of a structured `value`. */
|
|
260
|
+
value_string?: string;
|
|
261
|
+
rank?: "preferred" | "normal" | "deprecated";
|
|
262
|
+
label?: string;
|
|
263
|
+
description?: string;
|
|
264
|
+
qualifiers?: Record<string, WikidataProperty> | null;
|
|
265
|
+
};
|
|
266
|
+
```
|
|
101
267
|
|
|
102
|
-
|
|
103
|
-
[index: string]: T
|
|
104
|
-
}
|
|
268
|
+
Notes on the claim values:
|
|
105
269
|
|
|
106
|
-
|
|
270
|
+
- Statements Wikidata marks **deprecated** are dropped, and **preferred** ones
|
|
271
|
+
are sorted first, so `values[0]` is the value Wikidata recommends.
|
|
272
|
+
- Dates render at their stated precision and keep the sign of BCE years:
|
|
273
|
+
`-0044-03-15`.
|
|
274
|
+
- Coordinates render as `"47.0105,28.8638"`.
|
|
275
|
+
- Labels fall back to Wikidata's `mul` ("multiple languages") code, which is
|
|
276
|
+
where many items now keep a name that is spelled the same everywhere.
|
|
107
277
|
|
|
108
278
|
## SimpleEntity
|
|
109
279
|
|
|
110
280
|
```ts
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
WORK = 'W',
|
|
281
|
+
enum SimpleEntityType {
|
|
282
|
+
EVENT = "E",
|
|
283
|
+
ORG = "O",
|
|
284
|
+
PERSON = "H",
|
|
285
|
+
PLACE = "P",
|
|
286
|
+
PRODUCT = "R",
|
|
287
|
+
WORK = "W"
|
|
119
288
|
}
|
|
120
289
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
290
|
+
type SimpleEntity = {
|
|
291
|
+
/** Always set. */
|
|
292
|
+
lang: string;
|
|
293
|
+
/** Always set. */
|
|
294
|
+
wikiDataId: string;
|
|
295
|
+
name?: string;
|
|
296
|
+
description?: string;
|
|
297
|
+
about?: string;
|
|
298
|
+
wikiPageId?: number;
|
|
299
|
+
wikiPageTitle?: string;
|
|
300
|
+
type?: SimpleEntityType;
|
|
301
|
+
types?: string[];
|
|
302
|
+
countryCodes?: string[];
|
|
303
|
+
data?: Record<string, string[]>;
|
|
304
|
+
categories?: string[];
|
|
305
|
+
redirectsToId?: string;
|
|
306
|
+
redirectsFromId?: string;
|
|
307
|
+
};
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
The entity `type` is resolved from the DBpedia ontology types first, then from
|
|
311
|
+
the `P31` claims against the generated Wikidata class tables, and finally from
|
|
312
|
+
the opening words of the extract.
|
|
313
|
+
|
|
314
|
+
## Generated data
|
|
139
315
|
|
|
316
|
+
`data/countries.json` and `data/entity-types.json` are derived from Wikidata
|
|
317
|
+
and checked in. Regenerate them against the live query service with:
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
npm run data:countries
|
|
321
|
+
npm run data:entity-types
|
|
140
322
|
```
|
|
323
|
+
|
|
324
|
+
`data:entity-types` verifies a set of known classifications before writing, so
|
|
325
|
+
a bad expansion fails loudly instead of silently degrading type detection.
|
|
326
|
+
|
|
327
|
+
## Development
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
npm install
|
|
331
|
+
npm test # unit tests, fully mocked
|
|
332
|
+
npm run test:integration # hits the live Wikimedia and DBpedia APIs
|
|
333
|
+
npm run check # format, lint, typecheck, test, build
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## License
|
|
337
|
+
|
|
338
|
+
ISC
|