Files
pipu-music/packages/api-client/src/generated/schema.ts
T
mrleo1nidandClaude Opus 5.5 6a67c27f50
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 43s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m12s
ci / api / api (push) Successful in 35s
ci / ts / ts (packages + web) (push) Successful in 1m20s
feat(api): Android self-update endpoints proxied from Gitea releases (M5)
GET /api/v1/app/android/latest reads the latest Gitea release with the
server token (cached for 10 minutes); the download endpoint caches the
APK under /updates, verifies its SHA-256 and serves it with Range.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 12:52:41 +03:00

2940 lines
90 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* This file was auto-generated by openapi-typescript.
* Do not make direct changes to the file.
*/
export interface paths {
"/healthz": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Живость процесса */
get: operations["getHealthz"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/readyz": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Готовность обслуживать запросы (зависимости доступны) */
get: operations["getReadyz"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/server-info": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* Сведения о сервере для клиентов
* @description Вызывается без аутентификации: веб и Android проверяют версию сервера,
* совместимость клиента и поддерживаемые языки (экран подключения).
*/
get: operations["getServerInfo"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/auth/login": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* Вход по логину и паролю
* @description Веб (`client_type: web`) получает refresh-токен в cookie `pipu_rt`
* (`HttpOnly; Secure; SameSite=Strict; Path=/api/v1/auth`), Android — в поле `refresh_token`.
* Неверный логин или пароль, а также временно заблокированный перебором вход — всегда
* `401 auth.invalid_credentials`. Превышен лимит попыток с адреса — `429 auth.too_many_attempts`.
*/
post: operations["login"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/auth/refresh": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* Ротация refresh-токена
* @description Refresh-токен берётся из cookie `pipu_rt` (веб) или из тела (Android). Старый токен
* становится использованным; его повторное предъявление отзывает всю семью токенов.
*/
post: operations["refreshTokens"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/auth/logout": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/** Выход — отзыв текущей сессии */
post: operations["logout"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/auth/logout-all": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/** Выход на всех устройствах */
post: operations["logoutAll"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/me": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Текущий пользователь */
get: operations["getMe"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
/**
* Изменить имя, язык, настройки интерфейса
* @description Поля `ui_prefs` сливаются с сохранёнными; не переданные поля не меняются.
*/
patch: operations["updateMe"];
trace?: never;
};
"/api/v1/me/password": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* Сменить пароль
* @description `current_password` обязателен, кроме случая `must_change_password` (вход по временному паролю).
* Все сессии отзываются; текущему устройству выдаётся новая пара токенов.
*/
post: operations["changePassword"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/me/bootstrap-credentials": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* Первый запуск — новые логин и пароль администратора
* @description Только при `must_change_credentials`. Пароль должен отличаться от текущего.
* Все прочие сессии отзываются, выдаётся новая пара токенов.
*/
post: operations["setBootstrapCredentials"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/me/sessions": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Активные сессии (устройства) */
get: operations["listMySessions"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/me/sessions/{id}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
post?: never;
/** Завершить сессию на устройстве */
delete: operations["revokeMySession"];
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/admin/users": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* Пользователи (admin, moderator)
* @description Сортировка по логину. `q` ищет по логину и имени без учёта регистра.
*/
get: operations["listUsers"];
put?: never;
/**
* Создать пользователя
* @description Пароль генерирует сервер и возвращает **один раз**; при первом входе его нужно сменить.
* Модератор создаёт только `user`, админ — любые роли.
*/
post: operations["createUser"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/admin/users/{id}": {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["UserId"];
};
cookie?: never;
};
get?: never;
put?: never;
post?: never;
/** Удалить пользователя (admin) */
delete: operations["deleteUser"];
options?: never;
head?: never;
/**
* Изменить имя, роль, блокировку
* @description Роль меняет только админ. Смена роли и блокировка мгновенно отзывают токены пользователя.
* Последнего активного админа нельзя понизить или заблокировать — `409 users.last_admin`.
*/
patch: operations["updateUser"];
trace?: never;
};
"/api/v1/admin/users/{id}/reset-password": {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["UserId"];
};
cookie?: never;
};
get?: never;
put?: never;
/**
* Сбросить пароль
* @description Новый временный пароль возвращается один раз; все сессии пользователя завершаются.
*/
post: operations["resetUserPassword"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/admin/audit": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Журнал действий (admin), новые сверху */
get: operations["listAudit"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/admin/sources": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Хранилища (admin) */
get: operations["listSources"];
put?: never;
/**
* Подключить хранилище (admin)
* @description `local` — подпапка в каталоге LIBRARY_HOST сервера; `nfs` — монтирует storage-agent.
* Хранилище сохраняется, даже если подключиться не удалось: статус и сообщение — в ответе.
*/
post: operations["createSource"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/admin/sources/{id}": {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["SourceId"];
};
cookie?: never;
};
/** Хранилище (admin) */
get: operations["getSource"];
put?: never;
post?: never;
/**
* Отключить и удалить хранилище (admin)
* @description Треки, файлы которых были только в этом хранилище, удаляются из каталога.
*/
delete: operations["deleteSource"];
options?: never;
head?: never;
/**
* Изменить хранилище (admin)
* @description Изменение адреса NFS или папки переподключает хранилище.
*/
patch: operations["updateSource"];
trace?: never;
};
"/api/v1/admin/sources/{id}/test": {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["SourceId"];
};
cookie?: never;
};
get?: never;
put?: never;
/** Проверить подключение (admin) */
post: operations["testSource"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/admin/sources/{id}/patterns": {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["SourceId"];
};
cookie?: never;
};
/** Шаблоны путей (admin) */
get: operations["getSourcePatterns"];
/**
* Заменить шаблоны путей (admin)
* @description Ошибка компиляции — `422 validation.pattern_invalid` с `params.index` и `params.reason`.
*/
put: operations["putSourcePatterns"];
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/admin/sources/{id}/patterns/preview": {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["SourceId"];
};
cookie?: never;
};
get?: never;
put?: never;
/** Предпросмотр разбора путей без сохранения (admin) */
post: operations["previewSourcePatterns"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/admin/sources/{id}/scan": {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["SourceId"];
};
cookie?: never;
};
get?: never;
put?: never;
/**
* Запустить скан (admin)
* @description Скан идёт в фоне; прогресс — в `GET /admin/library/status`. Уже идёт — `409 library.scan_running`.
*/
post: operations["scanSource"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/admin/library/status": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Состояние библиотеки (admin, moderator) */
get: operations["getLibraryStatus"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/admin/library/errors": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Файлы, которые не удалось прочитать (admin) */
get: operations["listLibraryErrors"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/admin/library/host-dirs": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Подпапки каталога LIBRARY_HOST — выбор папки для local-хранилища (admin) */
get: operations["listHostDirs"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/artists/{id}": {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
/** Исполнитель */
get: operations["getArtist"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/artists/{id}/albums": {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
/** Альбомы исполнителя (свои и сборники с его треками) */
get: operations["listArtistAlbums"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/albums/{id}": {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
/** Альбом с треками */
get: operations["getAlbum"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/tracks/{id}": {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
/** Трек */
get: operations["getTrack"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/search/suggest": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* Выпадающий список поиска — до 3 исполнителей, 3 альбомов, 5 треков
* @description Если по запросу ничего не найдено, сервер повторяет его в другой раскладке клавиатуры
* («ghbdtn» → «привет») и возвращает исправленный запрос в `corrected_query`.
*/
get: operations["searchSuggest"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/search": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* Страница поиска
* @description `type=all` — по несколько результатов каждого вида без пагинации;
* конкретный тип — страницы с `next_cursor`.
*/
get: operations["search"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/admin/search/reindex": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/** Пересобрать поисковые индексы (admin) */
post: operations["reindexSearch"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/covers/{id}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* Обложка альбома (WebP)
* @description Ссылку целиком даёт `cover_url` альбома (подписана, без срока: обложка с данным `v` неизменна);
* клиент добавляет `size`. Файл отдаёт nginx через X-Accel-Redirect.
*/
get: operations["getCover"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/stream/{id}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* Аудио трека (поддерживает Range)
* @description Ссылку целиком даёт `stream_url` трека (подпись пользователя и срок 12 ч); клиент может добавить `q`.
* Файл отдаёт nginx через X-Accel-Redirect: оригинал из хранилища или транскод в Opus из кэша.
*/
get: operations["streamTrack"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/tracks/batch": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/** Треки по списку id (восстановление очереди) */
post: operations["getTracksBatch"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/events": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* Пачка событий прослушивания (до 500)
* @description Повторно присланные события (тот же id) не учитываются дважды.
*/
post: operations["postEvents"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/me/playback-state": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Последнее состояние плеера (трек, позиция, очередь) */
get: operations["getPlaybackState"];
/** Сохранить состояние плеера (last-write-wins) */
put: operations["putPlaybackState"];
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/me/history": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** История прослушиваний, новые сверху */
get: operations["getHistory"];
put?: never;
post?: never;
/** Очистить историю (события остаются для статистики) */
delete: operations["clearHistory"];
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/me/likes": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Лайки, новые сверху */
get: operations["getLikes"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/me/dislikes": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Дизлайки, новые сверху */
get: operations["getDislikes"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/me/reactions/tracks/{id}": {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
get?: never;
/** Лайк или дизлайк трека */
put: operations["setTrackReaction"];
post?: never;
/** Снять реакцию */
delete: operations["clearTrackReaction"];
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/wave/options": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Занятия и настроения (ключи для i18n и иконки) */
get: operations["getWaveOptions"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/wave/sessions": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/** Начать «Мою волну» */
post: operations["startWave"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/wave/sessions/{id}": {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
get?: never;
put?: never;
post?: never;
/** Завершить сессию волны */
delete: operations["endWave"];
options?: never;
head?: never;
/** Сменить занятие / настроение на лету — пачка пересобирается */
patch: operations["updateWave"];
trace?: never;
};
"/api/v1/wave/sessions/{id}/next": {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
get?: never;
put?: never;
/** Следующая пачка с учётом реакций на выданные треки */
post: operations["nextWave"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/app/android/latest": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* Последняя версия Android-приложения (из релизов Gitea через сервер)
* @description Сервер сам опрашивает Gitea своим токеном и кэширует ответ на 10 минут, поэтому приложению
* не нужен доступ к Gitea. Нет настроек Gitea или релиза с APK — `404 app.update_unavailable`.
*/
get: operations["getAndroidLatest"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/app/android/download/{version}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** APK версии (кэшируется на сервере, поддерживает Range для докачки) */
get: operations["downloadAndroidApk"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
}
export type webhooks = Record<string, never>;
export interface components {
schemas: {
HealthStatus: {
/** @enum {string} */
status: "ok";
};
ReadyStatus: {
/** @enum {string} */
status: "ok" | "degraded";
/** @description Результат проверки каждой зависимости */
checks: {
[key: string]: string;
};
};
ServerInfo: {
/** @example pipu-music */
name: string;
/**
* @description Версия сервера (SemVer)
* @example 0.1.0
*/
version: string;
/** @example v1 */
api_version: string;
/**
* @example [
* "ru",
* "en"
* ]
*/
supported_locales: string[];
/**
* @description Минимальный versionCode Android-приложения, которое поддерживает сервер
* @example 10099
*/
min_android_version_code: number;
/** @description Первый вход администратора ещё не завершён — клиент может показать подсказку */
bootstrap_required: boolean;
};
/** @enum {string} */
Role: "admin" | "moderator" | "user";
/** @enum {string} */
ClientType: "web" | "android";
LoginRequest: {
username: string;
password: string;
client_type: components["schemas"]["ClientType"];
/** @description Например «Chrome / Windows», «Pixel 8» */
device_name?: string;
};
RefreshRequest: {
/** @description Только Android; веб передаёт токен в cookie */
refresh_token?: string;
};
AuthTokens: {
access_token: string;
/** @enum {string} */
token_type: "Bearer";
/** @description Срок жизни access-токена, секунды */
expires_in: number;
/** @description Только для `client_type: android` */
refresh_token?: string;
user: components["schemas"]["Me"];
};
UiPrefs: {
/** @enum {string} */
theme?: "dark" | "light" | "system";
/** @enum {string} */
wave_variant?: "orb" | "liquid";
/** @enum {string} */
web_player?: "bar" | "island";
/** @enum {string} */
mobile_player?: "cover" | "wave";
ambient?: boolean;
crossfade_s?: number;
normalize?: boolean;
};
Me: {
/** Format: uuid */
id: string;
username: string;
display_name: string | null;
role: components["schemas"]["Role"];
locale: string;
ui_prefs: components["schemas"]["UiPrefs"];
must_change_password: boolean;
must_change_credentials: boolean;
/** Format: date-time */
created_at: string;
};
UpdateMeRequest: {
/** @description Пустая строка — сбросить имя */
display_name?: string;
locale?: string;
ui_prefs?: components["schemas"]["UiPrefs"];
};
ChangePasswordRequest: {
current_password?: string;
new_password: string;
};
BootstrapCredentialsRequest: {
new_username: string;
new_password: string;
};
AdminUser: {
/** Format: uuid */
id: string;
username: string;
display_name: string | null;
role: components["schemas"]["Role"];
locale: string;
is_blocked: boolean;
must_change_password: boolean;
must_change_credentials: boolean;
/** Format: date-time */
created_at: string;
/** Format: date-time */
last_login_at: string | null;
};
AdminUserPage: {
items: components["schemas"]["AdminUser"][];
next_cursor: string | null;
};
CreateUserRequest: {
username: string;
display_name?: string;
role: components["schemas"]["Role"];
};
CreatedUser: {
user: components["schemas"]["AdminUser"];
/** @description Показывается один раз */
temporary_password: string;
};
UpdateUserRequest: {
/** @description Пустая строка — сбросить имя */
display_name?: string;
role?: components["schemas"]["Role"];
is_blocked?: boolean;
};
TemporaryPassword: {
temporary_password: string;
};
AuditActor: {
/** Format: uuid */
id: string;
username: string;
};
AuditEntry: {
/** Format: uuid */
id: string;
/** @description null — система или удалённый пользователь */
actor: components["schemas"]["AuditActor"] | null;
/** @example user.create */
action: string;
target_type: string | null;
/** Format: uuid */
target_id: string | null;
payload: {
[key: string]: unknown;
} | null;
/** Format: date-time */
created_at: string;
};
AuditPage: {
items: components["schemas"]["AuditEntry"][];
next_cursor: string | null;
};
/** @enum {string} */
SourceType: "nfs" | "local";
/** @enum {string} */
SourceStatus: "pending" | "mounted" | "error" | "disabled";
/** @enum {string} */
TagPriority: "tags_first" | "path_first";
Source: {
/** Format: uuid */
id: string;
name: string;
type: components["schemas"]["SourceType"];
nfs_server: string | null;
nfs_export: string | null;
nfs_options: string;
/** @description Подпапка относительно LIBRARY_HOST, пусто — весь каталог */
local_path: string | null;
tag_priority: components["schemas"]["TagPriority"];
/** @description Автоматический скан, null — только вручную */
scan_interval_minutes: number | null;
status: components["schemas"]["SourceStatus"];
status_message: string | null;
/** Format: date-time */
last_scan_at: string | null;
/** Format: date-time */
created_at: string;
scan: components["schemas"]["ScanProgress"] | null;
};
SourceList: {
items: components["schemas"]["Source"][];
};
SourceInput: {
name: string;
type: components["schemas"]["SourceType"];
nfs_server?: string;
nfs_export?: string;
nfs_options?: string;
local_path?: string;
tag_priority?: components["schemas"]["TagPriority"];
scan_interval_minutes?: number | null;
};
SourcePatch: {
name?: string;
nfs_server?: string;
nfs_export?: string;
nfs_options?: string;
local_path?: string;
tag_priority?: components["schemas"]["TagPriority"];
/** @description 0 — отключить автоматический скан */
scan_interval_minutes?: number;
/** @description false — отключить хранилище (треки становятся недоступны), true — подключить снова */
enabled?: boolean;
};
SourceTestResult: {
ok: boolean;
message: string;
/** @description Сколько аудиофайлов найдено (проверка останавливается на 1000) */
audio_files: number;
};
PathPattern: {
regex: string;
is_enabled: boolean;
};
PatternList: {
patterns: components["schemas"]["PathPattern"][];
};
PatternPreviewRequest: {
patterns: components["schemas"]["PathPattern"][];
/** @default 50 */
sample: number;
};
TrackMeta: {
artist: string;
album_artist: string;
album: string;
title: string;
genres: string[];
year: number | null;
track: number | null;
disc: number | null;
};
PreviewItem: {
rel_path: string;
/** @description Номер совпавшего шаблона, null — ни один */
pattern_index: number | null;
skipped: boolean;
path_fields: {
[key: string]: string;
};
tags: {
[key: string]: string;
};
result: components["schemas"]["TrackMeta"];
error: string | null;
};
PatternPreview: {
items: components["schemas"]["PreviewItem"][];
unmatched: number;
};
ScanRequest: {
/** @description Перечитать все файлы, а не только новые и изменённые */
full?: boolean;
};
ScanProgress: {
running: boolean;
full: boolean;
/** Format: date-time */
started_at: string;
/** Format: date-time */
finished_at: string | null;
found: number;
to_process: number;
processed: number;
added: number;
updated: number;
moved: number;
missing: number;
errors: number;
error: string | null;
};
LibraryStatus: {
analysis: components["schemas"]["AnalysisStatus"];
wave: components["schemas"]["WaveMetrics"];
artists: number;
albums: number;
tracks: number;
files: number;
missing_files: number;
file_errors: number;
sources: components["schemas"]["SourceStatusItem"][];
};
SourceStatusItem: {
/** Format: uuid */
id: string;
name: string;
status: components["schemas"]["SourceStatus"];
status_message: string | null;
/** Format: date-time */
last_scan_at: string | null;
scan: components["schemas"]["ScanProgress"] | null;
};
LibraryError: {
/** Format: uuid */
file_id: string;
/** Format: uuid */
source_id: string;
rel_path: string;
error: string;
};
LibraryErrorPage: {
items: components["schemas"]["LibraryError"][];
next_cursor: string | null;
};
HostDirList: {
path: string;
dirs: string[];
};
ArtistRef: {
/** Format: uuid */
id: string;
name: string;
};
AlbumRef: {
/** Format: uuid */
id: string;
title: string;
year: number | null;
cover_url: string | null;
cover_colors: string[];
};
Track: {
/** Format: uuid */
id: string;
title: string;
duration_ms: number;
artists: components["schemas"]["ArtistRef"][];
album: components["schemas"]["AlbumRef"];
genres: string[];
disc_no: number | null;
track_no: number | null;
/** @description Есть доступный файл (хранилище подключено, файл на месте) */
available: boolean;
/** @description Подписанная ссылка на аудио (12 ч); null — трек недоступен */
stream_url: string | null;
reaction: components["schemas"]["Reaction"] | null;
/** @description Аудиопризнаки (после анализа) — для анимации волны и выравнивания громкости */
features: components["schemas"]["TrackFeatures"] | null;
};
Artist: {
/** Format: uuid */
id: string;
name: string;
album_count: number;
track_count: number;
};
AlbumSummary: {
/** Format: uuid */
id: string;
title: string;
year: number | null;
cover_url: string | null;
cover_colors: string[];
artist: components["schemas"]["ArtistRef"];
track_count: number;
};
AlbumSummaryList: {
items: components["schemas"]["AlbumSummary"][];
};
Album: {
/** Format: uuid */
id: string;
title: string;
year: number | null;
cover_url: string | null;
cover_colors: string[];
artist: components["schemas"]["ArtistRef"];
duration_ms: number;
tracks: components["schemas"]["Track"][];
};
SearchResults: {
artists: components["schemas"]["ArtistRef"][];
albums: components["schemas"]["AlbumSummary"][];
tracks: components["schemas"]["Track"][];
/** @description Оценка общего числа совпадений */
totals: {
artists: number;
albums: number;
tracks: number;
};
/** @description Запрос в другой раскладке, если по исходному ничего не нашлось */
corrected_query: string | null;
next_cursor: string | null;
};
TrackFeatures: {
bpm: number | null;
energy: number | null;
loudness_lufs: number | null;
};
/** @enum {string} */
StreamQuality: "auto" | "original" | "high" | "medium" | "low";
/** @enum {string} */
Reaction: "like" | "dislike";
TrackIds: {
ids: string[];
};
TrackList: {
items: components["schemas"]["Track"][];
};
PlayEvent: {
/**
* Format: uuid
* @description UUIDv7 от клиента — ключ идемпотентности
*/
id: string;
/** @enum {string} */
type: "play_start" | "play_end" | "skip" | "seek" | "pause" | "resume" | "like" | "unlike" | "dislike" | "undislike";
/** Format: uuid */
track_id: string;
/** Format: date-time */
occurred_at: string;
position_ms?: number;
played_ms?: number;
from_ms?: number;
/** @enum {string} */
context_type?: "wave" | "album" | "artist" | "search" | "collection" | "history" | "queue";
context_id?: string;
/** Format: uuid */
wave_session_id?: string;
offline?: boolean;
};
EventBatch: {
events: components["schemas"]["PlayEvent"][];
};
EventBatchResult: {
accepted: number;
duplicates: number;
/** @description Слишком старые (> 30 дней) или с неизвестным треком */
rejected: number;
};
PlaybackContext: {
type?: string;
id?: string;
label?: string;
/** Format: uuid */
wave_session_id?: string;
};
PlaybackStateInput: {
/** Format: uuid */
track_id: string | null;
position_ms: number;
queue: string[];
queue_index: number;
context?: components["schemas"]["PlaybackContext"];
shuffle?: boolean;
/** @enum {string} */
repeat_mode?: "off" | "one" | "all";
volume?: number;
device_id?: string;
};
PlaybackState: {
/** Format: uuid */
track_id: string | null;
position_ms: number;
queue: string[];
queue_index: number;
context: components["schemas"]["PlaybackContext"] | null;
shuffle: boolean;
/** @enum {string} */
repeat_mode: "off" | "one" | "all";
volume: number;
device_id: string | null;
/** Format: date-time */
updated_at: string | null;
};
HistoryItem: {
/** Format: uuid */
id: string;
/** Format: date-time */
played_at: string;
track: components["schemas"]["Track"];
};
HistoryPage: {
items: components["schemas"]["HistoryItem"][];
next_cursor: string | null;
};
ReactedTrack: {
/** Format: date-time */
created_at: string;
track: components["schemas"]["Track"];
};
ReactedTrackPage: {
items: components["schemas"]["ReactedTrack"][];
total: number;
next_cursor: string | null;
};
ReactionInput: {
reaction: components["schemas"]["Reaction"];
};
WaveOption: {
/** @example running */
key: string;
/** @description Имя иконки Material Symbols */
icon: string;
};
WaveOptions: {
activities: components["schemas"]["WaveOption"][];
moods: components["schemas"]["WaveOption"][];
};
WaveContext: {
activity?: string | null;
mood?: string | null;
};
WaveStart: {
activity?: string | null;
mood?: string | null;
seed?: {
/** @enum {string} */
type: "track" | "album" | "artist";
/** Format: uuid */
id: string;
};
};
WaveFeedback: {
/** Format: uuid */
track_id: string;
/** @enum {string} */
outcome: "complete" | "skip" | "skip_early" | "like" | "dislike";
};
WaveNext: {
feedback?: components["schemas"]["WaveFeedback"][];
};
WaveBatch: {
/** Format: uuid */
session_id: string;
activity: string | null;
mood: string | null;
tracks: components["schemas"]["Track"][];
/** @description Рекомендатель недоступен — пачка собрана упрощённо (лайки, любимые исполнители) */
fallback: boolean;
};
AnalysisStatus: {
queued: number;
running: number;
done: number;
failed: number;
analyzer_ver: string | null;
};
/** @description Метрики волны за 7 дней */
WaveMetrics: {
served: number;
listen_through_rate: number | null;
early_skip_rate: number | null;
/** @description Лайков на 100 треков */
like_rate: number | null;
sessions: number;
};
AndroidRelease: {
/** @example 0.6.1 */
version: string;
version_code: number;
/** @description Что нового (Markdown из релиза) */
notes_md: string;
/** Format: int64 */
size: number;
sha256: string;
download_url: string;
/** @description Версии ниже обязаны обновиться */
min_supported: number;
};
Session: {
/** Format: uuid */
id: string;
device_name: string | null;
client_type: components["schemas"]["ClientType"];
/**
* Format: date-time
* @description Время входа
*/
created_at: string;
/** Format: date-time */
last_used_at: string;
/** @description Сессия, из которой сделан запрос */
current: boolean;
};
SessionList: {
items: components["schemas"]["Session"][];
};
FieldError: {
field: string;
code: string;
};
Problem: {
/** @default about:blank */
type: string;
status: number;
/** @description Машинный код ошибки для i18n, например `auth.invalid_credentials` */
code: string;
/** @description Пояснение для логов (не для показа пользователю) */
detail?: string;
params?: {
[key: string]: unknown;
};
/** @description Ошибки отдельных полей запроса */
errors?: components["schemas"]["FieldError"][];
};
};
responses: {
/** @description Ошибка (RFC 9457) */
Problem: {
headers: {
[name: string]: unknown;
};
content: {
"application/problem+json": components["schemas"]["Problem"];
};
};
};
parameters: {
SourceId: string;
EntityId: string;
Limit: number;
/** @description Непрозрачный курсор из `next_cursor` предыдущей страницы */
Cursor: string;
UserId: string;
};
requestBodies: never;
headers: never;
pathItems: never;
}
export type $defs = Record<string, never>;
export interface operations {
getHealthz: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Процесс жив */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["HealthStatus"];
};
};
};
};
getReadyz: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Все зависимости доступны */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["ReadyStatus"];
};
};
/** @description Одна или несколько зависимостей недоступны */
503: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["ReadyStatus"];
};
};
};
};
getServerInfo: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Сведения о сервере */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["ServerInfo"];
};
};
default: components["responses"]["Problem"];
};
};
login: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["LoginRequest"];
};
};
responses: {
/** @description Успешный вход */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AuthTokens"];
};
};
default: components["responses"]["Problem"];
};
};
refreshTokens: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: {
pipu_rt?: string;
};
};
requestBody?: {
content: {
"application/json": components["schemas"]["RefreshRequest"];
};
};
responses: {
/** @description Новая пара токенов */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AuthTokens"];
};
};
default: components["responses"]["Problem"];
};
};
logout: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Сессия завершена, cookie `pipu_rt` очищена */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
default: components["responses"]["Problem"];
};
};
logoutAll: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Все сессии пользователя завершены */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
default: components["responses"]["Problem"];
};
};
getMe: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Профиль */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Me"];
};
};
default: components["responses"]["Problem"];
};
};
updateMe: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["UpdateMeRequest"];
};
};
responses: {
/** @description Обновлённый профиль */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Me"];
};
};
default: components["responses"]["Problem"];
};
};
changePassword: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["ChangePasswordRequest"];
};
};
responses: {
/** @description Пароль изменён, новая пара токенов */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AuthTokens"];
};
};
default: components["responses"]["Problem"];
};
};
setBootstrapCredentials: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["BootstrapCredentialsRequest"];
};
};
responses: {
/** @description Учётные данные заменены, новая пара токенов */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AuthTokens"];
};
};
default: components["responses"]["Problem"];
};
};
listMySessions: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Список сессий, новые сверху */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["SessionList"];
};
};
default: components["responses"]["Problem"];
};
};
revokeMySession: {
parameters: {
query?: never;
header?: never;
path: {
id: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Сессия завершена */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
default: components["responses"]["Problem"];
};
};
listUsers: {
parameters: {
query?: {
q?: string;
role?: components["schemas"]["Role"];
limit?: components["parameters"]["Limit"];
/** @description Непрозрачный курсор из `next_cursor` предыдущей страницы */
cursor?: components["parameters"]["Cursor"];
};
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Страница пользователей */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AdminUserPage"];
};
};
default: components["responses"]["Problem"];
};
};
createUser: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["CreateUserRequest"];
};
};
responses: {
/** @description Пользователь создан */
201: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["CreatedUser"];
};
};
default: components["responses"]["Problem"];
};
};
deleteUser: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["UserId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Удалён */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
default: components["responses"]["Problem"];
};
};
updateUser: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["UserId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["UpdateUserRequest"];
};
};
responses: {
/** @description Обновлённый пользователь */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AdminUser"];
};
};
default: components["responses"]["Problem"];
};
};
resetUserPassword: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["UserId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Временный пароль */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["TemporaryPassword"];
};
};
default: components["responses"]["Problem"];
};
};
listAudit: {
parameters: {
query?: {
limit?: components["parameters"]["Limit"];
/** @description Непрозрачный курсор из `next_cursor` предыдущей страницы */
cursor?: components["parameters"]["Cursor"];
};
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Страница журнала */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AuditPage"];
};
};
default: components["responses"]["Problem"];
};
};
listSources: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Список хранилищ */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["SourceList"];
};
};
default: components["responses"]["Problem"];
};
};
createSource: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["SourceInput"];
};
};
responses: {
/** @description Хранилище создано */
201: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Source"];
};
};
default: components["responses"]["Problem"];
};
};
getSource: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["SourceId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Хранилище */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Source"];
};
};
default: components["responses"]["Problem"];
};
};
deleteSource: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["SourceId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Удалено */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
default: components["responses"]["Problem"];
};
};
updateSource: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["SourceId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["SourcePatch"];
};
};
responses: {
/** @description Хранилище */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Source"];
};
};
default: components["responses"]["Problem"];
};
};
testSource: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["SourceId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Результат проверки */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["SourceTestResult"];
};
};
default: components["responses"]["Problem"];
};
};
getSourcePatterns: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["SourceId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Шаблоны по порядку */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["PatternList"];
};
};
default: components["responses"]["Problem"];
};
};
putSourcePatterns: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["SourceId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["PatternList"];
};
};
responses: {
/** @description Сохранённые шаблоны */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["PatternList"];
};
};
default: components["responses"]["Problem"];
};
};
previewSourcePatterns: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["SourceId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["PatternPreviewRequest"];
};
};
responses: {
/** @description Разбор выборки файлов */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["PatternPreview"];
};
};
default: components["responses"]["Problem"];
};
};
scanSource: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["SourceId"];
};
cookie?: never;
};
requestBody?: {
content: {
"application/json": components["schemas"]["ScanRequest"];
};
};
responses: {
/** @description Скан запущен */
202: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["ScanProgress"];
};
};
default: components["responses"]["Problem"];
};
};
getLibraryStatus: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Счётчики и сканы */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["LibraryStatus"];
};
};
default: components["responses"]["Problem"];
};
};
listLibraryErrors: {
parameters: {
query?: {
limit?: components["parameters"]["Limit"];
/** @description Непрозрачный курсор из `next_cursor` предыдущей страницы */
cursor?: components["parameters"]["Cursor"];
};
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Страница ошибок */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["LibraryErrorPage"];
};
};
default: components["responses"]["Problem"];
};
};
listHostDirs: {
parameters: {
query?: {
/** @description Путь относительно корня, пусто — корень */
path?: string;
};
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Подпапки */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["HostDirList"];
};
};
default: components["responses"]["Problem"];
};
};
getArtist: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Исполнитель */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Artist"];
};
};
default: components["responses"]["Problem"];
};
};
listArtistAlbums: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Альбомы исполнителя (свои и сборники с его треками) */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AlbumSummaryList"];
};
};
default: components["responses"]["Problem"];
};
};
getAlbum: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Альбом с треками */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Album"];
};
};
default: components["responses"]["Problem"];
};
};
getTrack: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Трек */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Track"];
};
};
default: components["responses"]["Problem"];
};
};
searchSuggest: {
parameters: {
query: {
q: string;
};
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Подсказки */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["SearchResults"];
};
};
default: components["responses"]["Problem"];
};
};
search: {
parameters: {
query: {
q: string;
type?: "all" | "artists" | "albums" | "tracks";
limit?: components["parameters"]["Limit"];
/** @description Непрозрачный курсор из `next_cursor` предыдущей страницы */
cursor?: components["parameters"]["Cursor"];
};
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Результаты */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["SearchResults"];
};
};
default: components["responses"]["Problem"];
};
};
reindexSearch: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Переиндексация запущена */
202: {
headers: {
[name: string]: unknown;
};
content?: never;
};
default: components["responses"]["Problem"];
};
};
getCover: {
parameters: {
query: {
v: string;
sig: string;
size?: 64 | 300 | 1200;
};
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Картинка */
200: {
headers: {
[name: string]: unknown;
};
content: {
"image/webp": string;
};
};
default: components["responses"]["Problem"];
};
};
streamTrack: {
parameters: {
query: {
u: string;
exp: number;
sig: string;
q?: components["schemas"]["StreamQuality"];
};
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Аудио */
200: {
headers: {
[name: string]: unknown;
};
content: {
"audio/*": string;
};
};
default: components["responses"]["Problem"];
};
};
getTracksBatch: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["TrackIds"];
};
};
responses: {
/** @description Треки в порядке запроса; удалённые пропущены */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["TrackList"];
};
};
default: components["responses"]["Problem"];
};
};
postEvents: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["EventBatch"];
};
};
responses: {
/** @description Принято */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["EventBatchResult"];
};
};
default: components["responses"]["Problem"];
};
};
getPlaybackState: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Состояние; пусто — плеер ещё не запускался */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["PlaybackState"];
};
};
default: components["responses"]["Problem"];
};
};
putPlaybackState: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["PlaybackStateInput"];
};
};
responses: {
/** @description Сохранённое состояние */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["PlaybackState"];
};
};
default: components["responses"]["Problem"];
};
};
getHistory: {
parameters: {
query?: {
limit?: components["parameters"]["Limit"];
/** @description Непрозрачный курсор из `next_cursor` предыдущей страницы */
cursor?: components["parameters"]["Cursor"];
};
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Страница истории */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["HistoryPage"];
};
};
default: components["responses"]["Problem"];
};
};
clearHistory: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Очищено */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
default: components["responses"]["Problem"];
};
};
getLikes: {
parameters: {
query?: {
limit?: components["parameters"]["Limit"];
/** @description Непрозрачный курсор из `next_cursor` предыдущей страницы */
cursor?: components["parameters"]["Cursor"];
};
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Страница */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["ReactedTrackPage"];
};
};
default: components["responses"]["Problem"];
};
};
getDislikes: {
parameters: {
query?: {
limit?: components["parameters"]["Limit"];
/** @description Непрозрачный курсор из `next_cursor` предыдущей страницы */
cursor?: components["parameters"]["Cursor"];
};
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Страница */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["ReactedTrackPage"];
};
};
default: components["responses"]["Problem"];
};
};
setTrackReaction: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["ReactionInput"];
};
};
responses: {
/** @description Сохранено */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
default: components["responses"]["Problem"];
};
};
clearTrackReaction: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Снято */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
default: components["responses"]["Problem"];
};
};
getWaveOptions: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Варианты */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["WaveOptions"];
};
};
default: components["responses"]["Problem"];
};
};
startWave: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: {
content: {
"application/json": components["schemas"]["WaveStart"];
};
};
responses: {
/** @description Сессия и первая пачка */
201: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["WaveBatch"];
};
};
default: components["responses"]["Problem"];
};
};
endWave: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Завершена */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
default: components["responses"]["Problem"];
};
};
updateWave: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["WaveContext"];
};
};
responses: {
/** @description Новая пачка */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["WaveBatch"];
};
};
default: components["responses"]["Problem"];
};
};
nextWave: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
requestBody?: {
content: {
"application/json": components["schemas"]["WaveNext"];
};
};
responses: {
/** @description Пачка */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["WaveBatch"];
};
};
default: components["responses"]["Problem"];
};
};
getAndroidLatest: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Последний релиз */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AndroidRelease"];
};
};
default: components["responses"]["Problem"];
};
};
downloadAndroidApk: {
parameters: {
query?: never;
header?: never;
path: {
version: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description APK */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/vnd.android.package-archive": string;
};
};
default: components["responses"]["Problem"];
};
};
}