@mediaryorg/contracts 2.0.0 → 2.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/dist/proto/paths.d.ts +0 -1
- package/dist/proto/paths.js +0 -1
- package/generated/auth/v1/auth.ts +21 -0
- package/generated/favorite/v1/favorite.ts +2 -1
- package/generated/library/v1/library.ts +2 -2
- package/generated/media/v1/media.ts +70 -62
- package/generated/media_request/v1/media_request.ts +4 -4
- package/package.json +3 -3
- package/proto/auth/v1/auth.proto +9 -0
- package/proto/favorite/v1/favorite.proto +3 -1
- package/proto/library/v1/library.proto +1 -1
- package/proto/media/v1/media.proto +62 -66
- package/proto/media_request/v1/media_request.proto +3 -3
- package/generated/collection/v1/collection.ts +0 -235
- package/proto/collection/v1/collection.proto +0 -120
package/dist/proto/paths.d.ts
CHANGED
package/dist/proto/paths.js
CHANGED
|
@@ -8,7 +8,6 @@ exports.PROTO_PATH = {
|
|
|
8
8
|
USER: (0, path_1.join)(PROTO_DIR, "user/v1/user.proto"),
|
|
9
9
|
PROFILE: (0, path_1.join)(PROTO_DIR, "profile/v1/profile.proto"),
|
|
10
10
|
MEDIA: (0, path_1.join)(PROTO_DIR, "media/v1/media.proto"),
|
|
11
|
-
COLLECTION: (0, path_1.join)(PROTO_DIR, "collection/v1/collection.proto"),
|
|
12
11
|
LIBRARY: (0, path_1.join)(PROTO_DIR, "library/v1/library.proto"),
|
|
13
12
|
FAVORITE: (0, path_1.join)(PROTO_DIR, "favorite/v1/favorite.proto"),
|
|
14
13
|
MEDIA_REQUEST: (0, path_1.join)(PROTO_DIR, "media_request/v1/media_request.proto"),
|
|
@@ -141,6 +141,13 @@ export interface AdminValidateSessionResponse {
|
|
|
141
141
|
user: AuthUser | undefined;
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
+
export interface ApplyUserIdentitySnapshotRequest {
|
|
145
|
+
user: AuthUser | undefined;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export interface ApplyUserIdentitySnapshotResponse {
|
|
149
|
+
}
|
|
150
|
+
|
|
144
151
|
export const AUTH_V1_PACKAGE_NAME = "auth.v1";
|
|
145
152
|
|
|
146
153
|
export interface AuthServiceClient {
|
|
@@ -169,6 +176,10 @@ export interface AuthServiceClient {
|
|
|
169
176
|
adminLogout(request: AdminLogoutRequest): Observable<AdminLogoutResponse>;
|
|
170
177
|
|
|
171
178
|
adminValidateSession(request: AdminValidateSessionRequest): Observable<AdminValidateSessionResponse>;
|
|
179
|
+
|
|
180
|
+
/** Called by user-service after identity fields change (e.g. email, role) so active sessions stay in sync. */
|
|
181
|
+
|
|
182
|
+
applyUserIdentitySnapshot(request: ApplyUserIdentitySnapshotRequest): Observable<ApplyUserIdentitySnapshotResponse>;
|
|
172
183
|
}
|
|
173
184
|
|
|
174
185
|
export interface AuthServiceController {
|
|
@@ -217,6 +228,15 @@ export interface AuthServiceController {
|
|
|
217
228
|
adminValidateSession(
|
|
218
229
|
request: AdminValidateSessionRequest,
|
|
219
230
|
): Promise<AdminValidateSessionResponse> | Observable<AdminValidateSessionResponse> | AdminValidateSessionResponse;
|
|
231
|
+
|
|
232
|
+
/** Called by user-service after identity fields change (e.g. email, role) so active sessions stay in sync. */
|
|
233
|
+
|
|
234
|
+
applyUserIdentitySnapshot(
|
|
235
|
+
request: ApplyUserIdentitySnapshotRequest,
|
|
236
|
+
):
|
|
237
|
+
| Promise<ApplyUserIdentitySnapshotResponse>
|
|
238
|
+
| Observable<ApplyUserIdentitySnapshotResponse>
|
|
239
|
+
| ApplyUserIdentitySnapshotResponse;
|
|
220
240
|
}
|
|
221
241
|
|
|
222
242
|
export function AuthServiceControllerMethods() {
|
|
@@ -235,6 +255,7 @@ export function AuthServiceControllerMethods() {
|
|
|
235
255
|
"adminLogin",
|
|
236
256
|
"adminLogout",
|
|
237
257
|
"adminValidateSession",
|
|
258
|
+
"applyUserIdentitySnapshot",
|
|
238
259
|
];
|
|
239
260
|
for (const method of grpcMethods) {
|
|
240
261
|
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
/* eslint-disable */
|
|
8
8
|
import { GrpcMethod, GrpcStreamMethod } from "@nestjs/microservices";
|
|
9
9
|
import { Observable } from "rxjs";
|
|
10
|
+
import { MediaType } from "../../media/v1/media";
|
|
10
11
|
|
|
11
12
|
export const protobufPackage = "favorite.v1";
|
|
12
13
|
|
|
@@ -53,7 +54,7 @@ export interface IsFavoriteResponse {
|
|
|
53
54
|
export interface ListUserFavoritesRequest {
|
|
54
55
|
userId: string;
|
|
55
56
|
search?: string | undefined;
|
|
56
|
-
|
|
57
|
+
type?: MediaType | undefined;
|
|
57
58
|
page: number;
|
|
58
59
|
limit: number;
|
|
59
60
|
sortBy: string;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
/* eslint-disable */
|
|
8
8
|
import { GrpcMethod, GrpcStreamMethod } from "@nestjs/microservices";
|
|
9
9
|
import { Observable } from "rxjs";
|
|
10
|
-
import { Media, MediaSource } from "../../media/v1/media";
|
|
10
|
+
import { Media, MediaSource, MediaType } from "../../media/v1/media";
|
|
11
11
|
|
|
12
12
|
export const protobufPackage = "library.v1";
|
|
13
13
|
|
|
@@ -69,7 +69,7 @@ export interface AddFromSearchResponse {
|
|
|
69
69
|
export interface GetUserLibraryRequest {
|
|
70
70
|
userId: string;
|
|
71
71
|
statuses: LibraryItemStatus[];
|
|
72
|
-
|
|
72
|
+
type?: MediaType | undefined;
|
|
73
73
|
source?: MediaSource | undefined;
|
|
74
74
|
search?: string | undefined;
|
|
75
75
|
genres: string[];
|
|
@@ -10,20 +10,47 @@ import { Observable } from "rxjs";
|
|
|
10
10
|
|
|
11
11
|
export const protobufPackage = "media.v1";
|
|
12
12
|
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Provider the canonical metadata came from. Mirrors search.v1.SearchSource
|
|
15
|
+
* (minus LOCAL, which is not a persisted origin). CUSTOM is reserved for
|
|
16
|
+
* manually added media (media-request flow) with no external provider.
|
|
17
|
+
*/
|
|
14
18
|
export enum MediaSource {
|
|
15
19
|
MEDIA_SOURCE_UNSPECIFIED = 0,
|
|
16
20
|
MEDIA_SOURCE_TMDB = 1,
|
|
17
21
|
MEDIA_SOURCE_GOOGLE_BOOKS = 2,
|
|
18
22
|
MEDIA_SOURCE_MAL = 3,
|
|
19
|
-
|
|
23
|
+
MEDIA_SOURCE_ANILIST = 4,
|
|
24
|
+
MEDIA_SOURCE_MANGADEX = 5,
|
|
25
|
+
MEDIA_SOURCE_IGDB = 6,
|
|
26
|
+
MEDIA_SOURCE_RAWG = 7,
|
|
27
|
+
MEDIA_SOURCE_OPEN_LIBRARY = 8,
|
|
28
|
+
MEDIA_SOURCE_CUSTOM = 9,
|
|
20
29
|
UNRECOGNIZED = -1,
|
|
21
30
|
}
|
|
22
31
|
|
|
23
32
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
33
|
+
* Intrinsic kind of the media entry. Mirrors search.v1.SearchMediaType so a
|
|
34
|
+
* search hit maps 1:1 onto a catalog type. Replaces the legacy Collection
|
|
35
|
+
* concept (the 8 categories are now an attribute of the media itself).
|
|
36
|
+
*/
|
|
37
|
+
export enum MediaType {
|
|
38
|
+
MEDIA_TYPE_UNSPECIFIED = 0,
|
|
39
|
+
MEDIA_TYPE_MOVIE = 1,
|
|
40
|
+
MEDIA_TYPE_SERIES = 2,
|
|
41
|
+
MEDIA_TYPE_BOOK = 3,
|
|
42
|
+
MEDIA_TYPE_ANIME = 4,
|
|
43
|
+
MEDIA_TYPE_MANGA = 5,
|
|
44
|
+
MEDIA_TYPE_MANHWA = 6,
|
|
45
|
+
MEDIA_TYPE_GAME = 7,
|
|
46
|
+
MEDIA_TYPE_KDRAMA = 8,
|
|
47
|
+
UNRECOGNIZED = -1,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Structured metadata kept as a JSON column. `custom_fields_json` carries the
|
|
52
|
+
* type-specific customFields object as a JSON-encoded string so callers can
|
|
53
|
+
* extend it without schema migrations.
|
|
27
54
|
*/
|
|
28
55
|
export interface MediaData {
|
|
29
56
|
title: string;
|
|
@@ -41,33 +68,27 @@ export interface MediaData {
|
|
|
41
68
|
|
|
42
69
|
export interface Media {
|
|
43
70
|
id: string;
|
|
71
|
+
type: MediaType;
|
|
44
72
|
source: MediaSource;
|
|
45
73
|
externalId: string;
|
|
46
74
|
mediaData: MediaData | undefined;
|
|
47
75
|
searchableTitle: string;
|
|
76
|
+
/** JSON object preserving every known provider id, e.g. {"tmdb":"27205"}. */
|
|
48
77
|
externalIdsJson: string;
|
|
49
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Optional reference to the user who first added this entry (user-service).
|
|
80
|
+
* Purely informational; the catalog has no user ownership.
|
|
81
|
+
*/
|
|
50
82
|
addedById: string;
|
|
51
83
|
createdAt: string;
|
|
52
84
|
updatedAt: string;
|
|
53
85
|
}
|
|
54
86
|
|
|
55
|
-
export interface MediaCounts {
|
|
56
|
-
library: number;
|
|
57
|
-
reviews: number;
|
|
58
|
-
favorites: number;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export interface MediaWithCounts {
|
|
62
|
-
media: Media | undefined;
|
|
63
|
-
counts: MediaCounts | undefined;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
87
|
export interface CreateMediaRequest {
|
|
88
|
+
type: MediaType;
|
|
67
89
|
source: MediaSource;
|
|
68
90
|
externalId: string;
|
|
69
91
|
mediaData: MediaData | undefined;
|
|
70
|
-
collectionId: string;
|
|
71
92
|
addedById: string;
|
|
72
93
|
}
|
|
73
94
|
|
|
@@ -79,16 +100,8 @@ export interface GetMediaByIdRequest {
|
|
|
79
100
|
mediaId: string;
|
|
80
101
|
}
|
|
81
102
|
|
|
82
|
-
export interface RatingDistributionEntry {
|
|
83
|
-
rating: number;
|
|
84
|
-
count: number;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
103
|
export interface GetMediaByIdResponse {
|
|
88
104
|
media: Media | undefined;
|
|
89
|
-
counts: MediaCounts | undefined;
|
|
90
|
-
averageRating: number;
|
|
91
|
-
totalReviews: number;
|
|
92
105
|
}
|
|
93
106
|
|
|
94
107
|
export interface GetMediaByExternalIdRequest {
|
|
@@ -109,27 +122,12 @@ export interface FindDuplicatesResponse {
|
|
|
109
122
|
items: Media[];
|
|
110
123
|
}
|
|
111
124
|
|
|
112
|
-
export interface GetMediaStatsRequest {
|
|
113
|
-
mediaId: string;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export interface MediaStats {
|
|
117
|
-
averageRating: number;
|
|
118
|
-
totalReviews: number;
|
|
119
|
-
ratingDistribution: RatingDistributionEntry[];
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export interface GetMediaStatsResponse {
|
|
123
|
-
media: Media | undefined;
|
|
124
|
-
stats: MediaStats | undefined;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
125
|
export interface UpdateMediaRequest {
|
|
128
126
|
mediaId: string;
|
|
127
|
+
type?: MediaType | undefined;
|
|
129
128
|
source?: MediaSource | undefined;
|
|
130
129
|
externalId?: string | undefined;
|
|
131
130
|
mediaData?: MediaData | undefined;
|
|
132
|
-
collectionId?: string | undefined;
|
|
133
131
|
}
|
|
134
132
|
|
|
135
133
|
export interface UpdateMediaResponse {
|
|
@@ -145,7 +143,7 @@ export interface DeleteMediaResponse {
|
|
|
145
143
|
|
|
146
144
|
export interface ListMediaRequest {
|
|
147
145
|
search?: string | undefined;
|
|
148
|
-
|
|
146
|
+
type?: MediaType | undefined;
|
|
149
147
|
source?: MediaSource | undefined;
|
|
150
148
|
year?: number | undefined;
|
|
151
149
|
page: number;
|
|
@@ -164,19 +162,20 @@ export interface PaginationMeta {
|
|
|
164
162
|
}
|
|
165
163
|
|
|
166
164
|
export interface ListMediaResponse {
|
|
167
|
-
data:
|
|
165
|
+
data: Media[];
|
|
168
166
|
meta: PaginationMeta | undefined;
|
|
169
167
|
}
|
|
170
168
|
|
|
171
169
|
export interface EnsureMediaFromSearchRequest {
|
|
172
170
|
/**
|
|
173
171
|
* Source identifier coming from search-service results
|
|
174
|
-
* ("tmdb", "google_books", "mangadex",
|
|
172
|
+
* ("tmdb", "google_books", "anilist", "mangadex", ...). "local" means the
|
|
173
|
+
* hit already references a catalog entry by id.
|
|
175
174
|
*/
|
|
176
175
|
source: string;
|
|
177
|
-
/** External id within that source (or media id when source == "local") */
|
|
176
|
+
/** External id within that source (or media id when source == "local"). */
|
|
178
177
|
externalId: string;
|
|
179
|
-
/** Search media
|
|
178
|
+
/** Search media-type label ("movie"|"series"|"book"|"anime"|"manga"|"manhwa"|"game"|"kdrama"). */
|
|
180
179
|
mediaType: string;
|
|
181
180
|
title: string;
|
|
182
181
|
subtitle: string;
|
|
@@ -184,7 +183,7 @@ export interface EnsureMediaFromSearchRequest {
|
|
|
184
183
|
year: string;
|
|
185
184
|
rating?: number | undefined;
|
|
186
185
|
genres: string[];
|
|
187
|
-
/** User who initiated the action (
|
|
186
|
+
/** User who initiated the action (recorded as added_by_id on creation). */
|
|
188
187
|
requestedByUserId: string;
|
|
189
188
|
}
|
|
190
189
|
|
|
@@ -192,12 +191,20 @@ export interface EnsureMediaFromSearchResponse {
|
|
|
192
191
|
media:
|
|
193
192
|
| Media
|
|
194
193
|
| undefined;
|
|
195
|
-
/** True when the
|
|
194
|
+
/** True when the catalog entry was just created, false when reused. */
|
|
196
195
|
created: boolean;
|
|
197
196
|
}
|
|
198
197
|
|
|
199
198
|
export const MEDIA_V1_PACKAGE_NAME = "media.v1";
|
|
200
199
|
|
|
200
|
+
/**
|
|
201
|
+
* MediaService owns the global media catalog ("storage"): a deduplicated,
|
|
202
|
+
* user-agnostic set of media entries that are reused across every user's
|
|
203
|
+
* lists/library. Adding media to a search/discover flow first checks this
|
|
204
|
+
* catalog before hitting external providers; removing media from a user's
|
|
205
|
+
* list never deletes it here.
|
|
206
|
+
*/
|
|
207
|
+
|
|
201
208
|
export interface MediaServiceClient {
|
|
202
209
|
createMedia(request: CreateMediaRequest): Observable<CreateMediaResponse>;
|
|
203
210
|
|
|
@@ -207,8 +214,6 @@ export interface MediaServiceClient {
|
|
|
207
214
|
|
|
208
215
|
findDuplicates(request: FindDuplicatesRequest): Observable<FindDuplicatesResponse>;
|
|
209
216
|
|
|
210
|
-
getMediaStats(request: GetMediaStatsRequest): Observable<GetMediaStatsResponse>;
|
|
211
|
-
|
|
212
217
|
updateMedia(request: UpdateMediaRequest): Observable<UpdateMediaResponse>;
|
|
213
218
|
|
|
214
219
|
deleteMedia(request: DeleteMediaRequest): Observable<DeleteMediaResponse>;
|
|
@@ -216,14 +221,22 @@ export interface MediaServiceClient {
|
|
|
216
221
|
listMedia(request: ListMediaRequest): Observable<ListMediaResponse>;
|
|
217
222
|
|
|
218
223
|
/**
|
|
219
|
-
* Cross-service: ensure
|
|
220
|
-
* Used by library/
|
|
221
|
-
*
|
|
224
|
+
* Cross-service: ensure a catalog entry exists for a search/discover hit.
|
|
225
|
+
* Used by library/list/recommendation flows so they don't write into the
|
|
226
|
+
* catalog database directly. Returns the existing entry when found.
|
|
222
227
|
*/
|
|
223
228
|
|
|
224
229
|
ensureMediaFromSearch(request: EnsureMediaFromSearchRequest): Observable<EnsureMediaFromSearchResponse>;
|
|
225
230
|
}
|
|
226
231
|
|
|
232
|
+
/**
|
|
233
|
+
* MediaService owns the global media catalog ("storage"): a deduplicated,
|
|
234
|
+
* user-agnostic set of media entries that are reused across every user's
|
|
235
|
+
* lists/library. Adding media to a search/discover flow first checks this
|
|
236
|
+
* catalog before hitting external providers; removing media from a user's
|
|
237
|
+
* list never deletes it here.
|
|
238
|
+
*/
|
|
239
|
+
|
|
227
240
|
export interface MediaServiceController {
|
|
228
241
|
createMedia(
|
|
229
242
|
request: CreateMediaRequest,
|
|
@@ -241,10 +254,6 @@ export interface MediaServiceController {
|
|
|
241
254
|
request: FindDuplicatesRequest,
|
|
242
255
|
): Promise<FindDuplicatesResponse> | Observable<FindDuplicatesResponse> | FindDuplicatesResponse;
|
|
243
256
|
|
|
244
|
-
getMediaStats(
|
|
245
|
-
request: GetMediaStatsRequest,
|
|
246
|
-
): Promise<GetMediaStatsResponse> | Observable<GetMediaStatsResponse> | GetMediaStatsResponse;
|
|
247
|
-
|
|
248
257
|
updateMedia(
|
|
249
258
|
request: UpdateMediaRequest,
|
|
250
259
|
): Promise<UpdateMediaResponse> | Observable<UpdateMediaResponse> | UpdateMediaResponse;
|
|
@@ -256,9 +265,9 @@ export interface MediaServiceController {
|
|
|
256
265
|
listMedia(request: ListMediaRequest): Promise<ListMediaResponse> | Observable<ListMediaResponse> | ListMediaResponse;
|
|
257
266
|
|
|
258
267
|
/**
|
|
259
|
-
* Cross-service: ensure
|
|
260
|
-
* Used by library/
|
|
261
|
-
*
|
|
268
|
+
* Cross-service: ensure a catalog entry exists for a search/discover hit.
|
|
269
|
+
* Used by library/list/recommendation flows so they don't write into the
|
|
270
|
+
* catalog database directly. Returns the existing entry when found.
|
|
262
271
|
*/
|
|
263
272
|
|
|
264
273
|
ensureMediaFromSearch(
|
|
@@ -273,7 +282,6 @@ export function MediaServiceControllerMethods() {
|
|
|
273
282
|
"getMediaById",
|
|
274
283
|
"getMediaByExternalId",
|
|
275
284
|
"findDuplicates",
|
|
276
|
-
"getMediaStats",
|
|
277
285
|
"updateMedia",
|
|
278
286
|
"deleteMedia",
|
|
279
287
|
"listMedia",
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
/* eslint-disable */
|
|
8
8
|
import { GrpcMethod, GrpcStreamMethod } from "@nestjs/microservices";
|
|
9
9
|
import { Observable } from "rxjs";
|
|
10
|
-
import { MediaData, MediaSource } from "../../media/v1/media";
|
|
10
|
+
import { MediaData, MediaSource, MediaType } from "../../media/v1/media";
|
|
11
11
|
|
|
12
12
|
export const protobufPackage = "media_request.v1";
|
|
13
13
|
|
|
@@ -45,7 +45,7 @@ export interface MediaRequest {
|
|
|
45
45
|
moderatedById: string;
|
|
46
46
|
moderatedBy: MediaRequestUserRef | undefined;
|
|
47
47
|
approvedMediaId: string;
|
|
48
|
-
|
|
48
|
+
type: MediaType;
|
|
49
49
|
createdAt: string;
|
|
50
50
|
updatedAt: string;
|
|
51
51
|
}
|
|
@@ -55,7 +55,7 @@ export interface CreateMediaRequestRequest {
|
|
|
55
55
|
/** Currently only CUSTOM is accepted (TMDB content goes through search flow). */
|
|
56
56
|
source?: MediaSource | undefined;
|
|
57
57
|
mediaData: MediaData | undefined;
|
|
58
|
-
|
|
58
|
+
type: MediaType;
|
|
59
59
|
comment?: string | undefined;
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -83,7 +83,7 @@ export interface GetMediaRequestByIdResponse {
|
|
|
83
83
|
export interface ListMediaRequestsRequest {
|
|
84
84
|
status?: ModerationStatus | undefined;
|
|
85
85
|
source?: MediaSource | undefined;
|
|
86
|
-
|
|
86
|
+
type?: MediaType | undefined;
|
|
87
87
|
search?: string | undefined;
|
|
88
88
|
requestedById?: string | undefined;
|
|
89
89
|
moderatedById?: string | undefined;
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mediaryorg/contracts",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Protobuf definitions and generated TypeScript types",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"generate": "npm run generate:win",
|
|
9
|
-
"generate:win": "protoc -I .\\proto .\\proto\\auth\\v1\\auth.proto .\\proto\\user\\v1\\user.proto .\\proto\\profile\\v1\\profile.proto .\\proto\\media\\v1\\media.proto .\\proto\\
|
|
10
|
-
"generate:ci": "protoc -I ./proto ./proto/auth/v1/auth.proto ./proto/user/v1/user.proto ./proto/profile/v1/profile.proto ./proto/media/v1/media.proto ./proto/
|
|
9
|
+
"generate:win": "protoc -I .\\proto .\\proto\\auth\\v1\\auth.proto .\\proto\\user\\v1\\user.proto .\\proto\\profile\\v1\\profile.proto .\\proto\\media\\v1\\media.proto .\\proto\\library\\v1\\library.proto .\\proto\\favorite\\v1\\favorite.proto .\\proto\\media_request\\v1\\media_request.proto .\\proto\\image\\v1\\image.proto .\\proto\\search\\v1\\search.proto .\\proto\\recommendation\\v1\\recommendation.proto --plugin=protoc-gen-ts_proto=.\\node_modules\\.bin\\protoc-gen-ts_proto.cmd --ts_proto_out=.\\generated --ts_proto_opt=nestJs=true,package=omit",
|
|
10
|
+
"generate:ci": "protoc -I ./proto ./proto/auth/v1/auth.proto ./proto/user/v1/user.proto ./proto/profile/v1/profile.proto ./proto/media/v1/media.proto ./proto/library/v1/library.proto ./proto/favorite/v1/favorite.proto ./proto/media_request/v1/media_request.proto ./proto/image/v1/image.proto ./proto/search/v1/search.proto ./proto/recommendation/v1/recommendation.proto --plugin=protoc-gen-ts_proto=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_out=./generated --ts_proto_opt=nestJs=true,package=omit",
|
|
11
11
|
"build": "tsc -p tsconfig.build.json"
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
package/proto/auth/v1/auth.proto
CHANGED
|
@@ -21,6 +21,9 @@ service AuthService {
|
|
|
21
21
|
rpc AdminLogin(AdminLoginRequest) returns (AdminLoginResponse);
|
|
22
22
|
rpc AdminLogout(AdminLogoutRequest) returns (AdminLogoutResponse);
|
|
23
23
|
rpc AdminValidateSession(AdminValidateSessionRequest) returns (AdminValidateSessionResponse);
|
|
24
|
+
|
|
25
|
+
// Called by user-service after identity fields change (e.g. email, role) so active sessions stay in sync.
|
|
26
|
+
rpc ApplyUserIdentitySnapshot(ApplyUserIdentitySnapshotRequest) returns (ApplyUserIdentitySnapshotResponse);
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
// Identity-only view of a user emitted by auth-service.
|
|
@@ -151,3 +154,9 @@ message AdminValidateSessionResponse {
|
|
|
151
154
|
bool valid = 1;
|
|
152
155
|
AuthUser user = 2;
|
|
153
156
|
}
|
|
157
|
+
|
|
158
|
+
message ApplyUserIdentitySnapshotRequest {
|
|
159
|
+
AuthUser user = 1;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
message ApplyUserIdentitySnapshotResponse {}
|
|
@@ -2,6 +2,8 @@ syntax = "proto3";
|
|
|
2
2
|
|
|
3
3
|
package favorite.v1;
|
|
4
4
|
|
|
5
|
+
import "media/v1/media.proto";
|
|
6
|
+
|
|
5
7
|
service FavoriteService {
|
|
6
8
|
rpc CheckMultipleFavorites(CheckMultipleFavoritesRequest) returns (CheckMultipleFavoritesResponse);
|
|
7
9
|
rpc ToggleFavorite(ToggleFavoriteRequest) returns (ToggleFavoriteResponse);
|
|
@@ -48,7 +50,7 @@ message IsFavoriteResponse {
|
|
|
48
50
|
message ListUserFavoritesRequest {
|
|
49
51
|
string user_id = 1;
|
|
50
52
|
optional string search = 2;
|
|
51
|
-
optional
|
|
53
|
+
optional media.v1.MediaType type = 3;
|
|
52
54
|
int32 page = 4;
|
|
53
55
|
int32 limit = 5;
|
|
54
56
|
string sort_by = 6;
|
|
@@ -69,7 +69,7 @@ message AddFromSearchResponse {
|
|
|
69
69
|
message GetUserLibraryRequest {
|
|
70
70
|
string user_id = 1;
|
|
71
71
|
repeated LibraryItemStatus statuses = 2;
|
|
72
|
-
optional
|
|
72
|
+
optional media.v1.MediaType type = 3;
|
|
73
73
|
optional media.v1.MediaSource source = 4;
|
|
74
74
|
optional string search = 5;
|
|
75
75
|
repeated string genres = 6;
|
|
@@ -2,34 +2,60 @@ syntax = "proto3";
|
|
|
2
2
|
|
|
3
3
|
package media.v1;
|
|
4
4
|
|
|
5
|
+
// MediaService owns the global media catalog ("storage"): a deduplicated,
|
|
6
|
+
// user-agnostic set of media entries that are reused across every user's
|
|
7
|
+
// lists/library. Adding media to a search/discover flow first checks this
|
|
8
|
+
// catalog before hitting external providers; removing media from a user's
|
|
9
|
+
// list never deletes it here.
|
|
5
10
|
service MediaService {
|
|
6
11
|
rpc CreateMedia(CreateMediaRequest) returns (CreateMediaResponse);
|
|
7
12
|
rpc GetMediaById(GetMediaByIdRequest) returns (GetMediaByIdResponse);
|
|
8
13
|
rpc GetMediaByExternalId(GetMediaByExternalIdRequest) returns (GetMediaByExternalIdResponse);
|
|
9
14
|
rpc FindDuplicates(FindDuplicatesRequest) returns (FindDuplicatesResponse);
|
|
10
|
-
rpc GetMediaStats(GetMediaStatsRequest) returns (GetMediaStatsResponse);
|
|
11
15
|
rpc UpdateMedia(UpdateMediaRequest) returns (UpdateMediaResponse);
|
|
12
16
|
rpc DeleteMedia(DeleteMediaRequest) returns (DeleteMediaResponse);
|
|
13
17
|
rpc ListMedia(ListMediaRequest) returns (ListMediaResponse);
|
|
14
18
|
|
|
15
|
-
// Cross-service: ensure
|
|
16
|
-
// Used by library/
|
|
17
|
-
//
|
|
19
|
+
// Cross-service: ensure a catalog entry exists for a search/discover hit.
|
|
20
|
+
// Used by library/list/recommendation flows so they don't write into the
|
|
21
|
+
// catalog database directly. Returns the existing entry when found.
|
|
18
22
|
rpc EnsureMediaFromSearch(EnsureMediaFromSearchRequest) returns (EnsureMediaFromSearchResponse);
|
|
19
23
|
}
|
|
20
24
|
|
|
21
|
-
//
|
|
25
|
+
// Provider the canonical metadata came from. Mirrors search.v1.SearchSource
|
|
26
|
+
// (minus LOCAL, which is not a persisted origin). CUSTOM is reserved for
|
|
27
|
+
// manually added media (media-request flow) with no external provider.
|
|
22
28
|
enum MediaSource {
|
|
23
29
|
MEDIA_SOURCE_UNSPECIFIED = 0;
|
|
24
30
|
MEDIA_SOURCE_TMDB = 1;
|
|
25
31
|
MEDIA_SOURCE_GOOGLE_BOOKS = 2;
|
|
26
32
|
MEDIA_SOURCE_MAL = 3;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
MEDIA_SOURCE_ANILIST = 4;
|
|
34
|
+
MEDIA_SOURCE_MANGADEX = 5;
|
|
35
|
+
MEDIA_SOURCE_IGDB = 6;
|
|
36
|
+
MEDIA_SOURCE_RAWG = 7;
|
|
37
|
+
MEDIA_SOURCE_OPEN_LIBRARY = 8;
|
|
38
|
+
MEDIA_SOURCE_CUSTOM = 9;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Intrinsic kind of the media entry. Mirrors search.v1.SearchMediaType so a
|
|
42
|
+
// search hit maps 1:1 onto a catalog type. Replaces the legacy Collection
|
|
43
|
+
// concept (the 8 categories are now an attribute of the media itself).
|
|
44
|
+
enum MediaType {
|
|
45
|
+
MEDIA_TYPE_UNSPECIFIED = 0;
|
|
46
|
+
MEDIA_TYPE_MOVIE = 1;
|
|
47
|
+
MEDIA_TYPE_SERIES = 2;
|
|
48
|
+
MEDIA_TYPE_BOOK = 3;
|
|
49
|
+
MEDIA_TYPE_ANIME = 4;
|
|
50
|
+
MEDIA_TYPE_MANGA = 5;
|
|
51
|
+
MEDIA_TYPE_MANHWA = 6;
|
|
52
|
+
MEDIA_TYPE_GAME = 7;
|
|
53
|
+
MEDIA_TYPE_KDRAMA = 8;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Structured metadata kept as a JSON column. `custom_fields_json` carries the
|
|
57
|
+
// type-specific customFields object as a JSON-encoded string so callers can
|
|
58
|
+
// extend it without schema migrations.
|
|
33
59
|
message MediaData {
|
|
34
60
|
string title = 1;
|
|
35
61
|
string original_title = 2;
|
|
@@ -46,33 +72,25 @@ message MediaData {
|
|
|
46
72
|
|
|
47
73
|
message Media {
|
|
48
74
|
string id = 1;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
string
|
|
54
|
-
|
|
75
|
+
MediaType type = 2;
|
|
76
|
+
MediaSource source = 3;
|
|
77
|
+
string external_id = 4;
|
|
78
|
+
MediaData media_data = 5;
|
|
79
|
+
string searchable_title = 6;
|
|
80
|
+
// JSON object preserving every known provider id, e.g. {"tmdb":"27205"}.
|
|
81
|
+
string external_ids_json = 7;
|
|
82
|
+
// Optional reference to the user who first added this entry (user-service).
|
|
83
|
+
// Purely informational; the catalog has no user ownership.
|
|
55
84
|
string added_by_id = 8;
|
|
56
85
|
string created_at = 9;
|
|
57
86
|
string updated_at = 10;
|
|
58
87
|
}
|
|
59
88
|
|
|
60
|
-
message MediaCounts {
|
|
61
|
-
int32 library = 1;
|
|
62
|
-
int32 reviews = 2;
|
|
63
|
-
int32 favorites = 3;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
message MediaWithCounts {
|
|
67
|
-
Media media = 1;
|
|
68
|
-
MediaCounts counts = 2;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
89
|
message CreateMediaRequest {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
90
|
+
MediaType type = 1;
|
|
91
|
+
MediaSource source = 2;
|
|
92
|
+
string external_id = 3;
|
|
93
|
+
MediaData media_data = 4;
|
|
76
94
|
string added_by_id = 5;
|
|
77
95
|
}
|
|
78
96
|
|
|
@@ -84,16 +102,8 @@ message GetMediaByIdRequest {
|
|
|
84
102
|
string media_id = 1;
|
|
85
103
|
}
|
|
86
104
|
|
|
87
|
-
message RatingDistributionEntry {
|
|
88
|
-
double rating = 1;
|
|
89
|
-
int32 count = 2;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
105
|
message GetMediaByIdResponse {
|
|
93
106
|
Media media = 1;
|
|
94
|
-
MediaCounts counts = 2;
|
|
95
|
-
double average_rating = 3;
|
|
96
|
-
int32 total_reviews = 4;
|
|
97
107
|
}
|
|
98
108
|
|
|
99
109
|
message GetMediaByExternalIdRequest {
|
|
@@ -114,27 +124,12 @@ message FindDuplicatesResponse {
|
|
|
114
124
|
repeated Media items = 1;
|
|
115
125
|
}
|
|
116
126
|
|
|
117
|
-
message GetMediaStatsRequest {
|
|
118
|
-
string media_id = 1;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
message MediaStats {
|
|
122
|
-
double average_rating = 1;
|
|
123
|
-
int32 total_reviews = 2;
|
|
124
|
-
repeated RatingDistributionEntry rating_distribution = 3;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
message GetMediaStatsResponse {
|
|
128
|
-
Media media = 1;
|
|
129
|
-
MediaStats stats = 2;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
127
|
message UpdateMediaRequest {
|
|
133
128
|
string media_id = 1;
|
|
134
|
-
optional
|
|
135
|
-
optional
|
|
136
|
-
optional
|
|
137
|
-
optional
|
|
129
|
+
optional MediaType type = 2;
|
|
130
|
+
optional MediaSource source = 3;
|
|
131
|
+
optional string external_id = 4;
|
|
132
|
+
optional MediaData media_data = 5;
|
|
138
133
|
}
|
|
139
134
|
|
|
140
135
|
message UpdateMediaResponse {
|
|
@@ -149,7 +144,7 @@ message DeleteMediaResponse {}
|
|
|
149
144
|
|
|
150
145
|
message ListMediaRequest {
|
|
151
146
|
optional string search = 1;
|
|
152
|
-
optional
|
|
147
|
+
optional MediaType type = 2;
|
|
153
148
|
optional MediaSource source = 3;
|
|
154
149
|
optional int32 year = 4;
|
|
155
150
|
int32 page = 5;
|
|
@@ -168,17 +163,18 @@ message PaginationMeta {
|
|
|
168
163
|
}
|
|
169
164
|
|
|
170
165
|
message ListMediaResponse {
|
|
171
|
-
repeated
|
|
166
|
+
repeated Media data = 1;
|
|
172
167
|
PaginationMeta meta = 2;
|
|
173
168
|
}
|
|
174
169
|
|
|
175
170
|
message EnsureMediaFromSearchRequest {
|
|
176
171
|
// Source identifier coming from search-service results
|
|
177
|
-
// ("tmdb", "google_books", "mangadex",
|
|
172
|
+
// ("tmdb", "google_books", "anilist", "mangadex", ...). "local" means the
|
|
173
|
+
// hit already references a catalog entry by id.
|
|
178
174
|
string source = 1;
|
|
179
|
-
// External id within that source (or media id when source == "local")
|
|
175
|
+
// External id within that source (or media id when source == "local").
|
|
180
176
|
string external_id = 2;
|
|
181
|
-
// Search media
|
|
177
|
+
// Search media-type label ("movie"|"series"|"book"|"anime"|"manga"|"manhwa"|"game"|"kdrama").
|
|
182
178
|
string media_type = 3;
|
|
183
179
|
string title = 4;
|
|
184
180
|
string subtitle = 5;
|
|
@@ -186,12 +182,12 @@ message EnsureMediaFromSearchRequest {
|
|
|
186
182
|
string year = 7;
|
|
187
183
|
optional double rating = 8;
|
|
188
184
|
repeated string genres = 9;
|
|
189
|
-
// User who initiated the action (
|
|
185
|
+
// User who initiated the action (recorded as added_by_id on creation).
|
|
190
186
|
string requested_by_user_id = 10;
|
|
191
187
|
}
|
|
192
188
|
|
|
193
189
|
message EnsureMediaFromSearchResponse {
|
|
194
190
|
Media media = 1;
|
|
195
|
-
// True when the
|
|
191
|
+
// True when the catalog entry was just created, false when reused.
|
|
196
192
|
bool created = 2;
|
|
197
193
|
}
|
|
@@ -48,7 +48,7 @@ message MediaRequest {
|
|
|
48
48
|
string moderated_by_id = 12;
|
|
49
49
|
MediaRequestUserRef moderated_by = 13;
|
|
50
50
|
string approved_media_id = 14;
|
|
51
|
-
|
|
51
|
+
media.v1.MediaType type = 15;
|
|
52
52
|
string created_at = 16;
|
|
53
53
|
string updated_at = 17;
|
|
54
54
|
}
|
|
@@ -58,7 +58,7 @@ message CreateMediaRequestRequest {
|
|
|
58
58
|
// Currently only CUSTOM is accepted (TMDB content goes through search flow).
|
|
59
59
|
optional media.v1.MediaSource source = 2;
|
|
60
60
|
media.v1.MediaData media_data = 3;
|
|
61
|
-
|
|
61
|
+
media.v1.MediaType type = 4;
|
|
62
62
|
optional string comment = 5;
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -86,7 +86,7 @@ message GetMediaRequestByIdResponse {
|
|
|
86
86
|
message ListMediaRequestsRequest {
|
|
87
87
|
optional ModerationStatus status = 1;
|
|
88
88
|
optional media.v1.MediaSource source = 2;
|
|
89
|
-
optional
|
|
89
|
+
optional media.v1.MediaType type = 3;
|
|
90
90
|
optional string search = 4;
|
|
91
91
|
optional string requested_by_id = 5;
|
|
92
92
|
optional string moderated_by_id = 6;
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
|
2
|
-
// versions:
|
|
3
|
-
// protoc-gen-ts_proto v2.11.6
|
|
4
|
-
// protoc v3.21.12
|
|
5
|
-
// source: collection/v1/collection.proto
|
|
6
|
-
|
|
7
|
-
/* eslint-disable */
|
|
8
|
-
import { GrpcMethod, GrpcStreamMethod } from "@nestjs/microservices";
|
|
9
|
-
import { Observable } from "rxjs";
|
|
10
|
-
|
|
11
|
-
export const protobufPackage = "collection.v1";
|
|
12
|
-
|
|
13
|
-
export interface Collection {
|
|
14
|
-
id: string;
|
|
15
|
-
name: string;
|
|
16
|
-
createdAt: string;
|
|
17
|
-
updatedAt: string;
|
|
18
|
-
/** Number of Media records linked to the collection (returned by list/get). */
|
|
19
|
-
mediaCount: number;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface CollectionWithUserStatus {
|
|
23
|
-
collection: Collection | undefined;
|
|
24
|
-
isAdded: boolean;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface UserCollection {
|
|
28
|
-
id: string;
|
|
29
|
-
userId: string;
|
|
30
|
-
collectionId: string;
|
|
31
|
-
collection: Collection | undefined;
|
|
32
|
-
createdAt: string;
|
|
33
|
-
updatedAt: string;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface ListCollectionsRequest {
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface ListCollectionsResponse {
|
|
40
|
-
items: Collection[];
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface GetCollectionByIdRequest {
|
|
44
|
-
collectionId: string;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export interface GetCollectionByIdResponse {
|
|
48
|
-
collection: Collection | undefined;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export interface GetCollectionByNameRequest {
|
|
52
|
-
name: string;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface GetCollectionByNameResponse {
|
|
56
|
-
collection: Collection | undefined;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface SeedInitialCollectionsRequest {
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export interface SeedInitialCollectionsResponse {
|
|
63
|
-
items: Collection[];
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export interface GetUserCollectionsRequest {
|
|
67
|
-
userId: string;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export interface GetUserCollectionsResponse {
|
|
71
|
-
items: Collection[];
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export interface GetAllCollectionsWithUserStatusRequest {
|
|
75
|
-
userId: string;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export interface GetAllCollectionsWithUserStatusResponse {
|
|
79
|
-
items: CollectionWithUserStatus[];
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export interface GetAvailableCollectionsRequest {
|
|
83
|
-
userId: string;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export interface GetAvailableCollectionsResponse {
|
|
87
|
-
items: Collection[];
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export interface AddCollectionToUserRequest {
|
|
91
|
-
userId: string;
|
|
92
|
-
collectionId: string;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export interface AddCollectionToUserResponse {
|
|
96
|
-
userCollection: UserCollection | undefined;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export interface RemoveCollectionFromUserRequest {
|
|
100
|
-
userId: string;
|
|
101
|
-
collectionId: string;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export interface RemoveCollectionFromUserResponse {
|
|
105
|
-
collectionId: string;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export interface InitializeDefaultCollectionsRequest {
|
|
109
|
-
userId: string;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export interface InitializeDefaultCollectionsResponse {
|
|
113
|
-
items: UserCollection[];
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export const COLLECTION_V1_PACKAGE_NAME = "collection.v1";
|
|
117
|
-
|
|
118
|
-
export interface CollectionServiceClient {
|
|
119
|
-
/** Global catalog of media collections (Movies, Series, Books, ...). */
|
|
120
|
-
|
|
121
|
-
listCollections(request: ListCollectionsRequest): Observable<ListCollectionsResponse>;
|
|
122
|
-
|
|
123
|
-
getCollectionById(request: GetCollectionByIdRequest): Observable<GetCollectionByIdResponse>;
|
|
124
|
-
|
|
125
|
-
getCollectionByName(request: GetCollectionByNameRequest): Observable<GetCollectionByNameResponse>;
|
|
126
|
-
|
|
127
|
-
seedInitialCollections(request: SeedInitialCollectionsRequest): Observable<SeedInitialCollectionsResponse>;
|
|
128
|
-
|
|
129
|
-
/** Per-user enabled collections. */
|
|
130
|
-
|
|
131
|
-
getUserCollections(request: GetUserCollectionsRequest): Observable<GetUserCollectionsResponse>;
|
|
132
|
-
|
|
133
|
-
getAllCollectionsWithUserStatus(
|
|
134
|
-
request: GetAllCollectionsWithUserStatusRequest,
|
|
135
|
-
): Observable<GetAllCollectionsWithUserStatusResponse>;
|
|
136
|
-
|
|
137
|
-
getAvailableCollections(request: GetAvailableCollectionsRequest): Observable<GetAvailableCollectionsResponse>;
|
|
138
|
-
|
|
139
|
-
addCollectionToUser(request: AddCollectionToUserRequest): Observable<AddCollectionToUserResponse>;
|
|
140
|
-
|
|
141
|
-
removeCollectionFromUser(request: RemoveCollectionFromUserRequest): Observable<RemoveCollectionFromUserResponse>;
|
|
142
|
-
|
|
143
|
-
initializeDefaultCollections(
|
|
144
|
-
request: InitializeDefaultCollectionsRequest,
|
|
145
|
-
): Observable<InitializeDefaultCollectionsResponse>;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export interface CollectionServiceController {
|
|
149
|
-
/** Global catalog of media collections (Movies, Series, Books, ...). */
|
|
150
|
-
|
|
151
|
-
listCollections(
|
|
152
|
-
request: ListCollectionsRequest,
|
|
153
|
-
): Promise<ListCollectionsResponse> | Observable<ListCollectionsResponse> | ListCollectionsResponse;
|
|
154
|
-
|
|
155
|
-
getCollectionById(
|
|
156
|
-
request: GetCollectionByIdRequest,
|
|
157
|
-
): Promise<GetCollectionByIdResponse> | Observable<GetCollectionByIdResponse> | GetCollectionByIdResponse;
|
|
158
|
-
|
|
159
|
-
getCollectionByName(
|
|
160
|
-
request: GetCollectionByNameRequest,
|
|
161
|
-
): Promise<GetCollectionByNameResponse> | Observable<GetCollectionByNameResponse> | GetCollectionByNameResponse;
|
|
162
|
-
|
|
163
|
-
seedInitialCollections(
|
|
164
|
-
request: SeedInitialCollectionsRequest,
|
|
165
|
-
):
|
|
166
|
-
| Promise<SeedInitialCollectionsResponse>
|
|
167
|
-
| Observable<SeedInitialCollectionsResponse>
|
|
168
|
-
| SeedInitialCollectionsResponse;
|
|
169
|
-
|
|
170
|
-
/** Per-user enabled collections. */
|
|
171
|
-
|
|
172
|
-
getUserCollections(
|
|
173
|
-
request: GetUserCollectionsRequest,
|
|
174
|
-
): Promise<GetUserCollectionsResponse> | Observable<GetUserCollectionsResponse> | GetUserCollectionsResponse;
|
|
175
|
-
|
|
176
|
-
getAllCollectionsWithUserStatus(
|
|
177
|
-
request: GetAllCollectionsWithUserStatusRequest,
|
|
178
|
-
):
|
|
179
|
-
| Promise<GetAllCollectionsWithUserStatusResponse>
|
|
180
|
-
| Observable<GetAllCollectionsWithUserStatusResponse>
|
|
181
|
-
| GetAllCollectionsWithUserStatusResponse;
|
|
182
|
-
|
|
183
|
-
getAvailableCollections(
|
|
184
|
-
request: GetAvailableCollectionsRequest,
|
|
185
|
-
):
|
|
186
|
-
| Promise<GetAvailableCollectionsResponse>
|
|
187
|
-
| Observable<GetAvailableCollectionsResponse>
|
|
188
|
-
| GetAvailableCollectionsResponse;
|
|
189
|
-
|
|
190
|
-
addCollectionToUser(
|
|
191
|
-
request: AddCollectionToUserRequest,
|
|
192
|
-
): Promise<AddCollectionToUserResponse> | Observable<AddCollectionToUserResponse> | AddCollectionToUserResponse;
|
|
193
|
-
|
|
194
|
-
removeCollectionFromUser(
|
|
195
|
-
request: RemoveCollectionFromUserRequest,
|
|
196
|
-
):
|
|
197
|
-
| Promise<RemoveCollectionFromUserResponse>
|
|
198
|
-
| Observable<RemoveCollectionFromUserResponse>
|
|
199
|
-
| RemoveCollectionFromUserResponse;
|
|
200
|
-
|
|
201
|
-
initializeDefaultCollections(
|
|
202
|
-
request: InitializeDefaultCollectionsRequest,
|
|
203
|
-
):
|
|
204
|
-
| Promise<InitializeDefaultCollectionsResponse>
|
|
205
|
-
| Observable<InitializeDefaultCollectionsResponse>
|
|
206
|
-
| InitializeDefaultCollectionsResponse;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
export function CollectionServiceControllerMethods() {
|
|
210
|
-
return function (constructor: Function) {
|
|
211
|
-
const grpcMethods: string[] = [
|
|
212
|
-
"listCollections",
|
|
213
|
-
"getCollectionById",
|
|
214
|
-
"getCollectionByName",
|
|
215
|
-
"seedInitialCollections",
|
|
216
|
-
"getUserCollections",
|
|
217
|
-
"getAllCollectionsWithUserStatus",
|
|
218
|
-
"getAvailableCollections",
|
|
219
|
-
"addCollectionToUser",
|
|
220
|
-
"removeCollectionFromUser",
|
|
221
|
-
"initializeDefaultCollections",
|
|
222
|
-
];
|
|
223
|
-
for (const method of grpcMethods) {
|
|
224
|
-
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|
|
225
|
-
GrpcMethod("CollectionService", method)(constructor.prototype[method], method, descriptor);
|
|
226
|
-
}
|
|
227
|
-
const grpcStreamMethods: string[] = [];
|
|
228
|
-
for (const method of grpcStreamMethods) {
|
|
229
|
-
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|
|
230
|
-
GrpcStreamMethod("CollectionService", method)(constructor.prototype[method], method, descriptor);
|
|
231
|
-
}
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
export const COLLECTION_SERVICE_NAME = "CollectionService";
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
syntax = "proto3";
|
|
2
|
-
|
|
3
|
-
package collection.v1;
|
|
4
|
-
|
|
5
|
-
service CollectionService {
|
|
6
|
-
// Global catalog of media collections (Movies, Series, Books, ...).
|
|
7
|
-
rpc ListCollections(ListCollectionsRequest) returns (ListCollectionsResponse);
|
|
8
|
-
rpc GetCollectionById(GetCollectionByIdRequest) returns (GetCollectionByIdResponse);
|
|
9
|
-
rpc GetCollectionByName(GetCollectionByNameRequest) returns (GetCollectionByNameResponse);
|
|
10
|
-
rpc SeedInitialCollections(SeedInitialCollectionsRequest) returns (SeedInitialCollectionsResponse);
|
|
11
|
-
|
|
12
|
-
// Per-user enabled collections.
|
|
13
|
-
rpc GetUserCollections(GetUserCollectionsRequest) returns (GetUserCollectionsResponse);
|
|
14
|
-
rpc GetAllCollectionsWithUserStatus(GetAllCollectionsWithUserStatusRequest) returns (GetAllCollectionsWithUserStatusResponse);
|
|
15
|
-
rpc GetAvailableCollections(GetAvailableCollectionsRequest) returns (GetAvailableCollectionsResponse);
|
|
16
|
-
rpc AddCollectionToUser(AddCollectionToUserRequest) returns (AddCollectionToUserResponse);
|
|
17
|
-
rpc RemoveCollectionFromUser(RemoveCollectionFromUserRequest) returns (RemoveCollectionFromUserResponse);
|
|
18
|
-
rpc InitializeDefaultCollections(InitializeDefaultCollectionsRequest) returns (InitializeDefaultCollectionsResponse);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
message Collection {
|
|
22
|
-
string id = 1;
|
|
23
|
-
string name = 2;
|
|
24
|
-
string created_at = 3;
|
|
25
|
-
string updated_at = 4;
|
|
26
|
-
// Number of Media records linked to the collection (returned by list/get).
|
|
27
|
-
int32 media_count = 5;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
message CollectionWithUserStatus {
|
|
31
|
-
Collection collection = 1;
|
|
32
|
-
bool is_added = 2;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
message UserCollection {
|
|
36
|
-
string id = 1;
|
|
37
|
-
string user_id = 2;
|
|
38
|
-
string collection_id = 3;
|
|
39
|
-
Collection collection = 4;
|
|
40
|
-
string created_at = 5;
|
|
41
|
-
string updated_at = 6;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
message ListCollectionsRequest {}
|
|
45
|
-
|
|
46
|
-
message ListCollectionsResponse {
|
|
47
|
-
repeated Collection items = 1;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
message GetCollectionByIdRequest {
|
|
51
|
-
string collection_id = 1;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
message GetCollectionByIdResponse {
|
|
55
|
-
Collection collection = 1;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
message GetCollectionByNameRequest {
|
|
59
|
-
string name = 1;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
message GetCollectionByNameResponse {
|
|
63
|
-
Collection collection = 1;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
message SeedInitialCollectionsRequest {}
|
|
67
|
-
|
|
68
|
-
message SeedInitialCollectionsResponse {
|
|
69
|
-
repeated Collection items = 1;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
message GetUserCollectionsRequest {
|
|
73
|
-
string user_id = 1;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
message GetUserCollectionsResponse {
|
|
77
|
-
repeated Collection items = 1;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
message GetAllCollectionsWithUserStatusRequest {
|
|
81
|
-
string user_id = 1;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
message GetAllCollectionsWithUserStatusResponse {
|
|
85
|
-
repeated CollectionWithUserStatus items = 1;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
message GetAvailableCollectionsRequest {
|
|
89
|
-
string user_id = 1;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
message GetAvailableCollectionsResponse {
|
|
93
|
-
repeated Collection items = 1;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
message AddCollectionToUserRequest {
|
|
97
|
-
string user_id = 1;
|
|
98
|
-
string collection_id = 2;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
message AddCollectionToUserResponse {
|
|
102
|
-
UserCollection user_collection = 1;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
message RemoveCollectionFromUserRequest {
|
|
106
|
-
string user_id = 1;
|
|
107
|
-
string collection_id = 2;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
message RemoveCollectionFromUserResponse {
|
|
111
|
-
string collection_id = 1;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
message InitializeDefaultCollectionsRequest {
|
|
115
|
-
string user_id = 1;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
message InitializeDefaultCollectionsResponse {
|
|
119
|
-
repeated UserCollection items = 1;
|
|
120
|
-
}
|