// // JellyfinMediaQuery.swift // // Copyright 2026 Brendan Szymanski // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // SPDX-License-Identifier: GPL-3.0-or-later // /// A browse or search query against a Jellyfin library. /// /// The server's item endpoint accepts close to ninety query parameters. This type exposes only the /// ones Luminate's browse, search, and filter surfaces actually drive, so a spec regeneration /// cannot ripple into feature code. Every property is optional; a `nil` property is simply not sent /// and the server applies its own default. /// /// ```swift /// var query = JellyfinMediaQuery() /// query.parentID = library.id /// query.includeItemKinds = [.movie] /// query.sortBy = [.sortName] /// query.limit = 60 /// let page = try await client.items(query) /// ``` package struct JellyfinMediaQuery: Hashable, Sendable { /// Restrict results to what this user may see, and populate their playback state. package var userID: String? /// Restrict results to descendants of this item, normally a library. package var parentID: String? /// Only return these kinds of item. package var includeItemKinds: [JellyfinMediaKind]? /// Never return these kinds of item. package var excludeItemKinds: [JellyfinMediaKind]? /// Fetch exactly these items, ignoring the other filters. package var ids: [String]? /// Match items against this free-text term. package var searchTerm: String? /// Order results by these fields, most significant first. package var sortBy: [JellyfinSortField]? /// The direction of each entry in ``sortBy``. package var sortOrder: [JellyfinSortOrder]? /// Optional metadata to populate on each returned item. package var fields: [JellyfinItemField]? /// Skip this many matching items before the first result. package var startIndex: Int32? /// Return at most this many items. package var limit: Int32? /// Search the whole subtree rather than only direct children. package var recursive: Bool? /// Only return items the user has, or has not, favourited. package var isFavorite: Bool? /// Only return items the user has, or has not, watched. package var isPlayed: Bool? /// Only return items carrying one of these genres. package var genres: [String]? /// Only return items produced in one of these years. package var years: [Int32]? /// Only return items with one of these parental rating certificates. package var officialRatings: [String]? /// Only return items whose sort title starts with this string, for the alphabet jump picker. package var nameStartsWith: String? /// Populate each item's playback and favourite state. package var enableUserData: Bool? /// Populate each item's artwork tags. package var enableImages: Bool? /// Return at most this many images per image type. package var imageTypeLimit: Int32? /// Only report artwork tags for these image types. package var enableImageTypes: [JellyfinImageType]? /// Creates an unfiltered query, leaving every parameter to the server's default. /// /// Each parameter sets the property of the same name. package init( userID: String? = nil, parentID: String? = nil, includeItemKinds: [JellyfinMediaKind]? = nil, excludeItemKinds: [JellyfinMediaKind]? = nil, ids: [String]? = nil, searchTerm: String? = nil, sortBy: [JellyfinSortField]? = nil, sortOrder: [JellyfinSortOrder]? = nil, fields: [JellyfinItemField]? = nil, startIndex: Int32? = nil, limit: Int32? = nil, recursive: Bool? = nil, isFavorite: Bool? = nil, isPlayed: Bool? = nil, genres: [String]? = nil, years: [Int32]? = nil, officialRatings: [String]? = nil, nameStartsWith: String? = nil, enableUserData: Bool? = nil, enableImages: Bool? = nil, imageTypeLimit: Int32? = nil, enableImageTypes: [JellyfinImageType]? = nil ) { self.userID = userID self.parentID = parentID self.includeItemKinds = includeItemKinds self.excludeItemKinds = excludeItemKinds self.ids = ids self.searchTerm = searchTerm self.sortBy = sortBy self.sortOrder = sortOrder self.fields = fields self.startIndex = startIndex self.limit = limit self.recursive = recursive self.isFavorite = isFavorite self.isPlayed = isPlayed self.genres = genres self.years = years self.officialRatings = officialRatings self.nameStartsWith = nameStartsWith self.enableUserData = enableUserData self.enableImages = enableImages self.imageTypeLimit = imageTypeLimit self.enableImageTypes = enableImageTypes } }