@zivue/zuuid 0.2.3 → 0.2.5
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 +10 -0
- package/README.md +83 -4
- package/dist/client.d.ts +22 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +88 -0
- package/dist/providers/comicvine/client.d.ts +40 -0
- package/dist/providers/comicvine/client.d.ts.map +1 -0
- package/dist/providers/comicvine/client.js +190 -0
- package/dist/providers/comicvine/constants.d.ts +2 -0
- package/dist/providers/comicvine/constants.d.ts.map +1 -1
- package/dist/providers/comicvine/constants.js +2 -0
- package/dist/providers/comicvine/index.d.ts +2 -0
- package/dist/providers/comicvine/index.d.ts.map +1 -1
- package/dist/providers/comicvine/index.js +2 -0
- package/dist/providers/comicvine/types.d.ts +26 -0
- package/dist/providers/comicvine/types.d.ts.map +1 -0
- package/dist/providers/comicvine/types.js +1 -0
- package/dist/providers/musicbrainz/constants.d.ts +1 -1
- package/dist/providers/musicbrainz/constants.js +1 -1
- package/dist/providers/openstreetmap/city.d.ts +2 -0
- package/dist/providers/openstreetmap/city.d.ts.map +1 -0
- package/dist/providers/openstreetmap/city.js +1 -0
- package/dist/providers/openstreetmap/client.d.ts +31 -0
- package/dist/providers/openstreetmap/client.d.ts.map +1 -0
- package/dist/providers/openstreetmap/client.js +146 -0
- package/dist/providers/openstreetmap/constants.d.ts +2 -0
- package/dist/providers/openstreetmap/constants.d.ts.map +1 -1
- package/dist/providers/openstreetmap/constants.js +2 -0
- package/dist/providers/openstreetmap/country.d.ts +2 -0
- package/dist/providers/openstreetmap/country.d.ts.map +1 -0
- package/dist/providers/openstreetmap/country.js +1 -0
- package/dist/providers/openstreetmap/index.d.ts +4 -0
- package/dist/providers/openstreetmap/index.d.ts.map +1 -1
- package/dist/providers/openstreetmap/index.js +4 -0
- package/dist/providers/openstreetmap/types.d.ts +16 -0
- package/dist/providers/openstreetmap/types.d.ts.map +1 -0
- package/dist/providers/openstreetmap/types.js +1 -0
- package/package.json +17 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.5 - 2026-05-25
|
|
4
|
+
|
|
5
|
+
- Added live OpenStreetMap/Nominatim lookup and search support for cities, countries, places, and venues.
|
|
6
|
+
- Added `OpenStreetMapProvider`, `visit.openstreetmap` client facades, city/country subpath exports, examples, and README documentation.
|
|
7
|
+
|
|
8
|
+
## 0.2.4 - 2026-05-25
|
|
9
|
+
|
|
10
|
+
- Added live ComicVine API support for volumes, issues, story arcs, characters, people, and publishers.
|
|
11
|
+
- Added `ComicVineProvider`, ComicVine fetch/search helpers, category-first client facades, examples, and `providers/comicvine/client` export.
|
|
12
|
+
|
|
3
13
|
## 0.2.3 - 2026-05-25
|
|
4
14
|
|
|
5
15
|
- Added live MusicBrainz lookup/search support for releases, release groups, recordings, artists, labels, and works.
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Search, fetch, and normalize media metadata from external providers into a share
|
|
|
4
4
|
|
|
5
5
|
This package is meant to be used by apps that need provider-backed lookup and transformation, but do not want provider-specific response shapes leaking through the app.
|
|
6
6
|
|
|
7
|
-
TMDB, Open Library, GamesDB, and
|
|
7
|
+
TMDB, Open Library, ComicVine, GamesDB, MusicBrainz, and OpenStreetMap include live search/fetch clients. IMDb includes a fetch-by-ID title-page scraper for movie and TV titles. Additional providers currently expose source-record transformers: you provide the raw provider payload, and this package normalizes it into `ZuuidData`.
|
|
8
8
|
|
|
9
9
|
Storage, caching, indexing, review state, object-store keys, and persistence belong in a layer outside this package.
|
|
10
10
|
|
|
@@ -109,20 +109,20 @@ Ratings are normalized to a `0-5` scale when the provider exposes a compatible n
|
|
|
109
109
|
| TMDB | person | yes | yes | yes |
|
|
110
110
|
| Open Library | book | yes | yes | yes |
|
|
111
111
|
| Open Library | author | yes | yes | yes |
|
|
112
|
-
| ComicVine | volume, issue, story_arc, character, person, publisher |
|
|
112
|
+
| ComicVine | volume, issue, story_arc, character, person, publisher | yes | yes | yes |
|
|
113
113
|
| IMDb | movie, tv | no | yes | yes |
|
|
114
114
|
| GamesDB | game | yes | yes | yes |
|
|
115
115
|
| GamesDB | platform | no | yes | yes |
|
|
116
116
|
| Jikan | anime, manga, producer, magazine, character, person | no | no | yes |
|
|
117
117
|
| MusicBrainz | release, release-group, recording, artist, label, work | yes | yes | yes |
|
|
118
118
|
| OpenFoodFacts | product | no | no | yes |
|
|
119
|
-
| OpenStreetMap | city, country, place, venue |
|
|
119
|
+
| OpenStreetMap | city, country, place, venue | yes | yes | yes |
|
|
120
120
|
| Podcast / iTunes | podcast | no | no | yes |
|
|
121
121
|
| Setlist.fm | setlist, artist, venue | no | no | yes |
|
|
122
122
|
| Ticketmaster | event, attraction, venue | no | no | yes |
|
|
123
123
|
| Wger | exercise, equipment | no | no | yes |
|
|
124
124
|
|
|
125
|
-
For IMDb, search is marked `no` because the scraper fetches known title IDs such as `tt0137523`; it does not implement IMDb search. GamesDB platform search is marked `no` because only game search and ID fetches are currently implemented. For transformer-only providers, "Search" and "Fetch" are marked `no` because this package does not perform those HTTP requests yet. Use your own provider client or stored payloads, wrap the payload in a `SourceRecord`, and call the category transformer.
|
|
125
|
+
For IMDb, search is marked `no` because the scraper fetches known title IDs such as `tt0137523`; it does not implement IMDb search. ComicVine and GamesDB require API keys for live API calls. GamesDB platform search is marked `no` because only game search and ID fetches are currently implemented. For transformer-only providers, "Search" and "Fetch" are marked `no` because this package does not perform those HTTP requests yet. Use your own provider client or stored payloads, wrap the payload in a `SourceRecord`, and call the category transformer.
|
|
126
126
|
|
|
127
127
|
|
|
128
128
|
|
|
@@ -154,6 +154,57 @@ const game = await zuuid.play.gamesdb?.game.fetch({ id: 17444 });
|
|
|
154
154
|
|
|
155
155
|
GamesDB transforms accept both simple flat payloads and native TheGamesDB API envelopes with `data.games`, `data.platforms`, lookup maps, and `boxart` image metadata.
|
|
156
156
|
|
|
157
|
+
## OpenStreetMap
|
|
158
|
+
|
|
159
|
+
`OpenStreetMapProvider` uses the public Nominatim API for OSM lookup and search. It sends a descriptive `User-Agent` by default and lets you override it. Fetch IDs must be OSM object IDs with a type prefix: `N` for node, `W` for way, or `R` for relation.
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
import { OpenStreetMapProvider } from "@zivue/zuuid/providers/openstreetmap";
|
|
163
|
+
|
|
164
|
+
const osm = new OpenStreetMapProvider({
|
|
165
|
+
userAgent: "your-app/1.0 (you@example.com)"
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const city = await osm.fetchCity({ id: "R406091" });
|
|
169
|
+
const venues = await osm.searchVenues({ query: "Blue Note Oslo" });
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
The category-first client exposes OpenStreetMap under `visit.openstreetmap`:
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
const zuuid = createZuuidClient({ providers: { openstreetmap: {} } });
|
|
176
|
+
|
|
177
|
+
const places = await zuuid.visit.openstreetmap?.place.search({ query: "Eiffel Tower" });
|
|
178
|
+
const country = await zuuid.visit.openstreetmap?.country.fetch({ id: "R2978650" });
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## ComicVine Credentials
|
|
182
|
+
|
|
183
|
+
`ComicVineProvider` uses the ComicVine API and requires an API key:
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
import { ComicVineProvider } from "@zivue/zuuid/providers/comicvine";
|
|
187
|
+
|
|
188
|
+
const comicvine = new ComicVineProvider({
|
|
189
|
+
apiKey: process.env.COMICVINE_API_KEY!
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
const volume = await comicvine.fetchVolume({ id: 1 });
|
|
193
|
+
const issues = await comicvine.searchIssues({ query: "Saga" });
|
|
194
|
+
const publisher = await comicvine.fetchPublisher({ id: 10 });
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
The category-first client exposes ComicVine under `read.comicvine` and `people.comicvine`:
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
const zuuid = createZuuidClient({
|
|
201
|
+
providers: { comicvine: { apiKey: process.env.COMICVINE_API_KEY! } }
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
const volumes = await zuuid.read.comicvine?.volume.search({ query: "Saga" });
|
|
205
|
+
const character = await zuuid.people.comicvine?.character.search({ query: "Spider-Man" });
|
|
206
|
+
```
|
|
207
|
+
|
|
157
208
|
|
|
158
209
|
## MusicBrainz
|
|
159
210
|
|
|
@@ -228,6 +279,8 @@ const tvShows = await zuuid.tv.tmdb?.search({ query: "Game of Thrones" });
|
|
|
228
279
|
const people = await zuuid.people.tmdb?.search({ query: "Brad Pitt" });
|
|
229
280
|
const books = await zuuid.read.openlibrary?.search({ query: "The Lord of the Rings" });
|
|
230
281
|
const authors = await zuuid.people.openlibrary?.search({ query: "J. K. Rowling" });
|
|
282
|
+
const comics = await zuuid.read.comicvine?.volume.search({ query: "Saga" });
|
|
283
|
+
const places = await zuuid.visit.openstreetmap?.place.search({ query: "Eiffel Tower" });
|
|
231
284
|
```
|
|
232
285
|
|
|
233
286
|
Provider methods are also available directly:
|
|
@@ -246,6 +299,22 @@ const books = await openlibrary.searchBooks({ query: "The Lord of the Rings" });
|
|
|
246
299
|
const authors = await openlibrary.searchAuthors({ query: "J. K. Rowling" });
|
|
247
300
|
```
|
|
248
301
|
|
|
302
|
+
```ts
|
|
303
|
+
import { ComicVineProvider } from "@zivue/zuuid/providers/comicvine";
|
|
304
|
+
|
|
305
|
+
const comicvine = new ComicVineProvider({ apiKey: process.env.COMICVINE_API_KEY! });
|
|
306
|
+
const volumes = await comicvine.searchVolumes({ query: "Saga" });
|
|
307
|
+
const issues = await comicvine.searchIssues({ query: "Saga" });
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
```ts
|
|
311
|
+
import { OpenStreetMapProvider } from "@zivue/zuuid/providers/openstreetmap";
|
|
312
|
+
|
|
313
|
+
const osm = new OpenStreetMapProvider();
|
|
314
|
+
const places = await osm.searchPlaces({ query: "Eiffel Tower" });
|
|
315
|
+
const city = await osm.fetchCity({ id: "R406091" });
|
|
316
|
+
```
|
|
317
|
+
|
|
249
318
|
Search options include pagination and common TMDB filters:
|
|
250
319
|
|
|
251
320
|
```ts
|
|
@@ -430,6 +499,10 @@ npm run example:search -- author "J. K. Rowling"
|
|
|
430
499
|
npm run example:search -- release-group "Kind of Blue"
|
|
431
500
|
npm run example:search -- recording "So What"
|
|
432
501
|
npm run example:search -- artist "Miles Davis"
|
|
502
|
+
COMICVINE_API_KEY=... npm run example:search -- comicvine:volume "Saga"
|
|
503
|
+
COMICVINE_API_KEY=... npm run example:search -- comicvine:issue "Saga"
|
|
504
|
+
npm run example:search -- openstreetmap:place "Eiffel Tower"
|
|
505
|
+
npm run example:search -- openstreetmap:venue "Blue Note Oslo"
|
|
433
506
|
```
|
|
434
507
|
|
|
435
508
|
Fetch and transform a selected provider ID:
|
|
@@ -447,11 +520,15 @@ Fetch live provider examples:
|
|
|
447
520
|
```sh
|
|
448
521
|
npm run example:fetch -- imdb:movie tt0137523
|
|
449
522
|
npm run example:fetch -- imdb:tv tt0944947
|
|
523
|
+
COMICVINE_API_KEY=... npm run example:fetch -- comicvine:volume 1
|
|
524
|
+
COMICVINE_API_KEY=... npm run example:fetch -- comicvine:issue 101
|
|
450
525
|
GAMESDB_API_KEY=... npm run example:fetch -- gamesdb:game 17444
|
|
451
526
|
GAMESDB_API_KEY=... npm run example:fetch -- gamesdb:platform 6
|
|
452
527
|
npm run example:fetch -- musicbrainz:release f5093c06-23e3-404f-aeaa-40f72885ee3a
|
|
453
528
|
npm run example:fetch -- musicbrainz:release-group aaa50249-1e6b-3910-b830-7e2fb622a8c4
|
|
454
529
|
npm run example:fetch -- musicbrainz:artist 561d854a-6a28-4aa7-8c99-323e6ce46c2a
|
|
530
|
+
npm run example:fetch -- openstreetmap:city R406091
|
|
531
|
+
npm run example:fetch -- openstreetmap:country R2978650
|
|
455
532
|
```
|
|
456
533
|
|
|
457
534
|
Transformer-only providers do not have fetch examples. Wrap a real payload from your own provider client in a `SourceRecord` and call the transformer directly.
|
|
@@ -487,8 +564,10 @@ Provider exports:
|
|
|
487
564
|
- `TmdbProvider`
|
|
488
565
|
- `OpenLibraryProvider`
|
|
489
566
|
- `ImdbProvider`
|
|
567
|
+
- `ComicVineProvider`
|
|
490
568
|
- `GamesDbProvider`
|
|
491
569
|
- `MusicBrainzProvider`
|
|
570
|
+
- `OpenStreetMapProvider`
|
|
492
571
|
- `transformTmdbMovie(sourceRecord, options?)`
|
|
493
572
|
- `transformTmdbTv(sourceRecord, options?)`
|
|
494
573
|
- `transformTmdbPerson(sourceRecord, options?)`
|
package/dist/client.d.ts
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
|
+
import { type ComicVineProviderOptions, type ComicVineSearchInput, type FetchComicVineInput } from "./providers/comicvine/index.js";
|
|
1
2
|
import type { SearchResponse, ZuuidData, ZuuidSearchResult } from "./entity.js";
|
|
2
3
|
import { type FetchMusicBrainzInput, type MusicBrainzProviderOptions, type MusicBrainzSearchInput } from "./providers/musicbrainz/index.js";
|
|
3
4
|
import { type FetchOpenLibraryAuthorInput, type FetchOpenLibraryBookInput, type OpenLibraryProviderOptions, type OpenLibrarySearchInput } from "./providers/openlibrary/index.js";
|
|
5
|
+
import { type FetchOpenStreetMapInput, type OpenStreetMapProviderOptions, type OpenStreetMapSearchInput } from "./providers/openstreetmap/index.js";
|
|
4
6
|
import { type FetchTmdbMovieInput, type FetchTmdbPersonInput, type FetchTmdbTvInput, type TmdbProviderOptions, type TmdbSearchInput } from "./providers/tmdb/index.js";
|
|
5
7
|
import { type FetchGamesDbGameInput, type FetchGamesDbPlatformInput, type GamesDbProviderOptions, type GamesDbSearchInput } from "./providers/gamesdb/index.js";
|
|
6
8
|
import { type FetchImdbTitleInput, type ImdbProviderOptions } from "./providers/imdb/index.js";
|
|
7
9
|
import type { SourceRecord } from "./source.js";
|
|
8
10
|
export type ProviderConfigs = {
|
|
11
|
+
comicvine?: ComicVineProviderOptions;
|
|
9
12
|
gamesdb?: GamesDbProviderOptions;
|
|
10
13
|
imdb?: ImdbProviderOptions;
|
|
11
14
|
musicbrainz?: MusicBrainzProviderOptions;
|
|
12
15
|
openlibrary?: OpenLibraryProviderOptions;
|
|
16
|
+
openstreetmap?: OpenStreetMapProviderOptions;
|
|
13
17
|
tmdb?: TmdbProviderOptions;
|
|
14
18
|
};
|
|
15
19
|
export type ZuuidClientConfig = {
|
|
@@ -50,9 +54,19 @@ export type ZuuidClient = {
|
|
|
50
54
|
artist: ProviderClient<FetchMusicBrainzInput, MusicBrainzSearchInput>;
|
|
51
55
|
label: ProviderClient<FetchMusicBrainzInput, MusicBrainzSearchInput>;
|
|
52
56
|
};
|
|
57
|
+
comicvine?: {
|
|
58
|
+
character: ProviderClient<FetchComicVineInput, ComicVineSearchInput>;
|
|
59
|
+
person: ProviderClient<FetchComicVineInput, ComicVineSearchInput>;
|
|
60
|
+
publisher: ProviderClient<FetchComicVineInput, ComicVineSearchInput>;
|
|
61
|
+
};
|
|
53
62
|
};
|
|
54
63
|
read: {
|
|
55
64
|
openlibrary?: ProviderClient<FetchOpenLibraryBookInput, OpenLibrarySearchInput>;
|
|
65
|
+
comicvine?: {
|
|
66
|
+
volume: ProviderClient<FetchComicVineInput, ComicVineSearchInput>;
|
|
67
|
+
issue: ProviderClient<FetchComicVineInput, ComicVineSearchInput>;
|
|
68
|
+
storyArc: ProviderClient<FetchComicVineInput, ComicVineSearchInput>;
|
|
69
|
+
};
|
|
56
70
|
};
|
|
57
71
|
listen: {
|
|
58
72
|
musicbrainz?: {
|
|
@@ -68,6 +82,14 @@ export type ZuuidClient = {
|
|
|
68
82
|
platform: FetchOnlyProviderClient<FetchGamesDbPlatformInput>;
|
|
69
83
|
};
|
|
70
84
|
};
|
|
85
|
+
visit: {
|
|
86
|
+
openstreetmap?: {
|
|
87
|
+
city: ProviderClient<FetchOpenStreetMapInput, OpenStreetMapSearchInput>;
|
|
88
|
+
country: ProviderClient<FetchOpenStreetMapInput, OpenStreetMapSearchInput>;
|
|
89
|
+
place: ProviderClient<FetchOpenStreetMapInput, OpenStreetMapSearchInput>;
|
|
90
|
+
venue: ProviderClient<FetchOpenStreetMapInput, OpenStreetMapSearchInput>;
|
|
91
|
+
};
|
|
92
|
+
};
|
|
71
93
|
};
|
|
72
94
|
export declare function createZuuidClient(config?: ZuuidClientConfig): ZuuidClient;
|
|
73
95
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
+
import { ComicVineProvider, transformComicVine } from "./providers/comicvine/index.js";
|
|
1
2
|
import { MusicBrainzProvider, transformMusicBrainzArtist, transformMusicBrainzLabel, transformMusicBrainzRecording, transformMusicBrainzRelease, transformMusicBrainzReleaseGroup, transformMusicBrainzWork } from "./providers/musicbrainz/index.js";
|
|
2
3
|
import { OpenLibraryProvider, transformOpenLibraryAuthor, transformOpenLibraryBook } from "./providers/openlibrary/index.js";
|
|
4
|
+
import { OpenStreetMapProvider, transformOpenStreetMapPlace } from "./providers/openstreetmap/index.js";
|
|
3
5
|
import { TmdbProvider, transformTmdbMovie, transformTmdbPerson, transformTmdbTv } from "./providers/tmdb/index.js";
|
|
4
6
|
import { GamesDbProvider, transformGamesDbGame, transformGamesDbPlatform } from "./providers/gamesdb/index.js";
|
|
5
7
|
import { ImdbProvider, transformImdbMovie, transformImdbTv } from "./providers/imdb/index.js";
|
|
6
8
|
export function createZuuidClient(config = {}) {
|
|
9
|
+
const comicvine = config.providers?.comicvine ? new ComicVineProvider(config.providers.comicvine) : undefined;
|
|
7
10
|
const gamesdb = config.providers?.gamesdb ? new GamesDbProvider(config.providers.gamesdb) : undefined;
|
|
8
11
|
const imdb = config.providers?.imdb ? new ImdbProvider(config.providers.imdb) : undefined;
|
|
9
12
|
const musicbrainz = config.providers?.musicbrainz ? new MusicBrainzProvider(config.providers.musicbrainz) : undefined;
|
|
10
13
|
const openlibrary = config.providers?.openlibrary ? new OpenLibraryProvider(config.providers.openlibrary) : undefined;
|
|
14
|
+
const openstreetmap = config.providers?.openstreetmap ? new OpenStreetMapProvider(config.providers.openstreetmap) : undefined;
|
|
11
15
|
const tmdb = config.providers?.tmdb ? new TmdbProvider(config.providers.tmdb) : undefined;
|
|
12
16
|
return Object.freeze({
|
|
13
17
|
movie: Object.freeze({
|
|
@@ -82,6 +86,31 @@ export function createZuuidClient(config = {}) {
|
|
|
82
86
|
transform: (source) => transformMusicBrainzLabel(source)
|
|
83
87
|
})
|
|
84
88
|
})
|
|
89
|
+
: undefined,
|
|
90
|
+
comicvine: comicvine
|
|
91
|
+
? Object.freeze({
|
|
92
|
+
character: Object.freeze({
|
|
93
|
+
fetch: (input) => comicvine.fetchCharacter(input),
|
|
94
|
+
fetchSourceRecord: (input) => comicvine.fetchCharacterSourceRecord(input),
|
|
95
|
+
search: (input) => comicvine.searchCharacters(input),
|
|
96
|
+
searchSourceRecords: (input) => comicvine.searchCharacterSourceRecords(input),
|
|
97
|
+
transform: (source) => transformComicVine(source)
|
|
98
|
+
}),
|
|
99
|
+
person: Object.freeze({
|
|
100
|
+
fetch: (input) => comicvine.fetchPerson(input),
|
|
101
|
+
fetchSourceRecord: (input) => comicvine.fetchPersonSourceRecord(input),
|
|
102
|
+
search: (input) => comicvine.searchPeople(input),
|
|
103
|
+
searchSourceRecords: (input) => comicvine.searchPersonSourceRecords(input),
|
|
104
|
+
transform: (source) => transformComicVine(source)
|
|
105
|
+
}),
|
|
106
|
+
publisher: Object.freeze({
|
|
107
|
+
fetch: (input) => comicvine.fetchPublisher(input),
|
|
108
|
+
fetchSourceRecord: (input) => comicvine.fetchPublisherSourceRecord(input),
|
|
109
|
+
search: (input) => comicvine.searchPublishers(input),
|
|
110
|
+
searchSourceRecords: (input) => comicvine.searchPublisherSourceRecords(input),
|
|
111
|
+
transform: (source) => transformComicVine(source)
|
|
112
|
+
})
|
|
113
|
+
})
|
|
85
114
|
: undefined
|
|
86
115
|
}),
|
|
87
116
|
read: Object.freeze({
|
|
@@ -93,6 +122,31 @@ export function createZuuidClient(config = {}) {
|
|
|
93
122
|
searchSourceRecords: (input) => openlibrary.searchBookSourceRecords(input),
|
|
94
123
|
transform: (source) => transformOpenLibraryBook(source, openlibrary.transformOptions())
|
|
95
124
|
})
|
|
125
|
+
: undefined,
|
|
126
|
+
comicvine: comicvine
|
|
127
|
+
? Object.freeze({
|
|
128
|
+
volume: Object.freeze({
|
|
129
|
+
fetch: (input) => comicvine.fetchVolume(input),
|
|
130
|
+
fetchSourceRecord: (input) => comicvine.fetchVolumeSourceRecord(input),
|
|
131
|
+
search: (input) => comicvine.searchVolumes(input),
|
|
132
|
+
searchSourceRecords: (input) => comicvine.searchVolumeSourceRecords(input),
|
|
133
|
+
transform: (source) => transformComicVine(source)
|
|
134
|
+
}),
|
|
135
|
+
issue: Object.freeze({
|
|
136
|
+
fetch: (input) => comicvine.fetchIssue(input),
|
|
137
|
+
fetchSourceRecord: (input) => comicvine.fetchIssueSourceRecord(input),
|
|
138
|
+
search: (input) => comicvine.searchIssues(input),
|
|
139
|
+
searchSourceRecords: (input) => comicvine.searchIssueSourceRecords(input),
|
|
140
|
+
transform: (source) => transformComicVine(source)
|
|
141
|
+
}),
|
|
142
|
+
storyArc: Object.freeze({
|
|
143
|
+
fetch: (input) => comicvine.fetchStoryArc(input),
|
|
144
|
+
fetchSourceRecord: (input) => comicvine.fetchStoryArcSourceRecord(input),
|
|
145
|
+
search: (input) => comicvine.searchStoryArcs(input),
|
|
146
|
+
searchSourceRecords: (input) => comicvine.searchStoryArcSourceRecords(input),
|
|
147
|
+
transform: (source) => transformComicVine(source)
|
|
148
|
+
})
|
|
149
|
+
})
|
|
96
150
|
: undefined
|
|
97
151
|
}),
|
|
98
152
|
listen: Object.freeze({
|
|
@@ -146,6 +200,40 @@ export function createZuuidClient(config = {}) {
|
|
|
146
200
|
})
|
|
147
201
|
})
|
|
148
202
|
: undefined
|
|
203
|
+
}),
|
|
204
|
+
visit: Object.freeze({
|
|
205
|
+
openstreetmap: openstreetmap
|
|
206
|
+
? Object.freeze({
|
|
207
|
+
city: Object.freeze({
|
|
208
|
+
fetch: (input) => openstreetmap.fetchCity(input),
|
|
209
|
+
fetchSourceRecord: (input) => openstreetmap.fetchCitySourceRecord(input),
|
|
210
|
+
search: (input) => openstreetmap.searchCities(input),
|
|
211
|
+
searchSourceRecords: (input) => openstreetmap.searchCitySourceRecords(input),
|
|
212
|
+
transform: (source) => transformOpenStreetMapPlace(source)
|
|
213
|
+
}),
|
|
214
|
+
country: Object.freeze({
|
|
215
|
+
fetch: (input) => openstreetmap.fetchCountry(input),
|
|
216
|
+
fetchSourceRecord: (input) => openstreetmap.fetchCountrySourceRecord(input),
|
|
217
|
+
search: (input) => openstreetmap.searchCountries(input),
|
|
218
|
+
searchSourceRecords: (input) => openstreetmap.searchCountrySourceRecords(input),
|
|
219
|
+
transform: (source) => transformOpenStreetMapPlace(source)
|
|
220
|
+
}),
|
|
221
|
+
place: Object.freeze({
|
|
222
|
+
fetch: (input) => openstreetmap.fetchPlace(input),
|
|
223
|
+
fetchSourceRecord: (input) => openstreetmap.fetchPlaceSourceRecord(input),
|
|
224
|
+
search: (input) => openstreetmap.searchPlaces(input),
|
|
225
|
+
searchSourceRecords: (input) => openstreetmap.searchPlaceSourceRecords(input),
|
|
226
|
+
transform: (source) => transformOpenStreetMapPlace(source)
|
|
227
|
+
}),
|
|
228
|
+
venue: Object.freeze({
|
|
229
|
+
fetch: (input) => openstreetmap.fetchVenue(input),
|
|
230
|
+
fetchSourceRecord: (input) => openstreetmap.fetchVenueSourceRecord(input),
|
|
231
|
+
search: (input) => openstreetmap.searchVenues(input),
|
|
232
|
+
searchSourceRecords: (input) => openstreetmap.searchVenueSourceRecords(input),
|
|
233
|
+
transform: (source) => transformOpenStreetMapPlace(source)
|
|
234
|
+
})
|
|
235
|
+
})
|
|
236
|
+
: undefined
|
|
149
237
|
})
|
|
150
238
|
});
|
|
151
239
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { SearchResponse, ZuuidData, ZuuidSearchResult } from "../../entity.js";
|
|
2
|
+
import { type SourceRecord } from "../../source.js";
|
|
3
|
+
import type { ComicVineApiResponse, ComicVineProviderOptions, ComicVineSearchInput, FetchComicVineInput } from "./types.js";
|
|
4
|
+
export declare class ComicVineProvider {
|
|
5
|
+
readonly apiBase: string;
|
|
6
|
+
readonly userAgent: string;
|
|
7
|
+
private readonly apiKey;
|
|
8
|
+
private readonly fetchImpl;
|
|
9
|
+
constructor(options: ComicVineProviderOptions);
|
|
10
|
+
getJson<T>(path: string, params: Record<string, string>): Promise<T | undefined>;
|
|
11
|
+
getEnvelope<T>(path: string, params: Record<string, string>): Promise<ComicVineApiResponse<T>>;
|
|
12
|
+
fetchVolumeSourceRecord(input: FetchComicVineInput): Promise<SourceRecord | undefined>;
|
|
13
|
+
fetchVolume(input: FetchComicVineInput): Promise<ZuuidData | undefined>;
|
|
14
|
+
searchVolumeSourceRecords(input: ComicVineSearchInput): Promise<SearchResponse<SourceRecord>>;
|
|
15
|
+
searchVolumes(input: ComicVineSearchInput): Promise<SearchResponse<ZuuidSearchResult>>;
|
|
16
|
+
fetchIssueSourceRecord(input: FetchComicVineInput): Promise<SourceRecord | undefined>;
|
|
17
|
+
fetchIssue(input: FetchComicVineInput): Promise<ZuuidData | undefined>;
|
|
18
|
+
searchIssueSourceRecords(input: ComicVineSearchInput): Promise<SearchResponse<SourceRecord>>;
|
|
19
|
+
searchIssues(input: ComicVineSearchInput): Promise<SearchResponse<ZuuidSearchResult>>;
|
|
20
|
+
fetchStoryArcSourceRecord(input: FetchComicVineInput): Promise<SourceRecord | undefined>;
|
|
21
|
+
fetchStoryArc(input: FetchComicVineInput): Promise<ZuuidData | undefined>;
|
|
22
|
+
searchStoryArcSourceRecords(input: ComicVineSearchInput): Promise<SearchResponse<SourceRecord>>;
|
|
23
|
+
searchStoryArcs(input: ComicVineSearchInput): Promise<SearchResponse<ZuuidSearchResult>>;
|
|
24
|
+
fetchCharacterSourceRecord(input: FetchComicVineInput): Promise<SourceRecord | undefined>;
|
|
25
|
+
fetchCharacter(input: FetchComicVineInput): Promise<ZuuidData | undefined>;
|
|
26
|
+
searchCharacterSourceRecords(input: ComicVineSearchInput): Promise<SearchResponse<SourceRecord>>;
|
|
27
|
+
searchCharacters(input: ComicVineSearchInput): Promise<SearchResponse<ZuuidSearchResult>>;
|
|
28
|
+
fetchPersonSourceRecord(input: FetchComicVineInput): Promise<SourceRecord | undefined>;
|
|
29
|
+
fetchPerson(input: FetchComicVineInput): Promise<ZuuidData | undefined>;
|
|
30
|
+
searchPersonSourceRecords(input: ComicVineSearchInput): Promise<SearchResponse<SourceRecord>>;
|
|
31
|
+
searchPeople(input: ComicVineSearchInput): Promise<SearchResponse<ZuuidSearchResult>>;
|
|
32
|
+
fetchPublisherSourceRecord(input: FetchComicVineInput): Promise<SourceRecord | undefined>;
|
|
33
|
+
fetchPublisher(input: FetchComicVineInput): Promise<ZuuidData | undefined>;
|
|
34
|
+
searchPublisherSourceRecords(input: ComicVineSearchInput): Promise<SearchResponse<SourceRecord>>;
|
|
35
|
+
searchPublishers(input: ComicVineSearchInput): Promise<SearchResponse<ZuuidSearchResult>>;
|
|
36
|
+
}
|
|
37
|
+
export declare function fetchComicVineSourceRecord(provider: ComicVineProvider, category: string, input: FetchComicVineInput): Promise<SourceRecord | undefined>;
|
|
38
|
+
export declare function searchComicVineSourceRecords(provider: ComicVineProvider, category: string, input: ComicVineSearchInput): Promise<SearchResponse<SourceRecord>>;
|
|
39
|
+
export declare function searchComicVine(provider: ComicVineProvider, category: string, input: ComicVineSearchInput): Promise<SearchResponse<ZuuidSearchResult>>;
|
|
40
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/providers/comicvine/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { providerZuuid } from "../../identity.js";
|
|
2
|
+
import { createSourceRecord } from "../../source.js";
|
|
3
|
+
import { datePrefix, nestedString, stringField, valueAsString } from "../common.js";
|
|
4
|
+
import { COMICVINE_API_BASE, COMICVINE_CHARACTER_CATEGORY, COMICVINE_DEFAULT_USER_AGENT, COMICVINE_ISSUE_CATEGORY, COMICVINE_PERSON_CATEGORY, COMICVINE_PROVIDER, COMICVINE_PUBLISHER_CATEGORY, COMICVINE_STORY_ARC_CATEGORY, COMICVINE_VOLUME_CATEGORY } from "./constants.js";
|
|
5
|
+
import { transformComicVine } from "./transform.js";
|
|
6
|
+
const CATEGORY_CONFIG = {
|
|
7
|
+
[COMICVINE_VOLUME_CATEGORY]: { detailPath: "volume", searchResource: "volume", idPrefix: "4050", publicCategory: "comic" },
|
|
8
|
+
[COMICVINE_ISSUE_CATEGORY]: { detailPath: "issue", searchResource: "issue", idPrefix: "4000", publicCategory: "comic" },
|
|
9
|
+
[COMICVINE_STORY_ARC_CATEGORY]: { detailPath: "story_arc", searchResource: "story_arc", idPrefix: "4045", publicCategory: "comic" },
|
|
10
|
+
[COMICVINE_CHARACTER_CATEGORY]: { detailPath: "character", searchResource: "character", idPrefix: "4005", publicCategory: "person" },
|
|
11
|
+
[COMICVINE_PERSON_CATEGORY]: { detailPath: "person", searchResource: "person", idPrefix: "4040", publicCategory: "person" },
|
|
12
|
+
[COMICVINE_PUBLISHER_CATEGORY]: { detailPath: "publisher", searchResource: "publisher", idPrefix: "4010", publicCategory: "organization" }
|
|
13
|
+
};
|
|
14
|
+
export class ComicVineProvider {
|
|
15
|
+
apiBase;
|
|
16
|
+
userAgent;
|
|
17
|
+
apiKey;
|
|
18
|
+
fetchImpl;
|
|
19
|
+
constructor(options) {
|
|
20
|
+
this.apiKey = options.apiKey.trim();
|
|
21
|
+
if (!this.apiKey)
|
|
22
|
+
throw new Error("ComicVine API key must not be empty");
|
|
23
|
+
this.apiBase = options.apiBase ?? COMICVINE_API_BASE;
|
|
24
|
+
this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
25
|
+
this.userAgent = options.userAgent ?? COMICVINE_DEFAULT_USER_AGENT;
|
|
26
|
+
}
|
|
27
|
+
async getJson(path, params) {
|
|
28
|
+
const url = new URL(`${this.apiBase.replace(/\/$/, "")}/${path.replace(/^\//, "")}`);
|
|
29
|
+
url.searchParams.set("api_key", this.apiKey);
|
|
30
|
+
url.searchParams.set("format", "json");
|
|
31
|
+
for (const [key, value] of Object.entries(params))
|
|
32
|
+
url.searchParams.set(key, value);
|
|
33
|
+
const response = await this.fetchImpl(url, { headers: { accept: "application/json", "user-agent": this.userAgent } });
|
|
34
|
+
if (response.status === 404)
|
|
35
|
+
return undefined;
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
const body = await response.text().catch(() => "");
|
|
38
|
+
throw new Error(`ComicVine API returned ${response.status}: ${body}`);
|
|
39
|
+
}
|
|
40
|
+
const payload = await response.json();
|
|
41
|
+
if (payload.status_code === 101)
|
|
42
|
+
return undefined;
|
|
43
|
+
if (payload.status_code !== undefined && payload.status_code !== 1) {
|
|
44
|
+
throw new Error(`ComicVine API returned status ${payload.status_code}: ${payload.error ?? "unknown error"}`);
|
|
45
|
+
}
|
|
46
|
+
return payload.results;
|
|
47
|
+
}
|
|
48
|
+
async getEnvelope(path, params) {
|
|
49
|
+
const url = new URL(`${this.apiBase.replace(/\/$/, "")}/${path.replace(/^\//, "")}`);
|
|
50
|
+
url.searchParams.set("api_key", this.apiKey);
|
|
51
|
+
url.searchParams.set("format", "json");
|
|
52
|
+
for (const [key, value] of Object.entries(params))
|
|
53
|
+
url.searchParams.set(key, value);
|
|
54
|
+
const response = await this.fetchImpl(url, { headers: { accept: "application/json", "user-agent": this.userAgent } });
|
|
55
|
+
if (!response.ok) {
|
|
56
|
+
const body = await response.text().catch(() => "");
|
|
57
|
+
throw new Error(`ComicVine API returned ${response.status}: ${body}`);
|
|
58
|
+
}
|
|
59
|
+
const payload = await response.json();
|
|
60
|
+
if (payload.status_code !== undefined && payload.status_code !== 1) {
|
|
61
|
+
throw new Error(`ComicVine API returned status ${payload.status_code}: ${payload.error ?? "unknown error"}`);
|
|
62
|
+
}
|
|
63
|
+
return payload;
|
|
64
|
+
}
|
|
65
|
+
async fetchVolumeSourceRecord(input) { return fetchComicVineSourceRecord(this, COMICVINE_VOLUME_CATEGORY, input); }
|
|
66
|
+
async fetchVolume(input) { const source = await this.fetchVolumeSourceRecord(input); return source ? transformComicVine(source) : undefined; }
|
|
67
|
+
async searchVolumeSourceRecords(input) { return searchComicVineSourceRecords(this, COMICVINE_VOLUME_CATEGORY, input); }
|
|
68
|
+
async searchVolumes(input) { return searchComicVine(this, COMICVINE_VOLUME_CATEGORY, input); }
|
|
69
|
+
async fetchIssueSourceRecord(input) { return fetchComicVineSourceRecord(this, COMICVINE_ISSUE_CATEGORY, input); }
|
|
70
|
+
async fetchIssue(input) { const source = await this.fetchIssueSourceRecord(input); return source ? transformComicVine(source) : undefined; }
|
|
71
|
+
async searchIssueSourceRecords(input) { return searchComicVineSourceRecords(this, COMICVINE_ISSUE_CATEGORY, input); }
|
|
72
|
+
async searchIssues(input) { return searchComicVine(this, COMICVINE_ISSUE_CATEGORY, input); }
|
|
73
|
+
async fetchStoryArcSourceRecord(input) { return fetchComicVineSourceRecord(this, COMICVINE_STORY_ARC_CATEGORY, input); }
|
|
74
|
+
async fetchStoryArc(input) { const source = await this.fetchStoryArcSourceRecord(input); return source ? transformComicVine(source) : undefined; }
|
|
75
|
+
async searchStoryArcSourceRecords(input) { return searchComicVineSourceRecords(this, COMICVINE_STORY_ARC_CATEGORY, input); }
|
|
76
|
+
async searchStoryArcs(input) { return searchComicVine(this, COMICVINE_STORY_ARC_CATEGORY, input); }
|
|
77
|
+
async fetchCharacterSourceRecord(input) { return fetchComicVineSourceRecord(this, COMICVINE_CHARACTER_CATEGORY, input); }
|
|
78
|
+
async fetchCharacter(input) { const source = await this.fetchCharacterSourceRecord(input); return source ? transformComicVine(source) : undefined; }
|
|
79
|
+
async searchCharacterSourceRecords(input) { return searchComicVineSourceRecords(this, COMICVINE_CHARACTER_CATEGORY, input); }
|
|
80
|
+
async searchCharacters(input) { return searchComicVine(this, COMICVINE_CHARACTER_CATEGORY, input); }
|
|
81
|
+
async fetchPersonSourceRecord(input) { return fetchComicVineSourceRecord(this, COMICVINE_PERSON_CATEGORY, input); }
|
|
82
|
+
async fetchPerson(input) { const source = await this.fetchPersonSourceRecord(input); return source ? transformComicVine(source) : undefined; }
|
|
83
|
+
async searchPersonSourceRecords(input) { return searchComicVineSourceRecords(this, COMICVINE_PERSON_CATEGORY, input); }
|
|
84
|
+
async searchPeople(input) { return searchComicVine(this, COMICVINE_PERSON_CATEGORY, input); }
|
|
85
|
+
async fetchPublisherSourceRecord(input) { return fetchComicVineSourceRecord(this, COMICVINE_PUBLISHER_CATEGORY, input); }
|
|
86
|
+
async fetchPublisher(input) { const source = await this.fetchPublisherSourceRecord(input); return source ? transformComicVine(source) : undefined; }
|
|
87
|
+
async searchPublisherSourceRecords(input) { return searchComicVineSourceRecords(this, COMICVINE_PUBLISHER_CATEGORY, input); }
|
|
88
|
+
async searchPublishers(input) { return searchComicVine(this, COMICVINE_PUBLISHER_CATEGORY, input); }
|
|
89
|
+
}
|
|
90
|
+
export async function fetchComicVineSourceRecord(provider, category, input) {
|
|
91
|
+
const comicCategory = requireCategory(category);
|
|
92
|
+
const id = comicVineId(input.id);
|
|
93
|
+
const config = CATEGORY_CONFIG[comicCategory];
|
|
94
|
+
const payload = await provider.getJson(`/${config.detailPath}/${config.idPrefix}-${id}/`, {});
|
|
95
|
+
if (!payload)
|
|
96
|
+
return undefined;
|
|
97
|
+
return createSourceRecord({ source: { provider: COMICVINE_PROVIDER, category, externalId: id }, payload });
|
|
98
|
+
}
|
|
99
|
+
export async function searchComicVineSourceRecords(provider, category, input) {
|
|
100
|
+
const payload = await searchPayload(provider, category, input);
|
|
101
|
+
const comicCategory = requireCategory(category);
|
|
102
|
+
return {
|
|
103
|
+
results: await Promise.all(searchItems(payload).map((item) => createSourceRecord({ source: { provider: COMICVINE_PROVIDER, category, externalId: resultId(item, comicCategory) ?? "" }, payload: item }))),
|
|
104
|
+
pagination: pagination(payload)
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export async function searchComicVine(provider, category, input) {
|
|
108
|
+
const payload = await searchPayload(provider, category, input);
|
|
109
|
+
const comicCategory = requireCategory(category);
|
|
110
|
+
const results = [];
|
|
111
|
+
for (const item of searchItems(payload)) {
|
|
112
|
+
const externalId = resultId(item, comicCategory);
|
|
113
|
+
const title = stringField(item, "name") ?? stringField(item, "title");
|
|
114
|
+
if (!externalId || !title)
|
|
115
|
+
continue;
|
|
116
|
+
const zuuid = await providerZuuid({ provider: COMICVINE_PROVIDER, category, externalId });
|
|
117
|
+
results.push({
|
|
118
|
+
id: zuuid,
|
|
119
|
+
zuuid,
|
|
120
|
+
category: CATEGORY_CONFIG[comicCategory].publicCategory,
|
|
121
|
+
title,
|
|
122
|
+
date: dateFor(item),
|
|
123
|
+
cover: nestedString(item, ["image", "super_url"]) ?? nestedString(item, ["image", "original_url"]) ?? nestedString(item, ["image", "medium_url"]) ?? null,
|
|
124
|
+
rating: null,
|
|
125
|
+
weight: numberValue(item, "score"),
|
|
126
|
+
relationType: null,
|
|
127
|
+
attribute: attributeFor(item, comicCategory),
|
|
128
|
+
order: null,
|
|
129
|
+
source: { source: COMICVINE_PROVIDER, category, value: externalId }
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
return { results, pagination: pagination(payload) };
|
|
133
|
+
}
|
|
134
|
+
async function searchPayload(provider, category, input) {
|
|
135
|
+
const comicCategory = requireCategory(category);
|
|
136
|
+
const query = input.query.trim();
|
|
137
|
+
if (!query)
|
|
138
|
+
throw new Error("ComicVine search query must not be empty");
|
|
139
|
+
return provider.getEnvelope("/search/", {
|
|
140
|
+
query,
|
|
141
|
+
resources: CATEGORY_CONFIG[comicCategory].searchResource,
|
|
142
|
+
limit: String(input.limit ?? 25),
|
|
143
|
+
offset: String(input.offset ?? 0),
|
|
144
|
+
...(input.fieldList?.length ? { field_list: input.fieldList.join(",") } : {})
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function searchItems(payload) {
|
|
148
|
+
return Array.isArray(payload.results) ? payload.results.filter(isObject) : [];
|
|
149
|
+
}
|
|
150
|
+
function pagination(payload) {
|
|
151
|
+
const total = payload.number_of_total_results ?? searchItems(payload).length;
|
|
152
|
+
const offset = payload.offset ?? 0;
|
|
153
|
+
const limit = payload.limit ?? payload.number_of_page_results ?? searchItems(payload).length;
|
|
154
|
+
return { page: limit > 0 ? Math.floor(offset / limit) + 1 : 1, totalPages: limit > 0 ? Math.ceil(total / limit) : 0, totalResults: total };
|
|
155
|
+
}
|
|
156
|
+
function requireCategory(category) {
|
|
157
|
+
if (category in CATEGORY_CONFIG)
|
|
158
|
+
return category;
|
|
159
|
+
throw new Error(`unsupported ComicVine category: ${category}`);
|
|
160
|
+
}
|
|
161
|
+
function comicVineId(value) {
|
|
162
|
+
const id = String(value).trim();
|
|
163
|
+
const normalized = id.includes("-") ? id.split("-").pop() ?? "" : id;
|
|
164
|
+
if (!/^\d+$/.test(normalized))
|
|
165
|
+
throw new Error(`ComicVine id must be numeric: ${value}`);
|
|
166
|
+
return normalized;
|
|
167
|
+
}
|
|
168
|
+
function resultId(item, category) {
|
|
169
|
+
const raw = valueAsString(item.id);
|
|
170
|
+
if (!raw)
|
|
171
|
+
return undefined;
|
|
172
|
+
return raw.startsWith(`${CATEGORY_CONFIG[category].idPrefix}-`) ? raw.slice(CATEGORY_CONFIG[category].idPrefix.length + 1) : raw;
|
|
173
|
+
}
|
|
174
|
+
function dateFor(item) {
|
|
175
|
+
return datePrefix(stringField(item, "cover_date")) ?? datePrefix(stringField(item, "store_date")) ?? stringField(item, "start_year") ?? null;
|
|
176
|
+
}
|
|
177
|
+
function attributeFor(item, category) {
|
|
178
|
+
if (category === COMICVINE_ISSUE_CATEGORY)
|
|
179
|
+
return stringField(item, "issue_number") ?? null;
|
|
180
|
+
if (category === COMICVINE_PERSON_CATEGORY || category === COMICVINE_CHARACTER_CATEGORY)
|
|
181
|
+
return stringField(item, "real_name") ?? null;
|
|
182
|
+
return stringField(item, "deck") ?? null;
|
|
183
|
+
}
|
|
184
|
+
function numberValue(item, key) {
|
|
185
|
+
const value = item[key];
|
|
186
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
187
|
+
}
|
|
188
|
+
function isObject(value) {
|
|
189
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
190
|
+
}
|
|
@@ -5,4 +5,6 @@ export declare const COMICVINE_STORY_ARC_CATEGORY = "story_arc";
|
|
|
5
5
|
export declare const COMICVINE_CHARACTER_CATEGORY = "character";
|
|
6
6
|
export declare const COMICVINE_PERSON_CATEGORY = "person";
|
|
7
7
|
export declare const COMICVINE_PUBLISHER_CATEGORY = "publisher";
|
|
8
|
+
export declare const COMICVINE_API_BASE = "https://comicvine.gamespot.com/api";
|
|
9
|
+
export declare const COMICVINE_DEFAULT_USER_AGENT = "@zivue/zuuid ComicVine client (+https://github.com/zivue/zuuid)";
|
|
8
10
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/providers/comicvine/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAC9C,eAAO,MAAM,yBAAyB,WAAW,CAAC;AAClD,eAAO,MAAM,wBAAwB,UAAU,CAAC;AAChD,eAAO,MAAM,4BAA4B,cAAc,CAAC;AACxD,eAAO,MAAM,4BAA4B,cAAc,CAAC;AACxD,eAAO,MAAM,yBAAyB,WAAW,CAAC;AAClD,eAAO,MAAM,4BAA4B,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/providers/comicvine/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAC9C,eAAO,MAAM,yBAAyB,WAAW,CAAC;AAClD,eAAO,MAAM,wBAAwB,UAAU,CAAC;AAChD,eAAO,MAAM,4BAA4B,cAAc,CAAC;AACxD,eAAO,MAAM,4BAA4B,cAAc,CAAC;AACxD,eAAO,MAAM,yBAAyB,WAAW,CAAC;AAClD,eAAO,MAAM,4BAA4B,cAAc,CAAC;AACxD,eAAO,MAAM,kBAAkB,uCAAuC,CAAC;AACvE,eAAO,MAAM,4BAA4B,oEAAoE,CAAC"}
|
|
@@ -5,3 +5,5 @@ export const COMICVINE_STORY_ARC_CATEGORY = "story_arc";
|
|
|
5
5
|
export const COMICVINE_CHARACTER_CATEGORY = "character";
|
|
6
6
|
export const COMICVINE_PERSON_CATEGORY = "person";
|
|
7
7
|
export const COMICVINE_PUBLISHER_CATEGORY = "publisher";
|
|
8
|
+
export const COMICVINE_API_BASE = "https://comicvine.gamespot.com/api";
|
|
9
|
+
export const COMICVINE_DEFAULT_USER_AGENT = "@zivue/zuuid ComicVine client (+https://github.com/zivue/zuuid)";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/comicvine/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/comicvine/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type ComicVineFetchLike = (input: string | URL, init?: RequestInit) => Promise<Response>;
|
|
2
|
+
export type ComicVineProviderOptions = {
|
|
3
|
+
apiKey: string;
|
|
4
|
+
apiBase?: string;
|
|
5
|
+
fetch?: ComicVineFetchLike;
|
|
6
|
+
userAgent?: string;
|
|
7
|
+
};
|
|
8
|
+
export type FetchComicVineInput = {
|
|
9
|
+
id: string | number;
|
|
10
|
+
};
|
|
11
|
+
export type ComicVineSearchInput = {
|
|
12
|
+
query: string;
|
|
13
|
+
limit?: number;
|
|
14
|
+
offset?: number;
|
|
15
|
+
fieldList?: string[];
|
|
16
|
+
};
|
|
17
|
+
export type ComicVineApiResponse<T> = {
|
|
18
|
+
error?: string;
|
|
19
|
+
limit?: number;
|
|
20
|
+
offset?: number;
|
|
21
|
+
number_of_page_results?: number;
|
|
22
|
+
number_of_total_results?: number;
|
|
23
|
+
status_code?: number;
|
|
24
|
+
results?: T;
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/providers/comicvine/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEhG,MAAM,MAAM,wBAAwB,GAAG;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,CAAC;CACb,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -8,5 +8,5 @@ export declare const MUSICBRAINZ_WORK_CATEGORY = "work";
|
|
|
8
8
|
export declare const MUSICBRAINZ_COVER_ART_BASE_URL = "https://coverartarchive.org/release";
|
|
9
9
|
export declare const MUSICBRAINZ_RELEASE_GROUP_COVER_ART_BASE_URL = "https://coverartarchive.org/release-group";
|
|
10
10
|
export declare const MUSICBRAINZ_API_BASE = "https://musicbrainz.org/ws/2";
|
|
11
|
-
export declare const MUSICBRAINZ_DEFAULT_USER_AGENT = "@zivue/zuuid/0.2.
|
|
11
|
+
export declare const MUSICBRAINZ_DEFAULT_USER_AGENT = "@zivue/zuuid/0.2.5 (https://github.com/zivue/zuuid)";
|
|
12
12
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -8,4 +8,4 @@ export const MUSICBRAINZ_WORK_CATEGORY = "work";
|
|
|
8
8
|
export const MUSICBRAINZ_COVER_ART_BASE_URL = "https://coverartarchive.org/release";
|
|
9
9
|
export const MUSICBRAINZ_RELEASE_GROUP_COVER_ART_BASE_URL = "https://coverartarchive.org/release-group";
|
|
10
10
|
export const MUSICBRAINZ_API_BASE = "https://musicbrainz.org/ws/2";
|
|
11
|
-
export const MUSICBRAINZ_DEFAULT_USER_AGENT = "@zivue/zuuid/0.2.
|
|
11
|
+
export const MUSICBRAINZ_DEFAULT_USER_AGENT = "@zivue/zuuid/0.2.5 (https://github.com/zivue/zuuid)";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"city.d.ts","sourceRoot":"","sources":["../../../src/providers/openstreetmap/city.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,IAAI,0BAA0B,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { transformOpenStreetMapPlace as transformOpenStreetMapCity } from "./place.js";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { SearchResponse, ZuuidData, ZuuidSearchResult } from "../../entity.js";
|
|
2
|
+
import { type SourceRecord } from "../../source.js";
|
|
3
|
+
import type { FetchOpenStreetMapInput, OpenStreetMapProviderOptions, OpenStreetMapSearchInput } from "./types.js";
|
|
4
|
+
export declare class OpenStreetMapProvider {
|
|
5
|
+
readonly apiBase: string;
|
|
6
|
+
readonly userAgent: string;
|
|
7
|
+
readonly language: string;
|
|
8
|
+
private readonly fetchImpl;
|
|
9
|
+
constructor(options?: OpenStreetMapProviderOptions);
|
|
10
|
+
getJson<T>(path: string, params: Record<string, string>): Promise<T | undefined>;
|
|
11
|
+
fetchCitySourceRecord(input: FetchOpenStreetMapInput): Promise<SourceRecord | undefined>;
|
|
12
|
+
fetchCity(input: FetchOpenStreetMapInput): Promise<ZuuidData | undefined>;
|
|
13
|
+
searchCitySourceRecords(input: OpenStreetMapSearchInput): Promise<SearchResponse<SourceRecord>>;
|
|
14
|
+
searchCities(input: OpenStreetMapSearchInput): Promise<SearchResponse<ZuuidSearchResult>>;
|
|
15
|
+
fetchCountrySourceRecord(input: FetchOpenStreetMapInput): Promise<SourceRecord | undefined>;
|
|
16
|
+
fetchCountry(input: FetchOpenStreetMapInput): Promise<ZuuidData | undefined>;
|
|
17
|
+
searchCountrySourceRecords(input: OpenStreetMapSearchInput): Promise<SearchResponse<SourceRecord>>;
|
|
18
|
+
searchCountries(input: OpenStreetMapSearchInput): Promise<SearchResponse<ZuuidSearchResult>>;
|
|
19
|
+
fetchPlaceSourceRecord(input: FetchOpenStreetMapInput): Promise<SourceRecord | undefined>;
|
|
20
|
+
fetchPlace(input: FetchOpenStreetMapInput): Promise<ZuuidData | undefined>;
|
|
21
|
+
searchPlaceSourceRecords(input: OpenStreetMapSearchInput): Promise<SearchResponse<SourceRecord>>;
|
|
22
|
+
searchPlaces(input: OpenStreetMapSearchInput): Promise<SearchResponse<ZuuidSearchResult>>;
|
|
23
|
+
fetchVenueSourceRecord(input: FetchOpenStreetMapInput): Promise<SourceRecord | undefined>;
|
|
24
|
+
fetchVenue(input: FetchOpenStreetMapInput): Promise<ZuuidData | undefined>;
|
|
25
|
+
searchVenueSourceRecords(input: OpenStreetMapSearchInput): Promise<SearchResponse<SourceRecord>>;
|
|
26
|
+
searchVenues(input: OpenStreetMapSearchInput): Promise<SearchResponse<ZuuidSearchResult>>;
|
|
27
|
+
}
|
|
28
|
+
export declare function fetchOpenStreetMapSourceRecord(provider: OpenStreetMapProvider, category: string, input: FetchOpenStreetMapInput): Promise<SourceRecord | undefined>;
|
|
29
|
+
export declare function searchOpenStreetMapSourceRecords(provider: OpenStreetMapProvider, category: string, input: OpenStreetMapSearchInput): Promise<SearchResponse<SourceRecord>>;
|
|
30
|
+
export declare function searchOpenStreetMap(provider: OpenStreetMapProvider, category: string, input: OpenStreetMapSearchInput): Promise<SearchResponse<ZuuidSearchResult>>;
|
|
31
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/providers/openstreetmap/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpF,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAaxE,OAAO,KAAK,EAAE,uBAAuB,EAA0B,4BAA4B,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAK1I,qBAAa,qBAAqB;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;gBAEvC,OAAO,GAAE,4BAAiC;IAOhD,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAYhF,qBAAqB,CAAC,KAAK,EAAE,uBAAuB;IACpD,SAAS,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IACzE,uBAAuB,CAAC,KAAK,EAAE,wBAAwB;IACvD,YAAY,CAAC,KAAK,EAAE,wBAAwB;IAE5C,wBAAwB,CAAC,KAAK,EAAE,uBAAuB;IACvD,YAAY,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAC5E,0BAA0B,CAAC,KAAK,EAAE,wBAAwB;IAC1D,eAAe,CAAC,KAAK,EAAE,wBAAwB;IAE/C,sBAAsB,CAAC,KAAK,EAAE,uBAAuB;IACrD,UAAU,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAC1E,wBAAwB,CAAC,KAAK,EAAE,wBAAwB;IACxD,YAAY,CAAC,KAAK,EAAE,wBAAwB;IAE5C,sBAAsB,CAAC,KAAK,EAAE,uBAAuB;IACrD,UAAU,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAC1E,wBAAwB,CAAC,KAAK,EAAE,wBAAwB;IACxD,YAAY,CAAC,KAAK,EAAE,wBAAwB;CACnD;AAED,wBAAsB,8BAA8B,CAAC,QAAQ,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAYzK;AAED,wBAAsB,gCAAgC,CAAC,QAAQ,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAOhL;AAED,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC,CAyBxK"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { providerZuuid } from "../../identity.js";
|
|
2
|
+
import { createSourceRecord } from "../../source.js";
|
|
3
|
+
import { nestedString, normalizeRating, objectPayload, stringField, valueAsString } from "../common.js";
|
|
4
|
+
import { OPENSTREETMAP_API_BASE, OPENSTREETMAP_CITY_CATEGORY, OPENSTREETMAP_COUNTRY_CATEGORY, OPENSTREETMAP_DEFAULT_USER_AGENT, OPENSTREETMAP_PLACE_CATEGORY, OPENSTREETMAP_PROVIDER, OPENSTREETMAP_VENUE_CATEGORY } from "./constants.js";
|
|
5
|
+
import { transformOpenStreetMapPlace } from "./place.js";
|
|
6
|
+
const CATEGORIES = [OPENSTREETMAP_CITY_CATEGORY, OPENSTREETMAP_COUNTRY_CATEGORY, OPENSTREETMAP_PLACE_CATEGORY, OPENSTREETMAP_VENUE_CATEGORY];
|
|
7
|
+
export class OpenStreetMapProvider {
|
|
8
|
+
apiBase;
|
|
9
|
+
userAgent;
|
|
10
|
+
language;
|
|
11
|
+
fetchImpl;
|
|
12
|
+
constructor(options = {}) {
|
|
13
|
+
this.apiBase = options.apiBase ?? OPENSTREETMAP_API_BASE;
|
|
14
|
+
this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
15
|
+
this.userAgent = options.userAgent ?? OPENSTREETMAP_DEFAULT_USER_AGENT;
|
|
16
|
+
this.language = options.language ?? "en-US,en;q=0.9";
|
|
17
|
+
}
|
|
18
|
+
async getJson(path, params) {
|
|
19
|
+
const url = new URL(`${this.apiBase.replace(/\/$/, "")}/${path.replace(/^\//, "")}`);
|
|
20
|
+
for (const [key, value] of Object.entries(params))
|
|
21
|
+
url.searchParams.set(key, value);
|
|
22
|
+
const response = await this.fetchImpl(url, { headers: { accept: "application/json", "accept-language": this.language, "user-agent": this.userAgent } });
|
|
23
|
+
if (response.status === 404)
|
|
24
|
+
return undefined;
|
|
25
|
+
if (!response.ok) {
|
|
26
|
+
const body = await response.text().catch(() => "");
|
|
27
|
+
throw new Error(`OpenStreetMap API returned ${response.status}: ${body}`);
|
|
28
|
+
}
|
|
29
|
+
return response.json();
|
|
30
|
+
}
|
|
31
|
+
async fetchCitySourceRecord(input) { return fetchOpenStreetMapSourceRecord(this, OPENSTREETMAP_CITY_CATEGORY, input); }
|
|
32
|
+
async fetchCity(input) { const source = await this.fetchCitySourceRecord(input); return source ? transformOpenStreetMapPlace(source) : undefined; }
|
|
33
|
+
async searchCitySourceRecords(input) { return searchOpenStreetMapSourceRecords(this, OPENSTREETMAP_CITY_CATEGORY, input); }
|
|
34
|
+
async searchCities(input) { return searchOpenStreetMap(this, OPENSTREETMAP_CITY_CATEGORY, input); }
|
|
35
|
+
async fetchCountrySourceRecord(input) { return fetchOpenStreetMapSourceRecord(this, OPENSTREETMAP_COUNTRY_CATEGORY, input); }
|
|
36
|
+
async fetchCountry(input) { const source = await this.fetchCountrySourceRecord(input); return source ? transformOpenStreetMapPlace(source) : undefined; }
|
|
37
|
+
async searchCountrySourceRecords(input) { return searchOpenStreetMapSourceRecords(this, OPENSTREETMAP_COUNTRY_CATEGORY, input); }
|
|
38
|
+
async searchCountries(input) { return searchOpenStreetMap(this, OPENSTREETMAP_COUNTRY_CATEGORY, input); }
|
|
39
|
+
async fetchPlaceSourceRecord(input) { return fetchOpenStreetMapSourceRecord(this, OPENSTREETMAP_PLACE_CATEGORY, input); }
|
|
40
|
+
async fetchPlace(input) { const source = await this.fetchPlaceSourceRecord(input); return source ? transformOpenStreetMapPlace(source) : undefined; }
|
|
41
|
+
async searchPlaceSourceRecords(input) { return searchOpenStreetMapSourceRecords(this, OPENSTREETMAP_PLACE_CATEGORY, input); }
|
|
42
|
+
async searchPlaces(input) { return searchOpenStreetMap(this, OPENSTREETMAP_PLACE_CATEGORY, input); }
|
|
43
|
+
async fetchVenueSourceRecord(input) { return fetchOpenStreetMapSourceRecord(this, OPENSTREETMAP_VENUE_CATEGORY, input); }
|
|
44
|
+
async fetchVenue(input) { const source = await this.fetchVenueSourceRecord(input); return source ? transformOpenStreetMapPlace(source) : undefined; }
|
|
45
|
+
async searchVenueSourceRecords(input) { return searchOpenStreetMapSourceRecords(this, OPENSTREETMAP_VENUE_CATEGORY, input); }
|
|
46
|
+
async searchVenues(input) { return searchOpenStreetMap(this, OPENSTREETMAP_VENUE_CATEGORY, input); }
|
|
47
|
+
}
|
|
48
|
+
export async function fetchOpenStreetMapSourceRecord(provider, category, input) {
|
|
49
|
+
const osmId = normalizeOsmId(input.id);
|
|
50
|
+
const payload = await provider.getJson("/lookup", {
|
|
51
|
+
osm_ids: osmId,
|
|
52
|
+
format: "jsonv2",
|
|
53
|
+
addressdetails: "1",
|
|
54
|
+
extratags: "1",
|
|
55
|
+
namedetails: "1"
|
|
56
|
+
});
|
|
57
|
+
const item = Array.isArray(payload) ? payload.find(isObject) : undefined;
|
|
58
|
+
if (!item)
|
|
59
|
+
return undefined;
|
|
60
|
+
return createSourceRecord({ source: { provider: OPENSTREETMAP_PROVIDER, category: requireCategory(category), externalId: osmId }, payload: item });
|
|
61
|
+
}
|
|
62
|
+
export async function searchOpenStreetMapSourceRecords(provider, category, input) {
|
|
63
|
+
const items = await searchPayload(provider, input);
|
|
64
|
+
const normalizedCategory = requireCategory(category);
|
|
65
|
+
return {
|
|
66
|
+
results: await Promise.all(items.map((item) => createSourceRecord({ source: { provider: OPENSTREETMAP_PROVIDER, category: normalizedCategory, externalId: osmExternalId(item) ?? valueAsString(item.place_id) ?? "" }, payload: item }))),
|
|
67
|
+
pagination: pagination(items, input.limit)
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export async function searchOpenStreetMap(provider, category, input) {
|
|
71
|
+
const items = await searchPayload(provider, input);
|
|
72
|
+
const normalizedCategory = requireCategory(category);
|
|
73
|
+
const results = [];
|
|
74
|
+
for (const item of items) {
|
|
75
|
+
const externalId = osmExternalId(item) ?? valueAsString(item.place_id);
|
|
76
|
+
const title = stringField(item, "name") ?? stringField(item, "display_name");
|
|
77
|
+
if (!externalId || !title)
|
|
78
|
+
continue;
|
|
79
|
+
const zuuid = await providerZuuid({ provider: OPENSTREETMAP_PROVIDER, category: normalizedCategory, externalId });
|
|
80
|
+
results.push({
|
|
81
|
+
id: zuuid,
|
|
82
|
+
zuuid,
|
|
83
|
+
category: normalizedCategory,
|
|
84
|
+
title,
|
|
85
|
+
date: null,
|
|
86
|
+
cover: stringField(item, "icon") ?? null,
|
|
87
|
+
rating: normalizeRating(typeof item.importance === "number" ? item.importance : undefined, 0, 1) ?? null,
|
|
88
|
+
weight: typeof item.importance === "number" ? item.importance : null,
|
|
89
|
+
relationType: null,
|
|
90
|
+
attribute: [stringField(item, "class"), stringField(item, "type")].filter(Boolean).join(":") || null,
|
|
91
|
+
order: null,
|
|
92
|
+
source: { source: OPENSTREETMAP_PROVIDER, category: normalizedCategory, value: externalId }
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return { results, pagination: pagination(items, input.limit) };
|
|
96
|
+
}
|
|
97
|
+
async function searchPayload(provider, input) {
|
|
98
|
+
const query = input.query.trim();
|
|
99
|
+
if (!query)
|
|
100
|
+
throw new Error("OpenStreetMap search query must not be empty");
|
|
101
|
+
const payload = await provider.getJson("/search", {
|
|
102
|
+
q: query,
|
|
103
|
+
format: "jsonv2",
|
|
104
|
+
addressdetails: "1",
|
|
105
|
+
extratags: "1",
|
|
106
|
+
namedetails: "1",
|
|
107
|
+
limit: String(input.limit ?? 10),
|
|
108
|
+
...(input.language ? { "accept-language": input.language } : {})
|
|
109
|
+
});
|
|
110
|
+
return Array.isArray(payload) ? payload.filter(isObject) : [];
|
|
111
|
+
}
|
|
112
|
+
function pagination(items, limit) {
|
|
113
|
+
const pageSize = limit ?? items.length;
|
|
114
|
+
return { page: 1, totalPages: pageSize > 0 && items.length > 0 ? 1 : 0, totalResults: items.length };
|
|
115
|
+
}
|
|
116
|
+
function normalizeOsmId(value) {
|
|
117
|
+
const raw = String(value).trim();
|
|
118
|
+
const prefixed = raw.match(/^([NWR])\s*(\d+)$/i);
|
|
119
|
+
if (prefixed)
|
|
120
|
+
return `${prefixed[1].toUpperCase()}${prefixed[2]}`;
|
|
121
|
+
const typed = raw.match(/^(node|way|relation)[-:\s]*(\d+)$/i);
|
|
122
|
+
if (typed)
|
|
123
|
+
return `${typePrefix(typed[1])}${typed[2]}`;
|
|
124
|
+
if (/^\d+$/.test(raw))
|
|
125
|
+
throw new Error(`OpenStreetMap id must include an OSM type prefix N, W, or R: ${value}`);
|
|
126
|
+
throw new Error(`Invalid OpenStreetMap id: ${value}`);
|
|
127
|
+
}
|
|
128
|
+
function typePrefix(value) {
|
|
129
|
+
const normalized = value.toLowerCase();
|
|
130
|
+
return normalized === "node" ? "N" : normalized === "way" ? "W" : "R";
|
|
131
|
+
}
|
|
132
|
+
function osmExternalId(payload) {
|
|
133
|
+
const osmType = stringField(payload, "osm_type");
|
|
134
|
+
const id = valueAsString(payload.osm_id);
|
|
135
|
+
if (!osmType || !id)
|
|
136
|
+
return undefined;
|
|
137
|
+
return `${typePrefix(osmType)}${id}`;
|
|
138
|
+
}
|
|
139
|
+
function requireCategory(category) {
|
|
140
|
+
if (CATEGORIES.includes(category))
|
|
141
|
+
return category;
|
|
142
|
+
throw new Error(`unsupported OpenStreetMap category: ${category}`);
|
|
143
|
+
}
|
|
144
|
+
function isObject(value) {
|
|
145
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
146
|
+
}
|
|
@@ -3,4 +3,6 @@ export declare const OPENSTREETMAP_CITY_CATEGORY = "city";
|
|
|
3
3
|
export declare const OPENSTREETMAP_COUNTRY_CATEGORY = "country";
|
|
4
4
|
export declare const OPENSTREETMAP_PLACE_CATEGORY = "place";
|
|
5
5
|
export declare const OPENSTREETMAP_VENUE_CATEGORY = "venue";
|
|
6
|
+
export declare const OPENSTREETMAP_API_BASE = "https://nominatim.openstreetmap.org";
|
|
7
|
+
export declare const OPENSTREETMAP_DEFAULT_USER_AGENT = "@zivue/zuuid OpenStreetMap client (+https://github.com/zivue/zuuid)";
|
|
6
8
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/providers/openstreetmap/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,kBAAkB,CAAC;AACtD,eAAO,MAAM,2BAA2B,SAAS,CAAC;AAClD,eAAO,MAAM,8BAA8B,YAAY,CAAC;AACxD,eAAO,MAAM,4BAA4B,UAAU,CAAC;AACpD,eAAO,MAAM,4BAA4B,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/providers/openstreetmap/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,kBAAkB,CAAC;AACtD,eAAO,MAAM,2BAA2B,SAAS,CAAC;AAClD,eAAO,MAAM,8BAA8B,YAAY,CAAC;AACxD,eAAO,MAAM,4BAA4B,UAAU,CAAC;AACpD,eAAO,MAAM,4BAA4B,UAAU,CAAC;AACpD,eAAO,MAAM,sBAAsB,wCAAwC,CAAC;AAC5E,eAAO,MAAM,gCAAgC,wEAAwE,CAAC"}
|
|
@@ -3,3 +3,5 @@ export const OPENSTREETMAP_CITY_CATEGORY = "city";
|
|
|
3
3
|
export const OPENSTREETMAP_COUNTRY_CATEGORY = "country";
|
|
4
4
|
export const OPENSTREETMAP_PLACE_CATEGORY = "place";
|
|
5
5
|
export const OPENSTREETMAP_VENUE_CATEGORY = "venue";
|
|
6
|
+
export const OPENSTREETMAP_API_BASE = "https://nominatim.openstreetmap.org";
|
|
7
|
+
export const OPENSTREETMAP_DEFAULT_USER_AGENT = "@zivue/zuuid OpenStreetMap client (+https://github.com/zivue/zuuid)";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"country.d.ts","sourceRoot":"","sources":["../../../src/providers/openstreetmap/country.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,IAAI,6BAA6B,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { transformOpenStreetMapPlace as transformOpenStreetMapCountry } from "./place.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/openstreetmap/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/openstreetmap/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type OpenStreetMapFetchLike = (input: string | URL, init?: RequestInit) => Promise<Response>;
|
|
2
|
+
export type OpenStreetMapProviderOptions = {
|
|
3
|
+
apiBase?: string;
|
|
4
|
+
fetch?: OpenStreetMapFetchLike;
|
|
5
|
+
userAgent?: string;
|
|
6
|
+
language?: string;
|
|
7
|
+
};
|
|
8
|
+
export type FetchOpenStreetMapInput = {
|
|
9
|
+
id: string | number;
|
|
10
|
+
};
|
|
11
|
+
export type OpenStreetMapSearchInput = {
|
|
12
|
+
query: string;
|
|
13
|
+
limit?: number;
|
|
14
|
+
language?: string;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/providers/openstreetmap/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,sBAAsB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEpG,MAAM,MAAM,4BAA4B,GAAG;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,sBAAsB,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zivue/zuuid",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "TypeScript helpers for fetching, searching, and transforming Zuuid datasets.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -56,6 +56,10 @@
|
|
|
56
56
|
"types": "./dist/providers/comicvine/transform.d.ts",
|
|
57
57
|
"import": "./dist/providers/comicvine/transform.js"
|
|
58
58
|
},
|
|
59
|
+
"./providers/comicvine/client": {
|
|
60
|
+
"types": "./dist/providers/comicvine/client.d.ts",
|
|
61
|
+
"import": "./dist/providers/comicvine/client.js"
|
|
62
|
+
},
|
|
59
63
|
"./providers/comicvine/volume": {
|
|
60
64
|
"types": "./dist/providers/comicvine/volume.d.ts",
|
|
61
65
|
"import": "./dist/providers/comicvine/volume.js"
|
|
@@ -164,10 +168,22 @@
|
|
|
164
168
|
"types": "./dist/providers/openstreetmap/index.d.ts",
|
|
165
169
|
"import": "./dist/providers/openstreetmap/index.js"
|
|
166
170
|
},
|
|
171
|
+
"./providers/openstreetmap/client": {
|
|
172
|
+
"types": "./dist/providers/openstreetmap/client.d.ts",
|
|
173
|
+
"import": "./dist/providers/openstreetmap/client.js"
|
|
174
|
+
},
|
|
167
175
|
"./providers/openstreetmap/place": {
|
|
168
176
|
"types": "./dist/providers/openstreetmap/place.d.ts",
|
|
169
177
|
"import": "./dist/providers/openstreetmap/place.js"
|
|
170
178
|
},
|
|
179
|
+
"./providers/openstreetmap/city": {
|
|
180
|
+
"types": "./dist/providers/openstreetmap/city.d.ts",
|
|
181
|
+
"import": "./dist/providers/openstreetmap/city.js"
|
|
182
|
+
},
|
|
183
|
+
"./providers/openstreetmap/country": {
|
|
184
|
+
"types": "./dist/providers/openstreetmap/country.d.ts",
|
|
185
|
+
"import": "./dist/providers/openstreetmap/country.js"
|
|
186
|
+
},
|
|
171
187
|
"./providers/openstreetmap/venue": {
|
|
172
188
|
"types": "./dist/providers/openstreetmap/venue.d.ts",
|
|
173
189
|
"import": "./dist/providers/openstreetmap/venue.js"
|