itube-specs 0.0.779 → 0.0.781
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/package.json +6 -1
- package/services/__tests__/site-data.service.test.ts +61 -0
- package/services/api/authorization.service.ts +172 -0
- package/services/api/categories.service.ts +239 -0
- package/services/api/channels.service.ts +101 -0
- package/services/api/contacts.service.ts +22 -0
- package/services/api/dictionaries.service.ts +34 -0
- package/services/api/models.service.ts +315 -0
- package/services/api/playlists.service.ts +250 -0
- package/services/api/search.service.ts +63 -0
- package/services/api/videos.service.ts +558 -0
- package/services/site-data.service.ts +72 -0
- package/utils/__tests__/get-sorted-filter-groups.test.ts +28 -0
- package/utils/__tests__/parse-filter-categories.test.ts +21 -0
- package/utils/__tests__/sort-filter-radio-options.test.ts +23 -0
- package/utils/category-letter-groups/__tests__/group-by-first-letter.test.ts +42 -0
- package/utils/category-letter-groups/group-by-first-letter.ts +25 -0
- package/utils/filter-main/__tests__/build-filter-query.test.ts +56 -0
- package/utils/filter-main/__tests__/get-active-filter-values.test.ts +22 -0
- package/utils/filter-main/__tests__/parse-category-filter-values.test.ts +20 -0
- package/utils/filter-main/build-filter-query.ts +42 -0
- package/utils/filter-main/get-active-filter-values.ts +33 -0
- package/utils/filter-main/parse-category-filter-values.ts +15 -0
- package/utils/filter-slider/__tests__/build-range-filter-query.test.ts +39 -0
- package/utils/filter-slider/__tests__/get-slider-range-info.test.ts +28 -0
- package/utils/filter-slider/build-range-filter-query.ts +32 -0
- package/utils/filter-slider/get-slider-range-info.ts +28 -0
- package/utils/get-sorted-filter-groups.ts +13 -0
- package/utils/info-main/__tests__/group-parameters-by-group.test.ts +42 -0
- package/utils/info-main/group-parameters-by-group.ts +37 -0
- package/utils/iso-code-map.ts +2 -0
- package/utils/parse-filter-categories.ts +14 -0
- package/utils/player-channel/__tests__/get-name-initials.test.ts +24 -0
- package/utils/player-channel/get-name-initials.ts +11 -0
- package/utils/player-like/__tests__/apply-reaction.test.ts +28 -0
- package/utils/player-like/__tests__/get-reaction-percents.test.ts +16 -0
- package/utils/player-like/apply-reaction.ts +23 -0
- package/utils/player-like/get-reaction-percents.ts +19 -0
- package/utils/search-result/__tests__/build-search-tabs.test.ts +28 -0
- package/utils/search-result/build-search-tabs.ts +19 -0
- package/utils/section-seo-text/__tests__/split-text-by-keyword-links.test.ts +46 -0
- package/utils/section-seo-text/split-text-by-keyword-links.ts +60 -0
- package/utils/sort-filter-radio-options.ts +18 -0
- package/utils/ui-full-descr/__tests__/split-paragraphs.test.ts +24 -0
- package/utils/ui-full-descr/split-paragraphs.ts +12 -0
- package/utils/ui-pagination/__tests__/get-pagination-link.test.ts +24 -0
- package/utils/ui-pagination/__tests__/get-pagination-numbers.test.ts +18 -0
- package/utils/ui-pagination/get-pagination-link.ts +34 -0
- package/utils/ui-pagination/get-pagination-numbers.ts +14 -0
- package/components/auth/__tests__/login.test.ts +0 -123
- package/components/auth/__tests__/recovery.test.ts +0 -86
- package/components/auth/__tests__/register.test.ts +0 -122
- package/components/player/__tests__/like.test.ts +0 -85
- package/components/playlist/__tests__/add.test.ts +0 -115
- package/components/playlist/__tests__/edit.test.ts +0 -91
- package/components/profile/__tests__/password.test.ts +0 -60
- package/components/profile/__tests__/setup.test.ts +0 -100
- package/components/report/__tests__/main.test.ts +0 -106
- package/composables/__tests__/use-next-video.test.ts +0 -123
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
import type { Language } from '../../runtime';
|
|
2
|
+
import { ApiHelper, toHeaderLanguage } from '../../runtime';
|
|
3
|
+
import type { RequestPagination, PaginatedResponse, IRequestVideoFilter, IReportForm, IVideoData, IVideoCard, IPopularTags } from '../../types';
|
|
4
|
+
|
|
5
|
+
function getSafeReferrer(): string {
|
|
6
|
+
if (!document.referrer) return '';
|
|
7
|
+
try {
|
|
8
|
+
const url = new URL(document.referrer);
|
|
9
|
+
return url.origin + url.pathname;
|
|
10
|
+
} catch {
|
|
11
|
+
return '';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Сервис для работы с API видеороликов */
|
|
16
|
+
/** Сервис для работы с API видеороликов */
|
|
17
|
+
export class VideosApiService {
|
|
18
|
+
static async getSearchByNiche(
|
|
19
|
+
pagination: RequestPagination,
|
|
20
|
+
lang: Language,
|
|
21
|
+
phrase: string,
|
|
22
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
23
|
+
): Promise<PaginatedResponse<IVideoCard>> {
|
|
24
|
+
return await ApiHelper.fetch(
|
|
25
|
+
'/videos/video-search-by-niche',
|
|
26
|
+
{
|
|
27
|
+
method: 'POST',
|
|
28
|
+
headers: {
|
|
29
|
+
'X-Niche': niche,
|
|
30
|
+
'X-Language': toHeaderLanguage(lang),
|
|
31
|
+
'X-Cache-Time': '259200',
|
|
32
|
+
'Content-Type': 'application/json',
|
|
33
|
+
},
|
|
34
|
+
params: {
|
|
35
|
+
...pagination,
|
|
36
|
+
},
|
|
37
|
+
body: {
|
|
38
|
+
query: phrase,
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
useRuntimeConfig(),
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
static getSearchByNicheFiltered(phrase: string) {
|
|
46
|
+
return async (
|
|
47
|
+
lang: Language,
|
|
48
|
+
pagination: RequestPagination,
|
|
49
|
+
videosFilter: IRequestVideoFilter,
|
|
50
|
+
order: string,
|
|
51
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
52
|
+
): Promise<PaginatedResponse<IVideoCard>> => {
|
|
53
|
+
return await ApiHelper.fetch(
|
|
54
|
+
'/videos/video-search-by-niche',
|
|
55
|
+
{
|
|
56
|
+
method: 'POST',
|
|
57
|
+
headers: {
|
|
58
|
+
'X-Niche': niche,
|
|
59
|
+
'X-Language': toHeaderLanguage(lang),
|
|
60
|
+
'X-Cache-Time': '259200',
|
|
61
|
+
'Content-Type': 'application/json',
|
|
62
|
+
},
|
|
63
|
+
params: {
|
|
64
|
+
...pagination,
|
|
65
|
+
order,
|
|
66
|
+
},
|
|
67
|
+
body: {
|
|
68
|
+
query: phrase,
|
|
69
|
+
filter_request: videosFilter,
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
useRuntimeConfig(),
|
|
73
|
+
);
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
static async sendVideoAbuse(
|
|
77
|
+
data: IReportForm,
|
|
78
|
+
videoGuid: string,
|
|
79
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
80
|
+
) {
|
|
81
|
+
return await ApiHelper.fetch(
|
|
82
|
+
`/videos/send-video-abuse/${videoGuid}`,
|
|
83
|
+
{
|
|
84
|
+
method: 'POST',
|
|
85
|
+
headers: {
|
|
86
|
+
'X-Niche': niche,
|
|
87
|
+
'X-Cache-Time': '259200',
|
|
88
|
+
'Content-Type': 'application/json',
|
|
89
|
+
},
|
|
90
|
+
body: data
|
|
91
|
+
},
|
|
92
|
+
useRuntimeConfig(),
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
static async refererPhrasesById(
|
|
96
|
+
lang: Language,
|
|
97
|
+
id: string,
|
|
98
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
99
|
+
): Promise<string[]> {
|
|
100
|
+
return await ApiHelper.fetch(
|
|
101
|
+
`/videos/referer-phrases-by-id/${id}`,
|
|
102
|
+
{
|
|
103
|
+
method: 'GET',
|
|
104
|
+
headers: {
|
|
105
|
+
'X-Niche': niche,
|
|
106
|
+
'X-Language': toHeaderLanguage(lang),
|
|
107
|
+
'X-Cache-Time': '259200',
|
|
108
|
+
'Content-Type': 'application/json',
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
useRuntimeConfig(),
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
static async refererPhrasesByUrl(
|
|
115
|
+
lang: Language,
|
|
116
|
+
id: string,
|
|
117
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
118
|
+
): Promise<string[]> {
|
|
119
|
+
return await ApiHelper.fetch(
|
|
120
|
+
`/videos/referer-phrases-by-url/${id}`,
|
|
121
|
+
{
|
|
122
|
+
method: 'GET',
|
|
123
|
+
headers: {
|
|
124
|
+
'X-Niche': niche,
|
|
125
|
+
'X-Language': toHeaderLanguage(lang),
|
|
126
|
+
'X-Cache-Time': '259200',
|
|
127
|
+
'Content-Type': 'application/json',
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
useRuntimeConfig(),
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
static async getRelatedVideosById(
|
|
134
|
+
pagination: RequestPagination,
|
|
135
|
+
lang: Language,
|
|
136
|
+
id: string,
|
|
137
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
138
|
+
): Promise<PaginatedResponse<IVideoCard>> {
|
|
139
|
+
return await ApiHelper.fetch(
|
|
140
|
+
`/videos/get-related-videos-by-id/${id}`,
|
|
141
|
+
{
|
|
142
|
+
method: 'GET',
|
|
143
|
+
headers: {
|
|
144
|
+
'X-Niche': niche,
|
|
145
|
+
'X-Language': toHeaderLanguage(lang),
|
|
146
|
+
'X-Cache-Time': '259200',
|
|
147
|
+
'Content-Type': 'application/json',
|
|
148
|
+
},
|
|
149
|
+
params: {
|
|
150
|
+
...pagination,
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
useRuntimeConfig(),
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
static async getRelatedVideosByUrl(
|
|
157
|
+
pagination: RequestPagination,
|
|
158
|
+
lang: Language,
|
|
159
|
+
url: string,
|
|
160
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
161
|
+
): Promise<PaginatedResponse<IVideoCard>> {
|
|
162
|
+
return await ApiHelper.fetch(
|
|
163
|
+
`/videos/get-related-videos-by-url/${url}`,
|
|
164
|
+
{
|
|
165
|
+
method: 'GET',
|
|
166
|
+
headers: {
|
|
167
|
+
'X-Niche': niche,
|
|
168
|
+
'X-Language': toHeaderLanguage(lang),
|
|
169
|
+
'X-Cache-Time': '259200',
|
|
170
|
+
'Content-Type': 'application/json',
|
|
171
|
+
},
|
|
172
|
+
params: {
|
|
173
|
+
...pagination,
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
useRuntimeConfig(),
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
static async getVideoById(
|
|
181
|
+
lang: Language,
|
|
182
|
+
id: string,
|
|
183
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
184
|
+
headers = {} as HeadersInit,
|
|
185
|
+
): Promise<IVideoData> {
|
|
186
|
+
return await ApiHelper.fetch(
|
|
187
|
+
`/videos/get-video-by-id/${id}`,
|
|
188
|
+
{
|
|
189
|
+
method: 'GET',
|
|
190
|
+
headers: {
|
|
191
|
+
...headers,
|
|
192
|
+
'X-Niche': niche,
|
|
193
|
+
'X-Language': toHeaderLanguage(lang),
|
|
194
|
+
'X-Cache-Time': '259200',
|
|
195
|
+
'Content-Type': 'application/json',
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
useRuntimeConfig(),
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
static async getVideoByUrl(
|
|
203
|
+
lang: Language,
|
|
204
|
+
url: string,
|
|
205
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
206
|
+
headers = {} as HeadersInit,
|
|
207
|
+
): Promise<IVideoData> {
|
|
208
|
+
return await ApiHelper.fetch(
|
|
209
|
+
`/videos/get-video-by-url/${url}`,
|
|
210
|
+
{
|
|
211
|
+
method: 'GET',
|
|
212
|
+
headers: {
|
|
213
|
+
...headers,
|
|
214
|
+
'X-Niche': niche,
|
|
215
|
+
'X-Language': toHeaderLanguage(lang),
|
|
216
|
+
'X-Cache-Time': '259200',
|
|
217
|
+
'Content-Type': 'application/json',
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
useRuntimeConfig(),
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
static async videoLike(
|
|
225
|
+
md: string,
|
|
226
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
227
|
+
): Promise<IVideoData> {
|
|
228
|
+
return await ApiHelper.fetch(
|
|
229
|
+
`/videos/video-like/${md}`,
|
|
230
|
+
{
|
|
231
|
+
method: 'POST',
|
|
232
|
+
headers: {
|
|
233
|
+
'X-Niche': niche,
|
|
234
|
+
'X-Cache-Time': '259200',
|
|
235
|
+
'Content-Type': 'application/json',
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
useRuntimeConfig(),
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
static async videoDislike(
|
|
243
|
+
md: string,
|
|
244
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
245
|
+
): Promise<IVideoData> {
|
|
246
|
+
return await ApiHelper.fetch(
|
|
247
|
+
`/videos/video-dislike/${md}`,
|
|
248
|
+
{
|
|
249
|
+
method: 'POST',
|
|
250
|
+
headers: {
|
|
251
|
+
'X-Niche': niche,
|
|
252
|
+
'X-Cache-Time': '259200',
|
|
253
|
+
'Content-Type': 'application/json',
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
useRuntimeConfig(),
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
static async videoView(
|
|
261
|
+
md: string,
|
|
262
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
263
|
+
): Promise<IVideoData> {
|
|
264
|
+
return await ApiHelper.fetch(
|
|
265
|
+
`/videos/video-view/${md}`,
|
|
266
|
+
{
|
|
267
|
+
method: 'POST',
|
|
268
|
+
headers: {
|
|
269
|
+
'X-Niche': niche,
|
|
270
|
+
'X-Cache-Time': '259200',
|
|
271
|
+
'Content-Type': 'application/json',
|
|
272
|
+
},
|
|
273
|
+
body: {
|
|
274
|
+
referer: getSafeReferrer(),
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
useRuntimeConfig(),
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
static async getListByNiche(
|
|
282
|
+
lang: Language,
|
|
283
|
+
pagination: RequestPagination,
|
|
284
|
+
videosFilter: IRequestVideoFilter,
|
|
285
|
+
order: string,
|
|
286
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
287
|
+
): Promise<PaginatedResponse<IVideoCard>> {
|
|
288
|
+
return await ApiHelper.fetch(
|
|
289
|
+
'/videos/list-by-niche',
|
|
290
|
+
{
|
|
291
|
+
method: 'POST',
|
|
292
|
+
headers: {
|
|
293
|
+
'X-Niche': niche,
|
|
294
|
+
'X-Language': toHeaderLanguage(lang),
|
|
295
|
+
'X-Cache-Time': '259200',
|
|
296
|
+
'Content-Type': 'application/json',
|
|
297
|
+
'X-Country-Code': useState<string>('clientCountryCode').value || '',
|
|
298
|
+
},
|
|
299
|
+
params: {
|
|
300
|
+
...pagination,
|
|
301
|
+
order,
|
|
302
|
+
},
|
|
303
|
+
body: {
|
|
304
|
+
filter_request: videosFilter,
|
|
305
|
+
max_limit: 0,
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
useRuntimeConfig(),
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
static async getListByNicheAndCategory(
|
|
313
|
+
lang: Language,
|
|
314
|
+
pagination: RequestPagination,
|
|
315
|
+
videosFilter: IRequestVideoFilter,
|
|
316
|
+
category: string,
|
|
317
|
+
order: string,
|
|
318
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
319
|
+
): Promise<PaginatedResponse<IVideoCard>> {
|
|
320
|
+
return await ApiHelper.fetch(
|
|
321
|
+
'/videos/list-by-niche-and-category',
|
|
322
|
+
{
|
|
323
|
+
method: 'POST',
|
|
324
|
+
headers: {
|
|
325
|
+
'X-Niche': niche,
|
|
326
|
+
'X-Language': toHeaderLanguage(lang),
|
|
327
|
+
'X-Cache-Time': '259200',
|
|
328
|
+
'Content-Type': 'application/json',
|
|
329
|
+
},
|
|
330
|
+
params: {
|
|
331
|
+
...pagination,
|
|
332
|
+
order,
|
|
333
|
+
},
|
|
334
|
+
body: {
|
|
335
|
+
filter_request: videosFilter,
|
|
336
|
+
category: category,
|
|
337
|
+
max_limit: 100,
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
useRuntimeConfig(),
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
static async getListByNicheAndModel(
|
|
345
|
+
pagination: RequestPagination,
|
|
346
|
+
videosFilter: IRequestVideoFilter,
|
|
347
|
+
model: string,
|
|
348
|
+
lang: Language,
|
|
349
|
+
order: string,
|
|
350
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
351
|
+
): Promise<PaginatedResponse<IVideoCard>> {
|
|
352
|
+
return await ApiHelper.fetch(
|
|
353
|
+
'/videos/list-by-niche-and-model',
|
|
354
|
+
{
|
|
355
|
+
method: 'POST',
|
|
356
|
+
headers: {
|
|
357
|
+
'X-Niche': niche,
|
|
358
|
+
'X-Language': toHeaderLanguage(lang),
|
|
359
|
+
'X-Cache-Time': '259200',
|
|
360
|
+
'Content-Type': 'application/json',
|
|
361
|
+
},
|
|
362
|
+
params: {
|
|
363
|
+
...pagination,
|
|
364
|
+
order,
|
|
365
|
+
},
|
|
366
|
+
body: {
|
|
367
|
+
filter_request: videosFilter,
|
|
368
|
+
model: model,
|
|
369
|
+
max_limit: 100,
|
|
370
|
+
}
|
|
371
|
+
},
|
|
372
|
+
useRuntimeConfig(),
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
static async getListByNicheAndModelAndTag(
|
|
377
|
+
pagination: RequestPagination,
|
|
378
|
+
videosFilter: IRequestVideoFilter,
|
|
379
|
+
model: string,
|
|
380
|
+
tag: string,
|
|
381
|
+
lang: Language,
|
|
382
|
+
order: string,
|
|
383
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
384
|
+
): Promise<PaginatedResponse<IVideoCard>> {
|
|
385
|
+
return await ApiHelper.fetch(
|
|
386
|
+
'/videos/list-by-niche-and-model-and-tag',
|
|
387
|
+
{
|
|
388
|
+
method: 'POST',
|
|
389
|
+
headers: {
|
|
390
|
+
'X-Niche': niche,
|
|
391
|
+
'X-Language': toHeaderLanguage(lang),
|
|
392
|
+
'X-Cache-Time': '259200',
|
|
393
|
+
'Content-Type': 'application/json',
|
|
394
|
+
},
|
|
395
|
+
params: {
|
|
396
|
+
...pagination,
|
|
397
|
+
order,
|
|
398
|
+
},
|
|
399
|
+
body: {
|
|
400
|
+
filter_request: videosFilter,
|
|
401
|
+
model: model,
|
|
402
|
+
tag: tag,
|
|
403
|
+
max_limit: 100,
|
|
404
|
+
}
|
|
405
|
+
},
|
|
406
|
+
useRuntimeConfig(),
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
static async getListByNicheAndModelAndChannel(
|
|
411
|
+
pagination: RequestPagination,
|
|
412
|
+
videosFilter: IRequestVideoFilter,
|
|
413
|
+
model: string,
|
|
414
|
+
channel: string,
|
|
415
|
+
lang: Language,
|
|
416
|
+
order: string,
|
|
417
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
418
|
+
): Promise<PaginatedResponse<IVideoCard>> {
|
|
419
|
+
return await ApiHelper.fetch(
|
|
420
|
+
'/videos/list-by-niche-and-model-and-channel',
|
|
421
|
+
{
|
|
422
|
+
method: 'POST',
|
|
423
|
+
headers: {
|
|
424
|
+
'X-Niche': niche,
|
|
425
|
+
'X-Language': toHeaderLanguage(lang),
|
|
426
|
+
'X-Cache-Time': '259200',
|
|
427
|
+
'Content-Type': 'application/json',
|
|
428
|
+
},
|
|
429
|
+
params: {
|
|
430
|
+
...pagination,
|
|
431
|
+
order,
|
|
432
|
+
},
|
|
433
|
+
body: {
|
|
434
|
+
filter_request: videosFilter,
|
|
435
|
+
model: model,
|
|
436
|
+
channel: channel,
|
|
437
|
+
max_limit: 100,
|
|
438
|
+
}
|
|
439
|
+
},
|
|
440
|
+
useRuntimeConfig(),
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
static async getListByNicheAndTag(
|
|
445
|
+
pagination: RequestPagination,
|
|
446
|
+
videosFilter: IRequestVideoFilter,
|
|
447
|
+
tag: string,
|
|
448
|
+
lang: Language,
|
|
449
|
+
order: string,
|
|
450
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
451
|
+
): Promise<PaginatedResponse<IVideoCard>> {
|
|
452
|
+
return await ApiHelper.fetch(
|
|
453
|
+
'/videos/list-by-niche-and-tag',
|
|
454
|
+
{
|
|
455
|
+
method: 'POST',
|
|
456
|
+
headers: {
|
|
457
|
+
'X-Niche': niche,
|
|
458
|
+
'X-Language': toHeaderLanguage(lang),
|
|
459
|
+
'X-Cache-Time': '259200',
|
|
460
|
+
'Content-Type': 'application/json',
|
|
461
|
+
},
|
|
462
|
+
params: {
|
|
463
|
+
...pagination,
|
|
464
|
+
order,
|
|
465
|
+
},
|
|
466
|
+
body: {
|
|
467
|
+
filter_request: {
|
|
468
|
+
...videosFilter,
|
|
469
|
+
},
|
|
470
|
+
tag,
|
|
471
|
+
}
|
|
472
|
+
},
|
|
473
|
+
useRuntimeConfig(),
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
static async getListByNicheAndChannel(
|
|
478
|
+
pagination: RequestPagination,
|
|
479
|
+
videosFilter: IRequestVideoFilter,
|
|
480
|
+
channel: string,
|
|
481
|
+
lang: Language,
|
|
482
|
+
order: string,
|
|
483
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
484
|
+
): Promise<PaginatedResponse<IVideoCard>> {
|
|
485
|
+
return await ApiHelper.fetch(
|
|
486
|
+
'/videos/list-by-niche-and-channel',
|
|
487
|
+
{
|
|
488
|
+
method: 'POST',
|
|
489
|
+
headers: {
|
|
490
|
+
'X-Niche': niche,
|
|
491
|
+
'X-Language': toHeaderLanguage(lang),
|
|
492
|
+
'X-Cache-Time': '259200',
|
|
493
|
+
'Content-Type': 'application/json',
|
|
494
|
+
},
|
|
495
|
+
params: {
|
|
496
|
+
...pagination,
|
|
497
|
+
order,
|
|
498
|
+
},
|
|
499
|
+
body: {
|
|
500
|
+
filter_request: videosFilter,
|
|
501
|
+
channel,
|
|
502
|
+
max_limit: 100,
|
|
503
|
+
}
|
|
504
|
+
},
|
|
505
|
+
useRuntimeConfig(),
|
|
506
|
+
);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
static async popularTagsByModelName(
|
|
510
|
+
lang: Language,
|
|
511
|
+
model: string,
|
|
512
|
+
limit = 25,
|
|
513
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
514
|
+
): Promise<IPopularTags[]> {
|
|
515
|
+
return await ApiHelper.fetch(
|
|
516
|
+
'/videos/popular-tags-by-model-name',
|
|
517
|
+
{
|
|
518
|
+
method: 'GET',
|
|
519
|
+
headers: {
|
|
520
|
+
'X-Niche': niche,
|
|
521
|
+
'X-Language': toHeaderLanguage(lang),
|
|
522
|
+
'X-Cache-Time': '259200',
|
|
523
|
+
'Content-Type': 'application/json',
|
|
524
|
+
},
|
|
525
|
+
params: {
|
|
526
|
+
limit,
|
|
527
|
+
model,
|
|
528
|
+
},
|
|
529
|
+
},
|
|
530
|
+
useRuntimeConfig(),
|
|
531
|
+
);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
static async popularTagsByChannelName(
|
|
535
|
+
lang: Language,
|
|
536
|
+
channel: string,
|
|
537
|
+
limit = 25,
|
|
538
|
+
niche = NicheHelper.getSiteDefaultNiche(),
|
|
539
|
+
): Promise<IPopularTags[]> {
|
|
540
|
+
return await ApiHelper.fetch(
|
|
541
|
+
'/videos/popular-tags-by-channel-name',
|
|
542
|
+
{
|
|
543
|
+
method: 'GET',
|
|
544
|
+
headers: {
|
|
545
|
+
'X-Niche': niche,
|
|
546
|
+
'X-Language': toHeaderLanguage(lang),
|
|
547
|
+
'X-Cache-Time': '259200',
|
|
548
|
+
'Content-Type': 'application/json',
|
|
549
|
+
},
|
|
550
|
+
params: {
|
|
551
|
+
limit,
|
|
552
|
+
channel,
|
|
553
|
+
},
|
|
554
|
+
},
|
|
555
|
+
useRuntimeConfig(),
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ISiteData,
|
|
3
|
+
ISiteLanguageItem,
|
|
4
|
+
ISiteLanguagesResponse,
|
|
5
|
+
ISiteNicheItem,
|
|
6
|
+
ISiteNichesResponse,
|
|
7
|
+
ISiteResponse
|
|
8
|
+
} from '../types';
|
|
9
|
+
|
|
10
|
+
/** Класс для работы с данными сайта */
|
|
11
|
+
export class SiteDataService {
|
|
12
|
+
private static readonly _serviceName = 'SiteDataService';
|
|
13
|
+
private static siteData: ISiteData = {} as ISiteData;
|
|
14
|
+
private static updated: string;
|
|
15
|
+
|
|
16
|
+
public static getServiceName() {
|
|
17
|
+
return this._serviceName;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Метод для получения списка антиадблок доменов из админки */
|
|
21
|
+
public static getAntiAdblokDomains(): Array<string> {
|
|
22
|
+
return SiteDataService.siteData?.siteData?.antiAdblockDomains || [];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Метод для флага из админки */
|
|
26
|
+
public static isSiteEnabled(): boolean {
|
|
27
|
+
return this.siteData.siteData.enabled;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Метод для флага из админки */
|
|
31
|
+
public static getSiteLanguages(): Array<ISiteLanguageItem> {
|
|
32
|
+
return this.siteData.languages || [];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Метод для флага из админки */
|
|
36
|
+
public static getSiteNiches(): Array<ISiteNicheItem> {
|
|
37
|
+
return this.siteData.niches || [];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Метод для получения данных в сервис */
|
|
41
|
+
public static async fetchSiteData() {
|
|
42
|
+
const apiUrl = process.env.NUXT_PUBLIC_API_DOMAIN;
|
|
43
|
+
const xDomain = process.env.NUXT_PUBLIC_X_DOMAIN || '';
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
const fetchOptions = {
|
|
47
|
+
method: 'GET' as const,
|
|
48
|
+
headers: { 'X-Domain': xDomain },
|
|
49
|
+
responseType: 'json' as const,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const [siteData, languagesResponse, nichesResponse] = await Promise.all([
|
|
53
|
+
$fetch<{ data: ISiteResponse }>(`${apiUrl}/v1/site`, fetchOptions).then(r => r.data),
|
|
54
|
+
$fetch<{ data: ISiteLanguagesResponse }>(`${apiUrl}/v1/site/languages`, fetchOptions).then(r => r.data),
|
|
55
|
+
$fetch<{ data: ISiteNichesResponse }>(`${apiUrl}/v1/site/niches`, fetchOptions).then(r => r.data),
|
|
56
|
+
]);
|
|
57
|
+
|
|
58
|
+
SiteDataService.siteData = {
|
|
59
|
+
siteData: siteData,
|
|
60
|
+
languages: languagesResponse?.items || [],
|
|
61
|
+
niches: nichesResponse?.items || [],
|
|
62
|
+
};
|
|
63
|
+
} catch (e) {
|
|
64
|
+
console.error('Failed to fetch site data: ', e);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Метод для получения данных о времени последнего обновления */
|
|
69
|
+
public static getLastUpdate() {
|
|
70
|
+
return this.updated;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { getSortedFilterGroups } from '../get-sorted-filter-groups';
|
|
3
|
+
|
|
4
|
+
describe('getSortedFilterGroups', () => {
|
|
5
|
+
it('возвращает уникальные группы, отсортированные по order', () => {
|
|
6
|
+
const filters = [
|
|
7
|
+
{ group: { title: 'B', order: 2 } },
|
|
8
|
+
{ group: { title: 'A', order: 1 } },
|
|
9
|
+
{ group: { title: 'B', order: 2 } },
|
|
10
|
+
];
|
|
11
|
+
const result = getSortedFilterGroups(filters);
|
|
12
|
+
expect(result.map(g => g.title)).toEqual(['A', 'B']);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('дедуплицирует по title (первое вхождение группы)', () => {
|
|
16
|
+
const filters = [
|
|
17
|
+
{ group: { title: 'A', order: 1, name: 'a1' } },
|
|
18
|
+
{ group: { title: 'A', order: 1, name: 'a2' } },
|
|
19
|
+
];
|
|
20
|
+
const result = getSortedFilterGroups(filters);
|
|
21
|
+
expect(result).toHaveLength(1);
|
|
22
|
+
expect(result[0].name).toBe('a1');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('пустой список → []', () => {
|
|
26
|
+
expect(getSortedFilterGroups([])).toEqual([]);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { parseFilterCategories } from '../parse-filter-categories';
|
|
3
|
+
|
|
4
|
+
describe('parseFilterCategories', () => {
|
|
5
|
+
it('пустой query → []', () => {
|
|
6
|
+
expect(parseFilterCategories({})).toEqual([]);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('строка разбивается по запятой', () => {
|
|
10
|
+
expect(parseFilterCategories({ categories: 'age_18,body_slim' })).toEqual(['age_18', 'body_slim']);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('отбрасывает пустые сегменты', () => {
|
|
14
|
+
expect(parseFilterCategories({ categories: 'age_18,,body_slim,' })).toEqual(['age_18', 'body_slim']);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('массив строк разворачивается', () => {
|
|
18
|
+
expect(parseFilterCategories({ categories: ['age_18', 'body_slim,hair_dark'] }))
|
|
19
|
+
.toEqual(['age_18', 'body_slim', 'hair_dark']);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { sortFilterRadioOptions } from '../sort-filter-radio-options';
|
|
3
|
+
|
|
4
|
+
describe('sortFilterRadioOptions', () => {
|
|
5
|
+
it('ставит all, затем yes в начало', () => {
|
|
6
|
+
const result = sortFilterRadioOptions([{ name: 'yes' }, { name: 'no' }, { name: 'all' }]);
|
|
7
|
+
expect(result.map(o => o.name)).toEqual(['all', 'yes', 'no']);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('отбрасывает unspecified', () => {
|
|
11
|
+
const result = sortFilterRadioOptions([{ name: 'all' }, { name: 'unspecified' }, { name: 'yes' }]);
|
|
12
|
+
expect(result.map(o => o.name)).toEqual(['all', 'yes']);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('сохраняет порядок прочих опций между собой', () => {
|
|
16
|
+
const result = sortFilterRadioOptions([{ name: 'b' }, { name: 'a' }, { name: 'all' }]);
|
|
17
|
+
expect(result.map(o => o.name)).toEqual(['all', 'b', 'a']);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('пустой массив → []', () => {
|
|
21
|
+
expect(sortFilterRadioOptions([])).toEqual([]);
|
|
22
|
+
});
|
|
23
|
+
});
|