itube-specs 0.0.718 → 0.0.720
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 +1 -1
- package/runtime/utils/check-device-width.ts +4 -0
- package/runtime/utils/compress-image.ts +6 -0
- package/runtime/utils/format-date.ts +1 -0
- package/runtime/utils/format-number.ts +2 -2
- package/runtime/utils/format-time-ago.ts +5 -0
- package/runtime/utils/format-time.ts +1 -0
- package/runtime/utils/get-duration.ts +2 -2
- package/runtime/utils/get-month.ts +4 -2
- package/runtime/utils/get-multiple-query.ts +7 -0
- package/runtime/utils/get-selected-query.ts +1 -0
- package/runtime/utils/is-mobile-device.ts +1 -0
- package/runtime/utils/normalize-url.ts +1 -0
- package/runtime/utils/on-backdrop-click.ts +1 -0
- package/runtime/utils/scroll-lock.ts +1 -0
- package/runtime/utils/server/age.ts +7 -0
- package/runtime/utils/server/api-helper.ts +6 -2
- package/runtime/utils/server/get-client-headers.ts +4 -0
- package/runtime/utils/server/get-url-with-proxied-params.ts +1 -0
- package/runtime/utils/server/parse-api-error.ts +4 -0
- package/runtime/utils/server/server-api-helper.ts +6 -0
- package/runtime/utils/validate-email.ts +1 -0
- package/runtime/utils/validate-password.ts +1 -0
- package/runtime/utils/validate-phone.ts +1 -0
- package/runtime/utils/validate-username.ts +1 -0
- package/runtime/utils/video-data-add-model-icon.ts +5 -0
- package/runtime/utils/vtt-helper.ts +7 -0
package/package.json
CHANGED
|
@@ -13,6 +13,10 @@ function breakpoints(breakpoints: Record<CssBreakpoints, number>) {
|
|
|
13
13
|
)
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Возвращает реактивные флаги isMobile и isTablet на основе переданных breakpoints.
|
|
18
|
+
* @param projectBreakpoints - набор брейкпоинтов проекта (xs, sm, md, lg, xl) в пикселях
|
|
19
|
+
*/
|
|
16
20
|
export const checkDeviceWidth = (projectBreakpoints: Record<CssBreakpoints, number>) => {
|
|
17
21
|
const isMobile = breakpoints(projectBreakpoints).smaller('sm');
|
|
18
22
|
const isTablet = breakpoints(projectBreakpoints).smaller('md');
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Сжимает изображение до maxSize px по наибольшей стороне и возвращает Blob в формате JPEG.
|
|
3
|
+
* @param blob - исходное изображение
|
|
4
|
+
* @param maxSize - максимальный размер стороны в px (по умолчанию 512)
|
|
5
|
+
* @param quality - качество JPEG от 0 до 1 (по умолчанию 0.8)
|
|
6
|
+
*/
|
|
1
7
|
export const compressImage = (blob: Blob, maxSize = 512, quality = 0.8): Promise<Blob> => {
|
|
2
8
|
return new Promise((resolve, reject) => {
|
|
3
9
|
const img = new Image();
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Форматирует Unix timestamp (в секундах) в относительную строку: «сегодня», «вчера», «3 дня назад» и т.д.
|
|
3
|
+
* @param date - Unix timestamp в секундах
|
|
4
|
+
* @param t - функция перевода (i18n)
|
|
5
|
+
*/
|
|
1
6
|
export function formatTimeAgo(date: number, t) {
|
|
2
7
|
const pastDate = new Date(date * 1000);
|
|
3
8
|
const now = new Date();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Возвращает продолжительность по переданным секундам в формате
|
|
3
|
-
* @param
|
|
2
|
+
* Возвращает продолжительность по переданным секундам в формате [чч:]мм:сс.
|
|
3
|
+
* @param seconds - количество секунд
|
|
4
4
|
*/
|
|
5
5
|
export function getDuration (seconds: number) {
|
|
6
6
|
const date = new Date(0);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
|
|
2
|
+
* Возвращает локализованное название месяца по его номеру (0-based).
|
|
3
|
+
* @param t - функция перевода (i18n)
|
|
4
|
+
* @param number - номер месяца от 0 (январь) до 11 (декабрь)
|
|
5
|
+
*/
|
|
4
6
|
export function getMonth(t: (key: string) => string, number?: number) {
|
|
5
7
|
const months = [
|
|
6
8
|
'january',
|
|
@@ -2,6 +2,13 @@ import type { RouteLocationNormalizedLoaded } from 'vue-router';
|
|
|
2
2
|
import type { IChipsItem, ISelectItem } from '../../types';
|
|
3
3
|
import { getSelectedQuery } from '../utils/get-selected-query';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Возвращает query-объект для диапазонного фильтра (min/max) на основе текущего маршрута.
|
|
7
|
+
* @param route - текущий маршрут Vue Router
|
|
8
|
+
* @param items - список элементов фильтра
|
|
9
|
+
* @param minKey - ключ минимального значения в query
|
|
10
|
+
* @param maxKey - ключ максимального значения в query
|
|
11
|
+
*/
|
|
5
12
|
export function getMultipleQuery (
|
|
6
13
|
route: RouteLocationNormalizedLoaded,
|
|
7
14
|
items: ISelectItem[] | IChipsItem[],
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { RouteLocation } from 'vue-router';
|
|
2
2
|
import type { IChipsItem, ISelectItem } from '../../types';
|
|
3
3
|
|
|
4
|
+
/** Возвращает значение query выбранного элемента из items, совпадающего с текущим маршрутом. */
|
|
4
5
|
export function getSelectedQuery(route: RouteLocation, items: IChipsItem[] | ISelectItem[]) {
|
|
5
6
|
return items.find(item => item.value === route.query[item.key || ''])?.query;
|
|
6
7
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getCookie } from 'h3';
|
|
2
2
|
import { getClientHeaders } from './get-client-headers';
|
|
3
3
|
|
|
4
|
+
/** Возвращает true если пользователь находится в регионе где требуется верификация возраста (GB, штат KS). */
|
|
4
5
|
export async function isGeoMatch(event, config) {
|
|
5
6
|
const AGE_VERIFY_REGIONS = ['KS'];
|
|
6
7
|
const AGE_VERIFY_COUNTRIES = ['GB'];
|
|
@@ -13,6 +14,7 @@ export async function isGeoMatch(event, config) {
|
|
|
13
14
|
|| AGE_VERIFY_REGIONS.includes(stateCode);
|
|
14
15
|
}
|
|
15
16
|
|
|
17
|
+
/** Проверяет через API прошёл ли пользователь верификацию возраста по session_id из cookie или контекста. */
|
|
16
18
|
export async function isAgeVerified(event, config) {
|
|
17
19
|
const apiUrl = config.public.apiDomain;
|
|
18
20
|
const sessionId = getCookie(event, 'session_id') || event?.context.sessionId;
|
|
@@ -33,6 +35,11 @@ export async function isAgeVerified(event, config) {
|
|
|
33
35
|
return res.data === true;
|
|
34
36
|
}
|
|
35
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Запрашивает у API URL для редиректа на страницу верификации возраста.
|
|
40
|
+
* @param backPath - путь на который вернуть пользователя после верификации
|
|
41
|
+
* @returns URL редиректа и countryCode пользователя
|
|
42
|
+
*/
|
|
36
43
|
export async function getAgeValidationUrl(event, backPath: string, config) {
|
|
37
44
|
const sessionId = event.context?.sessionId || getCookie(event, 'session_id');
|
|
38
45
|
const apiUrl = config.public.apiDomain;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import type { NitroFetchOptions } from "nitropack/types";
|
|
2
2
|
|
|
3
|
-
/**
|
|
3
|
+
/** Клиентский хелпер для запросов через BFF (/bff prefix). Автоматически добавляет x-domain заголовок. */
|
|
4
4
|
export class ApiHelper {
|
|
5
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* @param path - путь без /bff префикса, например `/videos/list`
|
|
7
|
+
* @param fetchOptions - стандартные опции $fetch
|
|
8
|
+
* @param runtimeConfig - useRuntimeConfig() для получения xDomain
|
|
9
|
+
*/
|
|
6
10
|
static async fetch<T>(
|
|
7
11
|
path: string,
|
|
8
12
|
fetchOptions: NitroFetchOptions<string>,
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Извлекает гео-данные и клиентские параметры из заголовков запроса.
|
|
3
|
+
* Поддерживает заголовки Cloudflare (cf-ipcountry, cf-region) и кастомные (x-country-code, x-region-code).
|
|
4
|
+
*/
|
|
1
5
|
export function getClientHeaders(event: any) {
|
|
2
6
|
const headers = event.node.req.headers;
|
|
3
7
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** Копирует query-параметры из текущего запроса (event) в переданный URL. Используется для проксирования запросов с сохранением параметров. */
|
|
1
2
|
export function getUrlWithProxiedParams(url: string, event) {
|
|
2
3
|
const _url = new URL(url);
|
|
3
4
|
_url.search = new URLSearchParams(getQuery(event));
|
|
@@ -2,7 +2,13 @@ import type { H3Event } from "h3";
|
|
|
2
2
|
import { getHeaders } from "h3";
|
|
3
3
|
import type { FetchOptions } from "ofetch";
|
|
4
4
|
|
|
5
|
+
/** Серверный хелпер для запросов к внешнему API. Проксирует заголовки клиента и разворачивает `response.data`. */
|
|
5
6
|
export class ServerApiHelper {
|
|
7
|
+
/**
|
|
8
|
+
* @param url - полный URL внешнего API
|
|
9
|
+
* @param event - H3Event для проброса заголовков клиента
|
|
10
|
+
* @param requestOptions - дополнительные опции fetch (method, body и т.д.)
|
|
11
|
+
*/
|
|
6
12
|
public static async fetch<T>(url: string, event: H3Event, requestOptions?: FetchOptions): Promise<T> {
|
|
7
13
|
try {
|
|
8
14
|
const response = await $fetch<{ data: T }>(url, {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** Возвращает true если строка является валидным номером телефона (7–20 цифр, опциональные +, пробелы, скобки и дефисы). */
|
|
1
2
|
export function validatePhone (value: string) {
|
|
2
3
|
const re = /^\+?[0-9\s\-().]{7,20}$/;
|
|
3
4
|
return value?.length !== 0 && re.test(String(value).trim());
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { IRawModelCard, IRawVideoData } from '../../types';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Добавляет поле icon из modelsData в каждую модель videoData.models по совпадению guid.
|
|
5
|
+
* @param videoData - сырые данные видео
|
|
6
|
+
* @param modelsData - массив карточек моделей с primary_image_url
|
|
7
|
+
*/
|
|
3
8
|
export function videoDataAddModelIcon(videoData: IRawVideoData, modelsData: Array<IRawModelCard>): IRawVideoData {
|
|
4
9
|
const transformedData = { ...videoData };
|
|
5
10
|
|
|
@@ -4,6 +4,7 @@ export interface IVttItem {
|
|
|
4
4
|
coords: { x: number; y: number; w: number; h: number };
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
/** Загружает и парсит VTT-файл с тайм-кодами и координатами спрайтов превью видео. */
|
|
7
8
|
export class VttHelper {
|
|
8
9
|
private readonly vttUrl: string;
|
|
9
10
|
public hasInited: boolean;
|
|
@@ -15,6 +16,7 @@ export class VttHelper {
|
|
|
15
16
|
this.vttData = null;
|
|
16
17
|
}
|
|
17
18
|
|
|
19
|
+
/** Загружает и парсит VTT-файл по url из конструктора. Устанавливает hasInited = true после успешной загрузки. */
|
|
18
20
|
async init(): Promise<void> {
|
|
19
21
|
const vttContent: Response = await fetch(this.vttUrl);
|
|
20
22
|
|
|
@@ -71,6 +73,11 @@ export class VttHelper {
|
|
|
71
73
|
return hh * 3600 + mm * 60 + ss;
|
|
72
74
|
}
|
|
73
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Возвращает координаты спрайта превью для указанного времени воспроизведения.
|
|
78
|
+
* @param time - время в секундах
|
|
79
|
+
* @param vttData - данные VTT (по умолчанию загруженные через init)
|
|
80
|
+
*/
|
|
74
81
|
getCoordsByTime(time: number, vttData: Array<IVttItem> | null = this.vttData):
|
|
75
82
|
{ x: number; y: number; w: number; h: number } | string {
|
|
76
83
|
if (!this.hasInited || !vttData) {
|