@mediaryorg/contracts 1.0.10 → 2.0.1
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 +8 -0
- package/dist/proto/paths.js +8 -0
- package/generated/auth/v1/auth.ts +21 -0
- package/generated/collection/v1/collection.ts +235 -0
- package/generated/favorite/v1/favorite.ts +146 -0
- package/generated/image/v1/image.ts +140 -0
- package/generated/library/v1/library.ts +216 -0
- package/generated/media/v1/media.ts +294 -0
- package/generated/media_request/v1/media_request.ts +223 -0
- package/generated/recommendation/v1/recommendation.ts +126 -0
- package/generated/search/v1/search.ts +103 -0
- package/package.json +3 -3
- package/proto/auth/v1/auth.proto +9 -0
- package/proto/collection/v1/collection.proto +120 -0
- package/proto/favorite/v1/favorite.proto +79 -0
- package/proto/image/v1/image.proto +73 -0
- package/proto/library/v1/library.proto +144 -0
- package/proto/media/v1/media.proto +197 -0
- package/proto/media_request/v1/media_request.proto +142 -0
- package/proto/recommendation/v1/recommendation.proto +60 -0
- package/proto/search/v1/search.proto +62 -0
|
@@ -0,0 +1,223 @@
|
|
|
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: media_request/v1/media_request.proto
|
|
6
|
+
|
|
7
|
+
/* eslint-disable */
|
|
8
|
+
import { GrpcMethod, GrpcStreamMethod } from "@nestjs/microservices";
|
|
9
|
+
import { Observable } from "rxjs";
|
|
10
|
+
import { MediaData, MediaSource } from "../../media/v1/media";
|
|
11
|
+
|
|
12
|
+
export const protobufPackage = "media_request.v1";
|
|
13
|
+
|
|
14
|
+
/** Mirrors prisma enum ModerationType. */
|
|
15
|
+
export enum ModerationStatus {
|
|
16
|
+
MODERATION_STATUS_UNSPECIFIED = 0,
|
|
17
|
+
MODERATION_STATUS_PENDING = 1,
|
|
18
|
+
MODERATION_STATUS_APPROVED = 2,
|
|
19
|
+
MODERATION_STATUS_REJECTED = 3,
|
|
20
|
+
UNRECOGNIZED = -1,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Lightweight reference to the user who acted on the request.
|
|
25
|
+
* Populated by the gateway / user-service when needed; kept self-contained.
|
|
26
|
+
*/
|
|
27
|
+
export interface MediaRequestUserRef {
|
|
28
|
+
id: string;
|
|
29
|
+
displayName: string;
|
|
30
|
+
picture: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface MediaRequest {
|
|
34
|
+
id: string;
|
|
35
|
+
status: ModerationStatus;
|
|
36
|
+
mediaData: MediaData | undefined;
|
|
37
|
+
searchableTitle: string;
|
|
38
|
+
externalIdsJson: string;
|
|
39
|
+
comment: string;
|
|
40
|
+
moderatorNote: string;
|
|
41
|
+
duplicateCheckStatus: string;
|
|
42
|
+
possibleDuplicatesJson: string;
|
|
43
|
+
requestedById: string;
|
|
44
|
+
requestedBy: MediaRequestUserRef | undefined;
|
|
45
|
+
moderatedById: string;
|
|
46
|
+
moderatedBy: MediaRequestUserRef | undefined;
|
|
47
|
+
approvedMediaId: string;
|
|
48
|
+
collectionId: string;
|
|
49
|
+
createdAt: string;
|
|
50
|
+
updatedAt: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface CreateMediaRequestRequest {
|
|
54
|
+
userId: string;
|
|
55
|
+
/** Currently only CUSTOM is accepted (TMDB content goes through search flow). */
|
|
56
|
+
source?: MediaSource | undefined;
|
|
57
|
+
mediaData: MediaData | undefined;
|
|
58
|
+
collectionId: string;
|
|
59
|
+
comment?: string | undefined;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface CreateMediaRequestResponse {
|
|
63
|
+
request: MediaRequest | undefined;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface GetUserRequestsRequest {
|
|
67
|
+
userId: string;
|
|
68
|
+
status?: ModerationStatus | undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface GetUserRequestsResponse {
|
|
72
|
+
items: MediaRequest[];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface GetMediaRequestByIdRequest {
|
|
76
|
+
requestId: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface GetMediaRequestByIdResponse {
|
|
80
|
+
request: MediaRequest | undefined;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface ListMediaRequestsRequest {
|
|
84
|
+
status?: ModerationStatus | undefined;
|
|
85
|
+
source?: MediaSource | undefined;
|
|
86
|
+
collectionId?: string | undefined;
|
|
87
|
+
search?: string | undefined;
|
|
88
|
+
requestedById?: string | undefined;
|
|
89
|
+
moderatedById?: string | undefined;
|
|
90
|
+
year?: number | undefined;
|
|
91
|
+
page: number;
|
|
92
|
+
limit: number;
|
|
93
|
+
sortBy: string;
|
|
94
|
+
sortOrder: string;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface MediaRequestPaginationMeta {
|
|
98
|
+
page: number;
|
|
99
|
+
limit: number;
|
|
100
|
+
total: number;
|
|
101
|
+
totalPages: number;
|
|
102
|
+
hasNextPage: boolean;
|
|
103
|
+
hasPrevPage: boolean;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface ListMediaRequestsResponse {
|
|
107
|
+
data: MediaRequest[];
|
|
108
|
+
meta: MediaRequestPaginationMeta | undefined;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface UpdateMediaRequestRequest {
|
|
112
|
+
requestId: string;
|
|
113
|
+
/** Only PENDING requests can be updated. */
|
|
114
|
+
mediaData?: MediaData | undefined;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface UpdateMediaRequestResponse {
|
|
118
|
+
request: MediaRequest | undefined;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface ModerateMediaRequestRequest {
|
|
122
|
+
requestId: string;
|
|
123
|
+
moderatorId: string;
|
|
124
|
+
/** APPROVED or REJECTED. */
|
|
125
|
+
status: ModerationStatus;
|
|
126
|
+
moderatorNote?: string | undefined;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface ModerateMediaRequestResponse {
|
|
130
|
+
request:
|
|
131
|
+
| MediaRequest
|
|
132
|
+
| undefined;
|
|
133
|
+
/** Populated when status == APPROVED. References media in media-service. */
|
|
134
|
+
approvedMediaId: string;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface DeleteMediaRequestRequest {
|
|
138
|
+
requestId: string;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface DeleteMediaRequestResponse {
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export const MEDIA_REQUEST_V1_PACKAGE_NAME = "media_request.v1";
|
|
145
|
+
|
|
146
|
+
export interface MediaRequestServiceClient {
|
|
147
|
+
/** User-facing endpoints. */
|
|
148
|
+
|
|
149
|
+
createMediaRequest(request: CreateMediaRequestRequest): Observable<CreateMediaRequestResponse>;
|
|
150
|
+
|
|
151
|
+
getUserRequests(request: GetUserRequestsRequest): Observable<GetUserRequestsResponse>;
|
|
152
|
+
|
|
153
|
+
getMediaRequestById(request: GetMediaRequestByIdRequest): Observable<GetMediaRequestByIdResponse>;
|
|
154
|
+
|
|
155
|
+
/** Admin / moderator endpoints. */
|
|
156
|
+
|
|
157
|
+
listMediaRequests(request: ListMediaRequestsRequest): Observable<ListMediaRequestsResponse>;
|
|
158
|
+
|
|
159
|
+
updateMediaRequest(request: UpdateMediaRequestRequest): Observable<UpdateMediaRequestResponse>;
|
|
160
|
+
|
|
161
|
+
moderateMediaRequest(request: ModerateMediaRequestRequest): Observable<ModerateMediaRequestResponse>;
|
|
162
|
+
|
|
163
|
+
deleteMediaRequest(request: DeleteMediaRequestRequest): Observable<DeleteMediaRequestResponse>;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export interface MediaRequestServiceController {
|
|
167
|
+
/** User-facing endpoints. */
|
|
168
|
+
|
|
169
|
+
createMediaRequest(
|
|
170
|
+
request: CreateMediaRequestRequest,
|
|
171
|
+
): Promise<CreateMediaRequestResponse> | Observable<CreateMediaRequestResponse> | CreateMediaRequestResponse;
|
|
172
|
+
|
|
173
|
+
getUserRequests(
|
|
174
|
+
request: GetUserRequestsRequest,
|
|
175
|
+
): Promise<GetUserRequestsResponse> | Observable<GetUserRequestsResponse> | GetUserRequestsResponse;
|
|
176
|
+
|
|
177
|
+
getMediaRequestById(
|
|
178
|
+
request: GetMediaRequestByIdRequest,
|
|
179
|
+
): Promise<GetMediaRequestByIdResponse> | Observable<GetMediaRequestByIdResponse> | GetMediaRequestByIdResponse;
|
|
180
|
+
|
|
181
|
+
/** Admin / moderator endpoints. */
|
|
182
|
+
|
|
183
|
+
listMediaRequests(
|
|
184
|
+
request: ListMediaRequestsRequest,
|
|
185
|
+
): Promise<ListMediaRequestsResponse> | Observable<ListMediaRequestsResponse> | ListMediaRequestsResponse;
|
|
186
|
+
|
|
187
|
+
updateMediaRequest(
|
|
188
|
+
request: UpdateMediaRequestRequest,
|
|
189
|
+
): Promise<UpdateMediaRequestResponse> | Observable<UpdateMediaRequestResponse> | UpdateMediaRequestResponse;
|
|
190
|
+
|
|
191
|
+
moderateMediaRequest(
|
|
192
|
+
request: ModerateMediaRequestRequest,
|
|
193
|
+
): Promise<ModerateMediaRequestResponse> | Observable<ModerateMediaRequestResponse> | ModerateMediaRequestResponse;
|
|
194
|
+
|
|
195
|
+
deleteMediaRequest(
|
|
196
|
+
request: DeleteMediaRequestRequest,
|
|
197
|
+
): Promise<DeleteMediaRequestResponse> | Observable<DeleteMediaRequestResponse> | DeleteMediaRequestResponse;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export function MediaRequestServiceControllerMethods() {
|
|
201
|
+
return function (constructor: Function) {
|
|
202
|
+
const grpcMethods: string[] = [
|
|
203
|
+
"createMediaRequest",
|
|
204
|
+
"getUserRequests",
|
|
205
|
+
"getMediaRequestById",
|
|
206
|
+
"listMediaRequests",
|
|
207
|
+
"updateMediaRequest",
|
|
208
|
+
"moderateMediaRequest",
|
|
209
|
+
"deleteMediaRequest",
|
|
210
|
+
];
|
|
211
|
+
for (const method of grpcMethods) {
|
|
212
|
+
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|
|
213
|
+
GrpcMethod("MediaRequestService", method)(constructor.prototype[method], method, descriptor);
|
|
214
|
+
}
|
|
215
|
+
const grpcStreamMethods: string[] = [];
|
|
216
|
+
for (const method of grpcStreamMethods) {
|
|
217
|
+
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|
|
218
|
+
GrpcStreamMethod("MediaRequestService", method)(constructor.prototype[method], method, descriptor);
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export const MEDIA_REQUEST_SERVICE_NAME = "MediaRequestService";
|
|
@@ -0,0 +1,126 @@
|
|
|
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: recommendation/v1/recommendation.proto
|
|
6
|
+
|
|
7
|
+
/* eslint-disable */
|
|
8
|
+
import { GrpcMethod, GrpcStreamMethod } from "@nestjs/microservices";
|
|
9
|
+
import { Observable } from "rxjs";
|
|
10
|
+
import { SearchMediaType } from "../../search/v1/search";
|
|
11
|
+
|
|
12
|
+
export const protobufPackage = "recommendation.v1";
|
|
13
|
+
|
|
14
|
+
export interface MediaRecommendationItem {
|
|
15
|
+
mediaType: SearchMediaType;
|
|
16
|
+
title: string;
|
|
17
|
+
year?: number | undefined;
|
|
18
|
+
genres: string[];
|
|
19
|
+
rating?:
|
|
20
|
+
| number
|
|
21
|
+
| undefined;
|
|
22
|
+
/** Absolute HTTPS poster URL (already passed through ImageService). */
|
|
23
|
+
posterUrl: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface RecommendationBlock {
|
|
27
|
+
visible: boolean;
|
|
28
|
+
items: MediaRecommendationItem[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface GetHomeRecommendationsRequest {
|
|
32
|
+
/** Empty string => anonymous request (only trending + topRated are filled). */
|
|
33
|
+
userId: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface GetHomeRecommendationsResponse {
|
|
37
|
+
trending: RecommendationBlock | undefined;
|
|
38
|
+
topRated: RecommendationBlock | undefined;
|
|
39
|
+
recommendedForYou: RecommendationBlock | undefined;
|
|
40
|
+
fromYourLibrary: RecommendationBlock | undefined;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface RefreshGlobalBlocksRequest {
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface RefreshGlobalBlocksResponse {
|
|
47
|
+
trendingCount: number;
|
|
48
|
+
topRatedCount: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface RefreshUserRecommendationsRequest {
|
|
52
|
+
userId: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface RefreshUserRecommendationsResponse {
|
|
56
|
+
itemsCount: number;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const RECOMMENDATION_V1_PACKAGE_NAME = "recommendation.v1";
|
|
60
|
+
|
|
61
|
+
export interface RecommendationServiceClient {
|
|
62
|
+
/**
|
|
63
|
+
* Bundles all four blocks shown on the home screen (trending / topRated /
|
|
64
|
+
* recommendedForYou / fromYourLibrary). When `user_id` is empty only the
|
|
65
|
+
* global blocks are populated.
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
getHomeRecommendations(request: GetHomeRecommendationsRequest): Observable<GetHomeRecommendationsResponse>;
|
|
69
|
+
|
|
70
|
+
/** Force-refresh the global cached blocks (used by the cron job). */
|
|
71
|
+
|
|
72
|
+
refreshGlobalBlocks(request: RefreshGlobalBlocksRequest): Observable<RefreshGlobalBlocksResponse>;
|
|
73
|
+
|
|
74
|
+
/** Force-refresh a personal block for a given user. */
|
|
75
|
+
|
|
76
|
+
refreshUserRecommendations(
|
|
77
|
+
request: RefreshUserRecommendationsRequest,
|
|
78
|
+
): Observable<RefreshUserRecommendationsResponse>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface RecommendationServiceController {
|
|
82
|
+
/**
|
|
83
|
+
* Bundles all four blocks shown on the home screen (trending / topRated /
|
|
84
|
+
* recommendedForYou / fromYourLibrary). When `user_id` is empty only the
|
|
85
|
+
* global blocks are populated.
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
getHomeRecommendations(
|
|
89
|
+
request: GetHomeRecommendationsRequest,
|
|
90
|
+
):
|
|
91
|
+
| Promise<GetHomeRecommendationsResponse>
|
|
92
|
+
| Observable<GetHomeRecommendationsResponse>
|
|
93
|
+
| GetHomeRecommendationsResponse;
|
|
94
|
+
|
|
95
|
+
/** Force-refresh the global cached blocks (used by the cron job). */
|
|
96
|
+
|
|
97
|
+
refreshGlobalBlocks(
|
|
98
|
+
request: RefreshGlobalBlocksRequest,
|
|
99
|
+
): Promise<RefreshGlobalBlocksResponse> | Observable<RefreshGlobalBlocksResponse> | RefreshGlobalBlocksResponse;
|
|
100
|
+
|
|
101
|
+
/** Force-refresh a personal block for a given user. */
|
|
102
|
+
|
|
103
|
+
refreshUserRecommendations(
|
|
104
|
+
request: RefreshUserRecommendationsRequest,
|
|
105
|
+
):
|
|
106
|
+
| Promise<RefreshUserRecommendationsResponse>
|
|
107
|
+
| Observable<RefreshUserRecommendationsResponse>
|
|
108
|
+
| RefreshUserRecommendationsResponse;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function RecommendationServiceControllerMethods() {
|
|
112
|
+
return function (constructor: Function) {
|
|
113
|
+
const grpcMethods: string[] = ["getHomeRecommendations", "refreshGlobalBlocks", "refreshUserRecommendations"];
|
|
114
|
+
for (const method of grpcMethods) {
|
|
115
|
+
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|
|
116
|
+
GrpcMethod("RecommendationService", method)(constructor.prototype[method], method, descriptor);
|
|
117
|
+
}
|
|
118
|
+
const grpcStreamMethods: string[] = [];
|
|
119
|
+
for (const method of grpcStreamMethods) {
|
|
120
|
+
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|
|
121
|
+
GrpcStreamMethod("RecommendationService", method)(constructor.prototype[method], method, descriptor);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export const RECOMMENDATION_SERVICE_NAME = "RecommendationService";
|
|
@@ -0,0 +1,103 @@
|
|
|
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: search/v1/search.proto
|
|
6
|
+
|
|
7
|
+
/* eslint-disable */
|
|
8
|
+
import { GrpcMethod, GrpcStreamMethod } from "@nestjs/microservices";
|
|
9
|
+
import { Observable } from "rxjs";
|
|
10
|
+
|
|
11
|
+
export const protobufPackage = "search.v1";
|
|
12
|
+
|
|
13
|
+
/** Logical media types accepted by `mediaType` filter and returned in `type`. */
|
|
14
|
+
export enum SearchMediaType {
|
|
15
|
+
SEARCH_MEDIA_TYPE_UNSPECIFIED = 0,
|
|
16
|
+
SEARCH_MEDIA_TYPE_MOVIE = 1,
|
|
17
|
+
SEARCH_MEDIA_TYPE_SERIES = 2,
|
|
18
|
+
SEARCH_MEDIA_TYPE_BOOK = 3,
|
|
19
|
+
SEARCH_MEDIA_TYPE_ANIME = 4,
|
|
20
|
+
SEARCH_MEDIA_TYPE_MANGA = 5,
|
|
21
|
+
SEARCH_MEDIA_TYPE_MANHWA = 6,
|
|
22
|
+
SEARCH_MEDIA_TYPE_GAME = 7,
|
|
23
|
+
SEARCH_MEDIA_TYPE_KDRAMA = 8,
|
|
24
|
+
UNRECOGNIZED = -1,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Origin of the result. "local" means the row already lives in our database. */
|
|
28
|
+
export enum SearchSource {
|
|
29
|
+
SEARCH_SOURCE_UNSPECIFIED = 0,
|
|
30
|
+
SEARCH_SOURCE_TMDB = 1,
|
|
31
|
+
SEARCH_SOURCE_GOOGLE_BOOKS = 2,
|
|
32
|
+
SEARCH_SOURCE_OPEN_LIBRARY = 3,
|
|
33
|
+
SEARCH_SOURCE_ANILIST = 4,
|
|
34
|
+
SEARCH_SOURCE_MANGADEX = 5,
|
|
35
|
+
SEARCH_SOURCE_IGDB = 6,
|
|
36
|
+
SEARCH_SOURCE_RAWG = 7,
|
|
37
|
+
SEARCH_SOURCE_LOCAL = 8,
|
|
38
|
+
UNRECOGNIZED = -1,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface SearchResult {
|
|
42
|
+
/** External id (or local Media.id when source == LOCAL). */
|
|
43
|
+
id: string;
|
|
44
|
+
title: string;
|
|
45
|
+
subtitle: string;
|
|
46
|
+
description: string;
|
|
47
|
+
imageUrl: string;
|
|
48
|
+
/** Year as string because some sources return imprecise dates ("2020-.."). */
|
|
49
|
+
year: string;
|
|
50
|
+
rating?: number | undefined;
|
|
51
|
+
genres: string[];
|
|
52
|
+
type: SearchMediaType;
|
|
53
|
+
source: SearchSource;
|
|
54
|
+
externalId: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface SearchRequest {
|
|
58
|
+
query: string;
|
|
59
|
+
mediaType?: SearchMediaType | undefined;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface SearchResponse {
|
|
63
|
+
results: SearchResult[];
|
|
64
|
+
totalResults: number;
|
|
65
|
+
hasMore: boolean;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export const SEARCH_V1_PACKAGE_NAME = "search.v1";
|
|
69
|
+
|
|
70
|
+
export interface SearchServiceClient {
|
|
71
|
+
/**
|
|
72
|
+
* Cross-source search aggregator (TMDB, Google Books, AniList, MangaDex, IGDB,
|
|
73
|
+
* RAWG, Open Library + local db). Mirrors GET /search?query=&mediaType=.
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
search(request: SearchRequest): Observable<SearchResponse>;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface SearchServiceController {
|
|
80
|
+
/**
|
|
81
|
+
* Cross-source search aggregator (TMDB, Google Books, AniList, MangaDex, IGDB,
|
|
82
|
+
* RAWG, Open Library + local db). Mirrors GET /search?query=&mediaType=.
|
|
83
|
+
*/
|
|
84
|
+
|
|
85
|
+
search(request: SearchRequest): Promise<SearchResponse> | Observable<SearchResponse> | SearchResponse;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function SearchServiceControllerMethods() {
|
|
89
|
+
return function (constructor: Function) {
|
|
90
|
+
const grpcMethods: string[] = ["search"];
|
|
91
|
+
for (const method of grpcMethods) {
|
|
92
|
+
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|
|
93
|
+
GrpcMethod("SearchService", method)(constructor.prototype[method], method, descriptor);
|
|
94
|
+
}
|
|
95
|
+
const grpcStreamMethods: string[] = [];
|
|
96
|
+
for (const method of grpcStreamMethods) {
|
|
97
|
+
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|
|
98
|
+
GrpcStreamMethod("SearchService", method)(constructor.prototype[method], method, descriptor);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export const SEARCH_SERVICE_NAME = "SearchService";
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mediaryorg/contracts",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
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 --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 --plugin=protoc-gen-ts_proto=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_out=./generated --ts_proto_opt=nestJs=true,package=omit",
|
|
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\\collection\\v1\\collection.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/collection/v1/collection.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 {}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package collection.v1;
|
|
4
|
+
|
|
5
|
+
service CollectionService {
|
|
6
|
+
// Global catalog of media collections (Movies, Series, Books, Manga, Manhwa, Anime, Games, KDramas).
|
|
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
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package favorite.v1;
|
|
4
|
+
|
|
5
|
+
service FavoriteService {
|
|
6
|
+
rpc CheckMultipleFavorites(CheckMultipleFavoritesRequest) returns (CheckMultipleFavoritesResponse);
|
|
7
|
+
rpc ToggleFavorite(ToggleFavoriteRequest) returns (ToggleFavoriteResponse);
|
|
8
|
+
rpc IsFavorite(IsFavoriteRequest) returns (IsFavoriteResponse);
|
|
9
|
+
rpc ListUserFavorites(ListUserFavoritesRequest) returns (ListUserFavoritesResponse);
|
|
10
|
+
rpc RemoveAllForMedia(RemoveAllForMediaRequest) returns (RemoveAllForMediaResponse);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
message Favorite {
|
|
14
|
+
string id = 1;
|
|
15
|
+
string user_id = 2;
|
|
16
|
+
string media_id = 3;
|
|
17
|
+
string created_at = 4;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
message CheckMultipleFavoritesRequest {
|
|
21
|
+
string user_id = 1;
|
|
22
|
+
repeated string media_ids = 2;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// `results` is a `media_id -> bool` map (matches the legacy REST shape).
|
|
26
|
+
message CheckMultipleFavoritesResponse {
|
|
27
|
+
map<string, bool> results = 1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
message ToggleFavoriteRequest {
|
|
31
|
+
string user_id = 1;
|
|
32
|
+
string media_id = 2;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
message ToggleFavoriteResponse {
|
|
36
|
+
bool is_in_favorites = 1;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
message IsFavoriteRequest {
|
|
40
|
+
string user_id = 1;
|
|
41
|
+
string media_id = 2;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
message IsFavoriteResponse {
|
|
45
|
+
bool is_in_favorites = 1;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
message ListUserFavoritesRequest {
|
|
49
|
+
string user_id = 1;
|
|
50
|
+
optional string search = 2;
|
|
51
|
+
optional string collection_id = 3;
|
|
52
|
+
int32 page = 4;
|
|
53
|
+
int32 limit = 5;
|
|
54
|
+
string sort_by = 6;
|
|
55
|
+
string sort_order = 7;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
message FavoritePaginationMeta {
|
|
59
|
+
int32 page = 1;
|
|
60
|
+
int32 limit = 2;
|
|
61
|
+
int32 total = 3;
|
|
62
|
+
int32 total_pages = 4;
|
|
63
|
+
bool has_next_page = 5;
|
|
64
|
+
bool has_prev_page = 6;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
message ListUserFavoritesResponse {
|
|
68
|
+
repeated Favorite data = 1;
|
|
69
|
+
FavoritePaginationMeta meta = 2;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Used as a side-effect by library/media when content disappears.
|
|
73
|
+
message RemoveAllForMediaRequest {
|
|
74
|
+
string media_id = 1;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
message RemoveAllForMediaResponse {
|
|
78
|
+
int32 removed_count = 1;
|
|
79
|
+
}
|