@zivue/zuuid 0.1.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 +10 -0
- package/LICENSE +21 -0
- package/README.md +368 -0
- package/dist/client.d.ts +29 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +39 -0
- package/dist/entity.d.ts +106 -0
- package/dist/entity.d.ts.map +1 -0
- package/dist/entity.js +101 -0
- package/dist/hash.d.ts +3 -0
- package/dist/hash.d.ts.map +1 -0
- package/dist/hash.js +9 -0
- package/dist/identity.d.ts +14 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +39 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/providers/tmdb/client.d.ts +30 -0
- package/dist/providers/tmdb/client.d.ts.map +1 -0
- package/dist/providers/tmdb/client.js +92 -0
- package/dist/providers/tmdb/constants.d.ts +5 -0
- package/dist/providers/tmdb/constants.d.ts.map +1 -0
- package/dist/providers/tmdb/constants.js +4 -0
- package/dist/providers/tmdb/index.d.ts +7 -0
- package/dist/providers/tmdb/index.d.ts.map +1 -0
- package/dist/providers/tmdb/index.js +6 -0
- package/dist/providers/tmdb/movie.d.ts +164 -0
- package/dist/providers/tmdb/movie.d.ts.map +1 -0
- package/dist/providers/tmdb/movie.js +537 -0
- package/dist/providers/tmdb/person.d.ts +84 -0
- package/dist/providers/tmdb/person.d.ts.map +1 -0
- package/dist/providers/tmdb/person.js +345 -0
- package/dist/providers/tmdb/tv.d.ts +181 -0
- package/dist/providers/tmdb/tv.d.ts.map +1 -0
- package/dist/providers/tmdb/tv.js +522 -0
- package/dist/providers/tmdb/types.d.ts +36 -0
- package/dist/providers/tmdb/types.d.ts.map +1 -0
- package/dist/providers/tmdb/types.js +1 -0
- package/dist/source.d.ts +35 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/source.js +53 -0
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/uuid.d.ts +3 -0
- package/dist/uuid.d.ts.map +1 -0
- package/dist/uuid.js +32 -0
- package/package.json +72 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
- Added provider-stable ZUUID generation using UUID v5.
|
|
6
|
+
- Added flat `ZuuidData` model with source metadata and provenance.
|
|
7
|
+
- Added shared lightweight list item shape for search results, relations, and recommendations.
|
|
8
|
+
- Added TMDB provider support for movies, TV shows, and people.
|
|
9
|
+
- Added TMDB fetch, raw source-record fetch, transform, unified search, and raw search APIs.
|
|
10
|
+
- Added TMDB fetch and search CLI examples for local testing.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Zivue
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
# @zivue/zuuid
|
|
2
|
+
|
|
3
|
+
TypeScript helpers for fetching, searching, and transforming Zuuid datasets.
|
|
4
|
+
|
|
5
|
+
Zuuid is the metadata, search, and indexing substrate for Zivue/Stareto. This package focuses on the client-side model: provider-stable UUIDs, source records, and normalized Zuuid datasets.
|
|
6
|
+
|
|
7
|
+
Storage, caching, object keys, and persistence belong in a layer outside this package.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install @zivue/zuuid
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { createZuuidClient } from "@zivue/zuuid";
|
|
19
|
+
|
|
20
|
+
const zuuid = createZuuidClient({
|
|
21
|
+
providers: {
|
|
22
|
+
tmdb: {
|
|
23
|
+
bearerToken: process.env.TMDB_BEARER_TOKEN!
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const search = await zuuid.movie.tmdb?.search({ query: "Fight Club" });
|
|
29
|
+
const selected = search?.results[0];
|
|
30
|
+
const movie = selected ? await zuuid.movie.tmdb?.fetch({ id: selected.source.value }) : undefined;
|
|
31
|
+
|
|
32
|
+
console.log(movie?.zuuid);
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Generate A ZUUID
|
|
36
|
+
|
|
37
|
+
Zuuid generation is UUID v5:
|
|
38
|
+
|
|
39
|
+
```txt
|
|
40
|
+
uuid_v5(provider_namespace, "<normalized-category>:<external_id>")
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import { providerZuuid } from "@zivue/zuuid";
|
|
45
|
+
|
|
46
|
+
const zuuid = await providerZuuid({
|
|
47
|
+
provider: "tmdb",
|
|
48
|
+
category: "movie",
|
|
49
|
+
externalId: "550"
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
console.log(zuuid);
|
|
53
|
+
// 1706d641-d381-5618-9425-d8cd8b35f898
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`category` is trimmed and lowercased. `externalId` is trimmed but otherwise preserved.
|
|
57
|
+
|
|
58
|
+
## Zuuid Dataset
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { createZuuidData } from "@zivue/zuuid";
|
|
62
|
+
|
|
63
|
+
const dataset = createZuuidData({
|
|
64
|
+
zuuid: "1706d641-d381-5618-9425-d8cd8b35f898",
|
|
65
|
+
category: "movie",
|
|
66
|
+
primaryTitle: "Fight Club"
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The dataset shape is intentionally flat:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
type ZuuidData = {
|
|
74
|
+
zuuid: string;
|
|
75
|
+
kind: EntityKind;
|
|
76
|
+
category: string;
|
|
77
|
+
primaryTitle: string;
|
|
78
|
+
primaryDate?: string;
|
|
79
|
+
rating?: number;
|
|
80
|
+
cover?: string;
|
|
81
|
+
aliases: Alias[];
|
|
82
|
+
descriptions: Description[];
|
|
83
|
+
details: Detail[];
|
|
84
|
+
media: MediaAsset[];
|
|
85
|
+
relations: EntityRelation[];
|
|
86
|
+
recommendations: RecommendationEdge[];
|
|
87
|
+
tags: string[];
|
|
88
|
+
externalIds: ExternalId[];
|
|
89
|
+
provenance: Provenance[];
|
|
90
|
+
};
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Search results, relations, and recommendations use the same lightweight list item fields: `id`, `zuuid`, `category`, `title`, `date`, `cover`, `rating`, `weight`, `relationType`, `attribute`, and `order`. That lets transformed datasets and search results carry useful related-entity context before those related entities are fetched as full Zuuid datasets.
|
|
94
|
+
|
|
95
|
+
Backend-only concerns such as record versions, flags, review state, index state, and object-store metadata are intentionally not part of this package's dataset shape.
|
|
96
|
+
|
|
97
|
+
## Source Metadata
|
|
98
|
+
|
|
99
|
+
Source records are provider records before they are transformed into canonical entities. They carry the external provider key, raw JSON payload, content hash, and observation timestamps.
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
import { attachSourceMetadata, createSourceRecord } from "@zivue/zuuid";
|
|
103
|
+
|
|
104
|
+
const source = await createSourceRecord({
|
|
105
|
+
source: { provider: "tmdb", category: "movie", externalId: "550" },
|
|
106
|
+
payload: { title: "Fight Club" },
|
|
107
|
+
observedAt: "2026-05-21T00:00:00.000Z"
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const withSource = attachSourceMetadata(dataset, source);
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`attachSourceMetadata` returns a new dataset with `externalIds` and `provenance` updated.
|
|
114
|
+
|
|
115
|
+
## TMDB Movies, TV, And People
|
|
116
|
+
|
|
117
|
+
The first provider module supports fetching and transforming TMDB movies, TV shows, and people.
|
|
118
|
+
|
|
119
|
+
| Provider | Category | Search | Fetch | Transform |
|
|
120
|
+
| --- | --- | --- | --- | --- |
|
|
121
|
+
| TMDB | movie | yes | yes | yes |
|
|
122
|
+
| TMDB | tv | yes | yes | yes |
|
|
123
|
+
| TMDB | person | yes | yes | yes |
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { TmdbProvider } from "@zivue/zuuid/providers/tmdb";
|
|
127
|
+
|
|
128
|
+
const tmdb = new TmdbProvider({
|
|
129
|
+
bearerToken: process.env.TMDB_BEARER_TOKEN!
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const movie = await tmdb.fetchMovie({ id: 550 });
|
|
133
|
+
const tv = await tmdb.fetchTv({ id: 1399 });
|
|
134
|
+
const person = await tmdb.fetchPerson({ id: 287 });
|
|
135
|
+
|
|
136
|
+
console.log(movie?.zuuid);
|
|
137
|
+
// 1706d641-d381-5618-9425-d8cd8b35f898
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
You can also split fetching from transformation:
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
import { TmdbProvider, transformTmdbMovie, transformTmdbPerson, transformTmdbTv } from "@zivue/zuuid/providers/tmdb";
|
|
144
|
+
|
|
145
|
+
const source = await tmdb.fetchMovieSourceRecord({ id: 550 });
|
|
146
|
+
const movie = source ? await transformTmdbMovie(source) : undefined;
|
|
147
|
+
|
|
148
|
+
const tvSource = await tmdb.fetchTvSourceRecord({ id: 1399 });
|
|
149
|
+
const tv = tvSource ? await transformTmdbTv(tvSource) : undefined;
|
|
150
|
+
|
|
151
|
+
const personSource = await tmdb.fetchPersonSourceRecord({ id: 287 });
|
|
152
|
+
const person = personSource ? await transformTmdbPerson(personSource) : undefined;
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Search returns unified lightweight candidates. Use search to find candidate IDs, then fetch the selected item for the full transformed dataset:
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
const movies = await tmdb.searchMovies({ query: "Fight Club" });
|
|
159
|
+
const tvShows = await tmdb.searchTv({ query: "Game of Thrones" });
|
|
160
|
+
const people = await tmdb.searchPeople({ query: "Brad Pitt" });
|
|
161
|
+
|
|
162
|
+
console.log(movies.pagination);
|
|
163
|
+
// { page: 1, totalPages: 10, totalResults: 190 }
|
|
164
|
+
|
|
165
|
+
const selectedMovie = movies.results[0];
|
|
166
|
+
console.log(selectedMovie);
|
|
167
|
+
// {
|
|
168
|
+
// id: "1706d641-d381-5618-9425-d8cd8b35f898",
|
|
169
|
+
// zuuid: "1706d641-d381-5618-9425-d8cd8b35f898",
|
|
170
|
+
// category: "movie",
|
|
171
|
+
// title: "Fight Club",
|
|
172
|
+
// date: "1999-10-15",
|
|
173
|
+
// cover: "https://image.tmdb.org/t/p/w500/...",
|
|
174
|
+
// rating: 8.4,
|
|
175
|
+
// weight: 20.0,
|
|
176
|
+
// relationType: null,
|
|
177
|
+
// attribute: null,
|
|
178
|
+
// order: null,
|
|
179
|
+
// source: { source: "tmdb", category: "movie", value: "550" }
|
|
180
|
+
// }
|
|
181
|
+
|
|
182
|
+
const fullMovie = selectedMovie ? await tmdb.fetchMovie({ id: selectedMovie.source.value }) : undefined;
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Raw search source records are also available:
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
const rawMovies = await tmdb.searchMovieSourceRecords({ query: "Fight Club" });
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Category-specific imports are also available:
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
import { transformTmdbMovie } from "@zivue/zuuid/providers/tmdb/movie";
|
|
195
|
+
import { transformTmdbTv } from "@zivue/zuuid/providers/tmdb/tv";
|
|
196
|
+
import { transformTmdbPerson } from "@zivue/zuuid/providers/tmdb/person";
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
`TmdbProvider` accepts either `{ bearerToken }` or `{ apiKey }`. TMDB bearer tokens are API Read Access Tokens and usually start with `eyJ...`; v3 API keys are shorter hex-like strings.
|
|
200
|
+
|
|
201
|
+
## Client Instantiation
|
|
202
|
+
|
|
203
|
+
For applications with multiple providers, use `createZuuidClient` to wire provider config once:
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
import { createZuuidClient } from "@zivue/zuuid";
|
|
207
|
+
|
|
208
|
+
const zuuid = createZuuidClient({
|
|
209
|
+
providers: {
|
|
210
|
+
tmdb: {
|
|
211
|
+
bearerToken: process.env.TMDB_BEARER_TOKEN!
|
|
212
|
+
}
|
|
213
|
+
// Future movie providers can sit beside tmdb, e.g. omdb.
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
const movie = await zuuid.movie.tmdb?.fetch({ id: 550 });
|
|
218
|
+
const tv = await zuuid.tv.tmdb?.fetch({ id: 1399 });
|
|
219
|
+
const person = await zuuid.people.tmdb?.fetch({ id: 287 });
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
The config is provider-keyed because apps usually manage credentials per provider. The client facade is category-first, so multiple movie providers can live under `zuuid.movie`:
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
zuuid.movie.tmdb?.fetch({ id: 550 });
|
|
226
|
+
zuuid.tv.tmdb?.fetch({ id: 1399 });
|
|
227
|
+
zuuid.people.tmdb?.fetch({ id: 287 });
|
|
228
|
+
|
|
229
|
+
zuuid.movie.tmdb?.search({ query: "Fight Club" });
|
|
230
|
+
zuuid.tv.tmdb?.search({ query: "Game of Thrones" });
|
|
231
|
+
zuuid.people.tmdb?.search({ query: "Brad Pitt" });
|
|
232
|
+
// later: zuuid.movie.omdb?.fetch(...)
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
The client is stateless: it does not cache, persist, schedule, or read environment variables. It only closes over provider configuration and exposes category/provider methods.
|
|
236
|
+
|
|
237
|
+
## API
|
|
238
|
+
|
|
239
|
+
## Package Structure
|
|
240
|
+
|
|
241
|
+
The source is split by Zuuid responsibility:
|
|
242
|
+
|
|
243
|
+
- `identity.ts`: provider namespaces and UUID v5 ZUUID generation
|
|
244
|
+
- `entity.ts`: flat Zuuid data types and category helpers
|
|
245
|
+
- `client.ts`: stateless package instantiator for configured providers
|
|
246
|
+
- `providers/<provider>/index.ts`: provider module barrel
|
|
247
|
+
- `providers/<provider>/client.ts`: shared provider client/config
|
|
248
|
+
- `providers/<provider>/<category>.ts`: category-specific fetch and transform helpers
|
|
249
|
+
- `providers/tmdb/movie.ts`: TMDB movie fetch and transform helpers
|
|
250
|
+
- `providers/tmdb/tv.ts`: TMDB TV fetch and transform helpers
|
|
251
|
+
- `providers/tmdb/person.ts`: TMDB person fetch and transform helpers
|
|
252
|
+
- `source.ts`: source records, external IDs, and provenance
|
|
253
|
+
- `hash.ts`: stable payload hashing
|
|
254
|
+
- `uuid.ts`: UUID parsing/normalization and UUID v5 internals
|
|
255
|
+
- `types.ts`: shared JSON value types
|
|
256
|
+
- `index.ts`: public barrel exports
|
|
257
|
+
|
|
258
|
+
### `providerZuuid(input)`
|
|
259
|
+
|
|
260
|
+
Generates a deterministic ZUUID for a provider/category/external ID.
|
|
261
|
+
|
|
262
|
+
### `providerNamespace(provider)`
|
|
263
|
+
|
|
264
|
+
Returns the UUID namespace configured for a known provider.
|
|
265
|
+
|
|
266
|
+
### `createZuuidData(input)`
|
|
267
|
+
|
|
268
|
+
Creates a normalized Zuuid dataset.
|
|
269
|
+
|
|
270
|
+
### `createSourceRecord(input)`
|
|
271
|
+
|
|
272
|
+
Creates a source record and computes the SHA-256 payload hash used for provenance.
|
|
273
|
+
|
|
274
|
+
### `attachSourceMetadata(dataset, sourceRecord, confidence?)`
|
|
275
|
+
|
|
276
|
+
Returns a new dataset with external ID and provenance attached.
|
|
277
|
+
|
|
278
|
+
### `TmdbProvider`
|
|
279
|
+
|
|
280
|
+
Fetches TMDB source records and transforms them into `ZuuidData`.
|
|
281
|
+
|
|
282
|
+
### `transformTmdbMovie(sourceRecord, options?)`
|
|
283
|
+
|
|
284
|
+
Transforms an already-fetched TMDB movie source record into `ZuuidData`.
|
|
285
|
+
|
|
286
|
+
### `transformTmdbTv(sourceRecord, options?)`
|
|
287
|
+
|
|
288
|
+
Transforms an already-fetched TMDB TV source record into `ZuuidData`.
|
|
289
|
+
|
|
290
|
+
### `transformTmdbPerson(sourceRecord, options?)`
|
|
291
|
+
|
|
292
|
+
Transforms an already-fetched TMDB person source record into `ZuuidData`.
|
|
293
|
+
|
|
294
|
+
### `categoryFor(value)`
|
|
295
|
+
|
|
296
|
+
Normalizes a category and derives its entity kind.
|
|
297
|
+
|
|
298
|
+
### `kindForCategory(category)`
|
|
299
|
+
|
|
300
|
+
Maps categories such as `movie`, `book`, `game`, `restaurant`, and `person` to broad kinds such as `watch`, `read`, `play`, `visit`, and `people`.
|
|
301
|
+
|
|
302
|
+
## Development
|
|
303
|
+
|
|
304
|
+
```sh
|
|
305
|
+
npm install
|
|
306
|
+
npm test
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
## Try It
|
|
310
|
+
|
|
311
|
+
Fetch and transform TMDB movie `550`:
|
|
312
|
+
|
|
313
|
+
```sh
|
|
314
|
+
TMDB_BEARER_TOKEN=... npm run example:tmdb-fetch -- movie 550
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
or:
|
|
318
|
+
|
|
319
|
+
```sh
|
|
320
|
+
TMDB_API_KEY=... npm run example:tmdb-fetch -- movie 550
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Fetch and transform TMDB TV show `1399`:
|
|
324
|
+
|
|
325
|
+
```sh
|
|
326
|
+
TMDB_BEARER_TOKEN=... npm run example:tmdb-fetch -- tv 1399
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Fetch and transform TMDB person `287`:
|
|
330
|
+
|
|
331
|
+
```sh
|
|
332
|
+
TMDB_BEARER_TOKEN=... npm run example:tmdb-fetch -- people 287
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
Search TMDB and print unified search results:
|
|
336
|
+
|
|
337
|
+
```sh
|
|
338
|
+
npm run example:tmdb-search -- movie "Fight Club"
|
|
339
|
+
npm run example:tmdb-search -- tv "Game of Thrones"
|
|
340
|
+
npm run example:tmdb-search -- people "Brad Pitt"
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
The example also reads `.env` from the repo root:
|
|
344
|
+
|
|
345
|
+
```sh
|
|
346
|
+
TMDB_BEARER_TOKEN=...
|
|
347
|
+
# or
|
|
348
|
+
TMDB_READ_ACCESS_TOKEN=...
|
|
349
|
+
# or
|
|
350
|
+
TMDB_API_KEY=...
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
If both token and API key are present, the example uses the bearer token first. TMDB's API Read Access Token usually starts with `eyJ...`; the v3 API key is a shorter hex-like string.
|
|
354
|
+
|
|
355
|
+
If `TMDB_API_KEY` accidentally contains a token starting with `eyJ`, the example treats it as a bearer token and sends it as `Authorization: Bearer ...`.
|
|
356
|
+
|
|
357
|
+
The example writes debug output to:
|
|
358
|
+
|
|
359
|
+
```txt
|
|
360
|
+
data/tmdb/movie/550.raw.json
|
|
361
|
+
data/tmdb/movie/550.zuuid.json
|
|
362
|
+
data/tmdb/tv/1399.raw.json
|
|
363
|
+
data/tmdb/tv/1399.zuuid.json
|
|
364
|
+
data/tmdb/people/287.raw.json
|
|
365
|
+
data/tmdb/people/287.zuuid.json
|
|
366
|
+
data/tmdb/search/movie/fight-club.zuuid-search.json
|
|
367
|
+
data/tmdb/search/movie/fight-club.raw-search.json
|
|
368
|
+
```
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { SearchResponse, ZuuidData, ZuuidSearchResult } from "./entity.js";
|
|
2
|
+
import { type FetchTmdbMovieInput, type FetchTmdbPersonInput, type FetchTmdbTvInput, type TmdbProviderOptions, type TmdbSearchInput } from "./providers/tmdb/index.js";
|
|
3
|
+
import type { SourceRecord } from "./source.js";
|
|
4
|
+
export type ProviderConfigs = {
|
|
5
|
+
tmdb?: TmdbProviderOptions;
|
|
6
|
+
};
|
|
7
|
+
export type ZuuidClientConfig = {
|
|
8
|
+
providers?: ProviderConfigs;
|
|
9
|
+
};
|
|
10
|
+
export type MovieProviderClient<TFetchInput> = {
|
|
11
|
+
fetch(input: TFetchInput): Promise<ZuuidData | undefined>;
|
|
12
|
+
fetchSourceRecord(input: TFetchInput): Promise<SourceRecord | undefined>;
|
|
13
|
+
search(input: TmdbSearchInput): Promise<SearchResponse<ZuuidSearchResult>>;
|
|
14
|
+
searchSourceRecords(input: TmdbSearchInput): Promise<SearchResponse<SourceRecord>>;
|
|
15
|
+
transform(source: SourceRecord): Promise<ZuuidData>;
|
|
16
|
+
};
|
|
17
|
+
export type ZuuidClient = {
|
|
18
|
+
movie: {
|
|
19
|
+
tmdb?: MovieProviderClient<FetchTmdbMovieInput>;
|
|
20
|
+
};
|
|
21
|
+
tv: {
|
|
22
|
+
tmdb?: MovieProviderClient<FetchTmdbTvInput>;
|
|
23
|
+
};
|
|
24
|
+
people: {
|
|
25
|
+
tmdb?: MovieProviderClient<FetchTmdbPersonInput>;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
export declare function createZuuidClient(config?: ZuuidClientConfig): ZuuidClient;
|
|
29
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,EAKL,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,CAAC,EAAE,mBAAmB,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,mBAAmB,CAAC,WAAW,IAAI;IAC7C,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAC1D,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;IACzE,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC3E,mBAAmB,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;IACnF,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE;QACL,IAAI,CAAC,EAAE,mBAAmB,CAAC,mBAAmB,CAAC,CAAC;KACjD,CAAC;IACF,EAAE,EAAE;QACF,IAAI,CAAC,EAAE,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;KAC9C,CAAC;IACF,MAAM,EAAE;QACN,IAAI,CAAC,EAAE,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;KAClD,CAAC;CACH,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,iBAAsB,GAAG,WAAW,CAsC7E"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { TmdbProvider, transformTmdbMovie, transformTmdbPerson, transformTmdbTv } from "./providers/tmdb/index.js";
|
|
2
|
+
export function createZuuidClient(config = {}) {
|
|
3
|
+
const tmdb = config.providers?.tmdb ? new TmdbProvider(config.providers.tmdb) : undefined;
|
|
4
|
+
return Object.freeze({
|
|
5
|
+
movie: Object.freeze({
|
|
6
|
+
tmdb: tmdb
|
|
7
|
+
? Object.freeze({
|
|
8
|
+
fetch: (input) => tmdb.fetchMovie(input),
|
|
9
|
+
fetchSourceRecord: (input) => tmdb.fetchMovieSourceRecord(input),
|
|
10
|
+
search: (input) => tmdb.searchMovies(input),
|
|
11
|
+
searchSourceRecords: (input) => tmdb.searchMovieSourceRecords(input),
|
|
12
|
+
transform: (source) => transformTmdbMovie(source, tmdb.transformOptions())
|
|
13
|
+
})
|
|
14
|
+
: undefined
|
|
15
|
+
}),
|
|
16
|
+
tv: Object.freeze({
|
|
17
|
+
tmdb: tmdb
|
|
18
|
+
? Object.freeze({
|
|
19
|
+
fetch: (input) => tmdb.fetchTv(input),
|
|
20
|
+
fetchSourceRecord: (input) => tmdb.fetchTvSourceRecord(input),
|
|
21
|
+
search: (input) => tmdb.searchTv(input),
|
|
22
|
+
searchSourceRecords: (input) => tmdb.searchTvSourceRecords(input),
|
|
23
|
+
transform: (source) => transformTmdbTv(source, tmdb.transformOptions())
|
|
24
|
+
})
|
|
25
|
+
: undefined
|
|
26
|
+
}),
|
|
27
|
+
people: Object.freeze({
|
|
28
|
+
tmdb: tmdb
|
|
29
|
+
? Object.freeze({
|
|
30
|
+
fetch: (input) => tmdb.fetchPerson(input),
|
|
31
|
+
fetchSourceRecord: (input) => tmdb.fetchPersonSourceRecord(input),
|
|
32
|
+
search: (input) => tmdb.searchPeople(input),
|
|
33
|
+
searchSourceRecords: (input) => tmdb.searchPersonSourceRecords(input),
|
|
34
|
+
transform: (source) => transformTmdbPerson(source, tmdb.transformOptions())
|
|
35
|
+
})
|
|
36
|
+
: undefined
|
|
37
|
+
})
|
|
38
|
+
});
|
|
39
|
+
}
|
package/dist/entity.d.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { ExternalId, Provenance } from "./source.js";
|
|
2
|
+
import type { JsonValue } from "./types.js";
|
|
3
|
+
export type EntityKind = "event" | "listen" | "people" | "play" | "read" | "visit" | "watch" | string;
|
|
4
|
+
export type CategoryInfo = {
|
|
5
|
+
category: string;
|
|
6
|
+
kind: EntityKind;
|
|
7
|
+
};
|
|
8
|
+
export type Alias = {
|
|
9
|
+
value: string;
|
|
10
|
+
language?: string;
|
|
11
|
+
region?: string;
|
|
12
|
+
aliasType: string;
|
|
13
|
+
isPrimary: boolean;
|
|
14
|
+
source?: string;
|
|
15
|
+
};
|
|
16
|
+
export type Description = {
|
|
17
|
+
language?: string;
|
|
18
|
+
region?: string;
|
|
19
|
+
value: string;
|
|
20
|
+
source?: string;
|
|
21
|
+
};
|
|
22
|
+
export type Detail = {
|
|
23
|
+
key: string;
|
|
24
|
+
value: JsonValue;
|
|
25
|
+
source?: string;
|
|
26
|
+
};
|
|
27
|
+
export type MediaAsset = {
|
|
28
|
+
url: string;
|
|
29
|
+
mediaType: string;
|
|
30
|
+
mediaCategory: string;
|
|
31
|
+
width?: number;
|
|
32
|
+
height?: number;
|
|
33
|
+
isPrimary: boolean;
|
|
34
|
+
data?: JsonValue;
|
|
35
|
+
source?: string;
|
|
36
|
+
};
|
|
37
|
+
export type RelationKind = "appears_in" | "authored_by" | "based_on" | "contains" | "duplicate_of" | "mentions" | "part_of" | "performed_by" | "published_by" | "related_to" | "same_as" | "source_of" | string;
|
|
38
|
+
export type RecommendationKind = "similar" | "related" | "same_creator" | "same_series" | "same_topic" | string;
|
|
39
|
+
export type ZuuidData = {
|
|
40
|
+
zuuid: string;
|
|
41
|
+
kind: EntityKind;
|
|
42
|
+
category: string;
|
|
43
|
+
primaryTitle: string;
|
|
44
|
+
primaryDate?: string;
|
|
45
|
+
rating?: number;
|
|
46
|
+
cover?: string;
|
|
47
|
+
aliases: Alias[];
|
|
48
|
+
descriptions: Description[];
|
|
49
|
+
details: Detail[];
|
|
50
|
+
media: MediaAsset[];
|
|
51
|
+
relations: EntityRelation[];
|
|
52
|
+
recommendations: RecommendationEdge[];
|
|
53
|
+
tags: string[];
|
|
54
|
+
externalIds: ExternalId[];
|
|
55
|
+
provenance: Provenance[];
|
|
56
|
+
};
|
|
57
|
+
export type ZuuidListItem = {
|
|
58
|
+
id: string;
|
|
59
|
+
zuuid: string;
|
|
60
|
+
category: string;
|
|
61
|
+
title: string;
|
|
62
|
+
date: string | null;
|
|
63
|
+
cover: string | null;
|
|
64
|
+
rating: number | null;
|
|
65
|
+
weight: number | null;
|
|
66
|
+
relationType: string | null;
|
|
67
|
+
attribute: string | null;
|
|
68
|
+
order: number | null;
|
|
69
|
+
};
|
|
70
|
+
export type EntityRelation = ZuuidListItem & {
|
|
71
|
+
relationType: RelationKind;
|
|
72
|
+
direction: "outgoing" | "incoming" | "symmetric";
|
|
73
|
+
source?: string;
|
|
74
|
+
externalId?: string;
|
|
75
|
+
confidence?: number;
|
|
76
|
+
data?: JsonValue;
|
|
77
|
+
};
|
|
78
|
+
export type RecommendationEdge = ZuuidListItem & {
|
|
79
|
+
recommendationType: RecommendationKind;
|
|
80
|
+
relationType: RecommendationKind;
|
|
81
|
+
source?: string;
|
|
82
|
+
externalId?: string;
|
|
83
|
+
reasons: string[];
|
|
84
|
+
};
|
|
85
|
+
export type ZuuidSearchResult = ZuuidListItem & {
|
|
86
|
+
source: ExternalId;
|
|
87
|
+
};
|
|
88
|
+
export type SearchPagination = {
|
|
89
|
+
page: number;
|
|
90
|
+
totalPages: number;
|
|
91
|
+
totalResults: number;
|
|
92
|
+
};
|
|
93
|
+
export type SearchResponse<T> = {
|
|
94
|
+
results: T[];
|
|
95
|
+
pagination: SearchPagination;
|
|
96
|
+
};
|
|
97
|
+
export type CreateZuuidDataInput = {
|
|
98
|
+
zuuid: string;
|
|
99
|
+
category: string;
|
|
100
|
+
primaryTitle: string;
|
|
101
|
+
};
|
|
102
|
+
export declare function createZuuidData(input: CreateZuuidDataInput): ZuuidData;
|
|
103
|
+
export declare function createZuuidDataFromParts(zuuid: string, category: CategoryInfo, primaryTitle: string): ZuuidData;
|
|
104
|
+
export declare function categoryFor(value: string): CategoryInfo;
|
|
105
|
+
export declare function kindForCategory(category: string): EntityKind;
|
|
106
|
+
//# sourceMappingURL=entity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../src/entity.ts"],"names":[],"mappings":"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"}
|
package/dist/entity.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { normalizeUuid } from "./uuid.js";
|
|
2
|
+
export function createZuuidData(input) {
|
|
3
|
+
const zuuid = normalizeUuid(input.zuuid);
|
|
4
|
+
const category = categoryFor(input.category);
|
|
5
|
+
return createZuuidDataFromParts(zuuid, category, input.primaryTitle);
|
|
6
|
+
}
|
|
7
|
+
export function createZuuidDataFromParts(zuuid, category, primaryTitle) {
|
|
8
|
+
return {
|
|
9
|
+
zuuid: normalizeUuid(zuuid),
|
|
10
|
+
kind: category.kind,
|
|
11
|
+
category: category.category,
|
|
12
|
+
primaryTitle,
|
|
13
|
+
aliases: [],
|
|
14
|
+
descriptions: [],
|
|
15
|
+
details: [],
|
|
16
|
+
media: [],
|
|
17
|
+
relations: [],
|
|
18
|
+
recommendations: [],
|
|
19
|
+
tags: [],
|
|
20
|
+
externalIds: [],
|
|
21
|
+
provenance: []
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export function categoryFor(value) {
|
|
25
|
+
const normalized = normalizeKeyPart(value);
|
|
26
|
+
return {
|
|
27
|
+
category: normalized,
|
|
28
|
+
kind: kindForCategory(normalized),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function kindForCategory(category) {
|
|
32
|
+
switch (normalizeKeyPart(category)) {
|
|
33
|
+
case "movie":
|
|
34
|
+
case "film":
|
|
35
|
+
case "tv":
|
|
36
|
+
case "tvshow":
|
|
37
|
+
case "tv_show":
|
|
38
|
+
case "tvseason":
|
|
39
|
+
case "tv_season":
|
|
40
|
+
case "series":
|
|
41
|
+
case "anime":
|
|
42
|
+
case "documentary":
|
|
43
|
+
case "video":
|
|
44
|
+
return "watch";
|
|
45
|
+
case "album":
|
|
46
|
+
case "music":
|
|
47
|
+
case "musicalbum":
|
|
48
|
+
case "release":
|
|
49
|
+
case "master":
|
|
50
|
+
case "track":
|
|
51
|
+
case "recording":
|
|
52
|
+
case "podcast":
|
|
53
|
+
case "podcast_episode":
|
|
54
|
+
case "audiobook":
|
|
55
|
+
return "listen";
|
|
56
|
+
case "book":
|
|
57
|
+
case "work":
|
|
58
|
+
case "article":
|
|
59
|
+
case "web_page":
|
|
60
|
+
case "comic":
|
|
61
|
+
case "manga":
|
|
62
|
+
case "paper":
|
|
63
|
+
case "blog_post":
|
|
64
|
+
return "read";
|
|
65
|
+
case "game":
|
|
66
|
+
case "videogame":
|
|
67
|
+
case "boardgame":
|
|
68
|
+
case "platform":
|
|
69
|
+
return "play";
|
|
70
|
+
case "place":
|
|
71
|
+
case "location":
|
|
72
|
+
case "venue":
|
|
73
|
+
case "restaurant":
|
|
74
|
+
case "route":
|
|
75
|
+
case "city":
|
|
76
|
+
case "country":
|
|
77
|
+
return "visit";
|
|
78
|
+
case "event":
|
|
79
|
+
case "concert":
|
|
80
|
+
case "screening":
|
|
81
|
+
case "exhibition":
|
|
82
|
+
case "match":
|
|
83
|
+
case "festival":
|
|
84
|
+
return "event";
|
|
85
|
+
case "person":
|
|
86
|
+
case "people":
|
|
87
|
+
case "artist":
|
|
88
|
+
case "author":
|
|
89
|
+
case "actor":
|
|
90
|
+
case "creator":
|
|
91
|
+
case "organization":
|
|
92
|
+
case "company":
|
|
93
|
+
case "team":
|
|
94
|
+
return "people";
|
|
95
|
+
default:
|
|
96
|
+
return normalizeKeyPart(category);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function normalizeKeyPart(value) {
|
|
100
|
+
return value.trim().toLowerCase();
|
|
101
|
+
}
|
package/dist/hash.d.ts
ADDED