// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL // This file is automatically generated. DO NOT EDIT /** * AutoDownloadPrefs gates and scores what AutoPickable may choose * without asking. Zero values are permissive: no bitrate window, no * size ceiling and no format restriction. * * **The window is a rate, not a size.** It used to be three numbers in * megabytes, which cannot mean anything on their own: 300 MB is a * generous FLAC single and a suspiciously small boxset, and the user * setting the number has no idea which release the pipeline will * eventually apply it to. A bitrate is the same statement normalised * by how long the music is, so one number holds across a 9-minute EP * and a 3-hour opera — and it is the unit the thing being described is * actually measured in. The runtime is known for every request * auto-pick can act on (`Download.Expected` carries per-track lengths, * and an anchored request is the only kind that reaches here), so this * costs no extra lookup. */ export interface AutoDownloadPrefs { /** * MinKbps and MaxKbps bound the average bitrate auto-pick will * grab. Zero means no bound on that side. A candidate outside the * window is filtered out of auto-pick entirely, not merely scored * down — a 96 kbps rip of the right album is not a worse copy the * user might accept, it is one they said not to take unattended. * * For reference: 320 is the top of MP3, ~500–1000 is FLAC depending * on the material, and anything under ~128 is a transcode. */ "minKbps": number; "maxKbps": number; /** * PreferredKbps nudges the score toward a target rate within the * window, and breaks the tie when several candidates are equally * good matches. Zero disables the nudge; bitrateFit then returns a * neutral value that does not affect ranking. */ "preferredKbps": number; /** * MaxSizeMB is a hard ceiling on the whole candidate, and it is * deliberately still a size. It answers a different question from * the window above — not "is this the quality I want" but "is this * going to fill the disk" — and it has to hold even for a candidate * whose bitrate cannot be worked out, which is exactly the shape a * mislabelled boxset arrives in. Zero means no ceiling. */ "maxSizeMb": number; /** * AllowedFormats restricts auto-pick to candidates whose audio * files are all in one of these formats. Empty means no * restriction. */ "allowedFormats": Format[] | null; } /** * Candidate is one acquirable thing a provider found: a Soulseek user's * folder, a torrent, a YouTube playlist. Providers fill the descriptive * fields; the ranker fills Match, Quality and Score. */ export interface Candidate { /** * ID is unique within the provider that produced it, and is what * gets handed back to Grab. */ "id": string; "providerId": number; "kind": Kind; /** * Protocol determines which transport can fetch this. */ "protocol": Protocol; /** * Descriptive. */ "title": string; "artist"?: string; /** * peer username, indexer name, channel */ "origin"?: string; "files": CandidateFile[] | null; "totalSize": number; /** * Health is the provider's own availability signal, normalized to * 0..1: seeder count for torrents, free upload slots and queue * length for Soulseek. 0.5 when the provider has no signal. */ "health": number; /** * Scores, filled by the ranker. */ "match": MatchScore; "quality": QualityScore; "score": number; } /** * CandidateFile is one file inside a candidate. Soulseek and torrent * results give paths and sizes but no tags, so Format and duration are * inferred from the path and size where possible. */ export interface CandidateFile { "path": string; "size": number; "format": Format; /** * kbps, 0 when unknown */ "bitrate"?: number; "isAudio": boolean; /** * expected track position */ "matchedTo"?: number; } /** * Caps declares which roles a provider fills and which optional * behaviours it supports. The frontend renders controls from this * rather than switching on Kind, so a provider that gains resume * support later needs no frontend change. */ export interface Caps { /** * Roles. */ "canSearch": boolean; "canTransport": boolean; "canDelegate": boolean; /** * CanList marks a provider that keeps a persistent wanted list of * its own, which the reconciler mirrors this app's list into. */ "canList": boolean; /** * Optional behaviours. */ "canResume": boolean; "canCancel": boolean; "reportsSize": boolean; /** * Protocols this provider can transport. Empty for providers that * only fetch their own search results. */ "transports": Protocol[] | null; } /** * Config is a provider's stored settings. Secret values are not held * here — they live in the secrets store keyed by provider ID, so a * config blob can be logged or shown in the UI without redaction. */ export interface Config { "id": number; "kind": Kind; "name": string; "enabled": boolean; "priority": number; "settings": { [_ in string]?: string } | null; /** * SetSecrets names which of the descriptor's secret fields already * have a stored value, without exposing it. Populated only when a * Config is built for the frontend (see Service.withSecretFlags); * empty when read from or written to the store. */ "setSecrets"?: { [_ in string]?: boolean } | null; } /** * Descriptor is the static, instance-independent description of a * provider kind: what it is called, what it can do, and which settings * it needs. The settings page renders its form from this, so a new * provider gets a config UI without any frontend work. */ export interface Descriptor { "kind": Kind; "name": string; /** * Summary is one line explaining what connecting this gets you. */ "summary": string; /** * Caps are the kind's inherent capabilities, before configuration. */ "caps": Caps; /** * Fields are the settings the user must supply. */ "fields": Field[] | null; /** * RequiresExternal names the software the user must run themselves * (a slskd daemon, a Lidarr instance), or is empty for providers * that need nothing but a binary on PATH. */ "requiresExternal"?: string; } /** * DownloadItem is one grab attempt, as stored. * * deliberate: distinguishes it from download.Download (the attempt) and * download.Request (the durable record) at every call site, which a bare * "Item" would not. */ export interface DownloadItem { "id": string; "downloadId": string; "providerId": number; "transportId"?: number; "externalId"?: string; "candidate": Candidate; "state": State; "bytesDone": number; "bytesTotal": number; "error"?: string; "createdAt": string; "updatedAt": string; } /** * DownloadView is one row of the downloads list. * * would stop reading as "one row of the Downloads list" the moment this * package also has a Requests list — see RequestInput/Request nearby. */ export interface DownloadView { "id": string; /** * Anchors. Any may be empty; all empty means free-text. */ "releaseMbid"?: string; "releaseGroupMbid"?: string; /** * RecordingMBID anchors a single-track download. Its Expected holds * exactly that one track, which is what lets a track download be * scored — and therefore auto-picked — on the same footing as an * album. */ "recordingMbid"?: string; /** * RequestID links back to the durable Request row this download was * raised for or attached to, or 0 for a free-text download with * nothing stable to attach to. The reconciler and manual anchored * downloads both write the outcome back through it. */ "requestId"?: number; /** * Source records where the download came from, for the downloads * list. Empty means "manual". */ "source"?: string; /** * Display and query text. Artist/Album are what searches are built * from; Query overrides them when the user typed something raw. */ "artist": string; "album": string; "query"?: string; /** * Expected is the tracklist the anchor resolves to, used for * completeness scoring and for the autotag match at import. Empty * for free-text downloads. */ "expected"?: ExpectedTrack[] | null; /** * LibraryID is the library imported files belong to. */ "libraryId": number; "createdAt": string; "state": State; "error"?: string; "items": DownloadItem[] | null; } /** * Entity says what a request's MBID names, and is the only type * distinction the durable request list makes. */ export enum Entity { /** * The Go zero value for the underlying type of the enum. */ $zero = "", /** * Request entity types. * * EntityArtist is a subscription rather than a thing to fetch: it * is never satisfied, and each reconcile expands the artist's * discography into child requests. */ EntityArtist = "artist", /** * EntityReleaseGroup is an album in the abstract — any release of * it satisfies the request, which is what a user means by "I want * this album". */ EntityReleaseGroup = "release-group", /** * EntityRelease is one specific edition, used when the user picked * a particular pressing. */ EntityRelease = "release", /** * EntityRecording is a single track. */ EntityRecording = "recording", }; /** * ExpectedTrack is one track of the release the user asked for. */ export interface ExpectedTrack { "position": number; "discNumber": number; "title": string; "artist": string; "lengthMillis": number; } /** * Field describes one provider setting for the settings form. */ export interface Field { "key": string; "label": string; "placeholder"?: string; "help"?: string; /** * Secret marks a value stored in the secrets store rather than the * provider config row, and rendered as a password input. */ "secret": boolean; /** * Path marks a value that names a local filesystem directory, so * the settings form can offer a native folder picker beside the * text input rather than making the user type or paste it. */ "path": boolean; "required": boolean; "default"?: string; } /** * Format is a normalized audio container/codec name. */ export enum Format { /** * The Go zero value for the underlying type of the enum. */ $zero = "", /** * Audio formats, ordered by the quality ranking in formatRank. */ FormatUnknown = "", FormatFLAC = "flac", FormatALAC = "alac", FormatWAV = "wav", FormatMP3 = "mp3", FormatAAC = "aac", FormatOGG = "ogg", FormatOpus = "opus", FormatWMA = "wma", }; /** * Kind identifies a provider implementation. It is stored in the * database and used to look up the constructor in the registry, so * values are stable strings and never renamed. */ export enum Kind { /** * The Go zero value for the underlying type of the enum. */ $zero = "", /** * Provider kinds. */ KindSlskd = "slskd", KindYtDlp = "yt-dlp", KindLidarr = "lidarr", KindProwlarr = "prowlarr", KindQBittorrent = "qbittorrent", KindSABnzbd = "sabnzbd", /** * KindFake is an in-memory provider used by tests. It is never * offered in the UI. */ KindFake = "fake", }; /** * MatchScore answers "is this the release the user asked for?" It is * deliberately separate from QualityScore: a perfect match at 128kbps * and a mediocre match in FLAC are different failures, and collapsing * them into one number makes the ranking impossible to explain. */ export interface MatchScore { /** * Overall is 0..1. */ "overall": number; /** * filenames vs expected titles */ "titleFit": number; /** * path/origin vs expected artist */ "artistFit": number; /** * folder name vs album title */ "albumFit": number; /** * audio files vs expected count */ "completeness": number; /** * Anchored records whether an MBID drove this score. Unanchored * matches are capped, because there is nothing to be right about. */ "anchored": boolean; } /** * Protocol is how a candidate's bytes are moved. Search-only providers * report it so the pipeline can pick a compatible transport; providers * that transport their own results use ProtocolDirect. */ export enum Protocol { /** * The Go zero value for the underlying type of the enum. */ $zero = "", /** * Transport protocols. * * ProtocolDirect means the finding provider also does the fetch. */ ProtocolDirect = "direct", ProtocolTorrent = "torrent", ProtocolUsenet = "usenet", }; /** * QualityScore answers "is this a good copy?". */ export interface QualityScore { /** * Overall is 0..1. */ "overall": number; /** * FLAC > V0 > 320 > lower */ "formatRank": number; "bitrate": number; /** * seeders, free slots */ "health": number; /** * user's per-provider preference */ "priority": number; /** * BitrateFit is closeness to the preferred *rate*, which is what * the auto-download window is expressed in. It replaced a * `SizeFit` measured in megabytes: a size means nothing without * knowing how long the music is, so the same number described a * generous single and a suspiciously small boxset. */ "bitrateFit": number; /** * Mixed marks a candidate whose files are not all the same format, * which usually means a hand-assembled folder rather than a rip. */ "mixed": boolean; } /** * Request is one row of the durable request list. */ export interface Request { "id": number; "mbid": string; "entity": Entity; "libraryId": number; /** * Artist and Title are display cache only. Matching always uses * the MBID. */ "artist": string; "title": string; "scope": RequestScope; /** * Secondary includes compilations, live albums and remixes in an * artist request's expansion. */ "secondary": boolean; "state": RequestState; /** * ParentID is set on requests the reconciler derived from an artist * subscription. A request the user pinned directly has none, so * removing the artist leaves it alone. */ "parentId"?: number; "attempts": number; "lastError"?: string; "lastTriedAt"?: string; "nextTryAt"?: string; /** * ExternalIDs maps provider row ID (as a string, because JSON * object keys are strings) to that provider's own identifier for * this request. Only set for providers that keep a persistent * list of their own. */ "externalIds"?: { [_ in string]?: string } | null; "createdAt": string; "updatedAt": string; } /** * RequestInput is what the frontend submits to request something. It * is one MBID and the type of thing it names, because that is * genuinely all a durable request is. */ export interface RequestInput { "mbid": string; "entity": string; "libraryId": number; /** * Artist and Title are display text only, and optional: the * reconciler fills them in from the catalog when the caller has * nothing but an MBID. */ "artist": string; "title": string; /** * Scope and Secondary apply to artist requests. */ "scope": string; "secondary": boolean; } /** * RequestScope applies to artist requests only. */ export enum RequestScope { /** * The Go zero value for the underlying type of the enum. */ $zero = "", /** * Artist request scopes. * * ScopeFuture takes only releases first published after the artist * was added. Default, because subscribing to an artist should not * silently queue their entire back catalogue. */ ScopeFuture = "future", /** * ScopeAll backfills the whole discography as well. */ ScopeAll = "all", }; /** * RequestState is where a request sits. There is deliberately no * "failed": an attempt can fail, a request cannot. A request that has * tried and not found anything is still wanted, with attempts and * last_error recording why it is taking a while. */ export enum RequestState { /** * The Go zero value for the underlying type of the enum. */ $zero = "", /** * Request states. * * RequestStateWanted is the active state: due for another attempt * when its backoff elapses. */ RequestStateWanted = "wanted", /** * RequestStateSatisfied means the library owns it. How it got * there — downloaded here, ripped, bought elsewhere — does not * matter. */ RequestStateSatisfied = "satisfied", /** * RequestStatePaused is the user saying "keep this on the list but * stop trying". */ RequestStatePaused = "paused", }; /** * SearchRequest is what the frontend submits to start a download. */ export interface SearchRequest { "libraryId": number; "releaseMbid": string; "releaseGroupMbid": string; "artist": string; "album": string; "query": string; "expected": ExpectedTrack[] | null; } /** * StartResult is what the picker needs after a search. */ export interface StartResult { "downloadId": string; "candidates": Candidate[] | null; /** * AutoPicked reports that the pipeline already chose and is * downloading, so the picker should show progress rather than a * list of choices. */ "autoPicked": boolean; } /** * State is the lifecycle position of a download item. */ export enum State { /** * The Go zero value for the underlying type of the enum. */ $zero = "", /** * Download item states. Searching through Importing are live; * Complete, Cancelled and Failed are terminal. */ StateSearching = "searching", StateFound = "found", StateQueued = "queued", StateGrabbing = "grabbing", StateVerifying = "verifying", StateTagging = "tagging", StateImporting = "importing", StateComplete = "complete", StateCancelled = "cancelled", StateFailed = "failed", }; /** * Summary reports what a pass did, for logging and for the UI. */ export interface Summary { /** * Expanded is how many child requests artist subscriptions produced. */ "expanded": number; /** * Satisfied is how many requests the library turned out to own. */ "satisfied": number; /** * Attempted is how many requests were searched for. */ "attempted": number; /** * Started is how many of those found a clear enough winner to * download unattended. */ "started": number; /** * Synced is how many requests were pushed to an external list. */ "synced": number; /** * Waiting is how many requests are on the list and still being * looked for. A pass that did nothing is the normal case, and the * UI can only say so honestly if it knows the list was not empty. */ "waiting": number; /** * NoProviders reports that nothing could be searched because no * download client is enabled — the one "nothing happened" the user * can actually fix. */ "noProviders": boolean; }