From b66f84de79680aa71c4da98c05dc596055301481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=BCller-Seydlitz?= Date: Tue, 30 Jul 2024 21:09:58 +0200 Subject: [PATCH 01/13] Conformance with URLSessionDelegate, URLSessionTaskDelegate migrate to async/await --- NotificationService/NotificationService.swift | 48 ++++++++-------- .../Sources/OpenHABCore/Util/HTTPClient.swift | 56 ++++++++++++------- 2 files changed, 59 insertions(+), 45 deletions(-) diff --git a/NotificationService/NotificationService.swift b/NotificationService/NotificationService.swift index 038aacdc..a030ec68 100644 --- a/NotificationService/NotificationService.swift +++ b/NotificationService/NotificationService.swift @@ -18,23 +18,23 @@ import UserNotifications class NotificationService: UNNotificationServiceExtension { var contentHandler: ((UNNotificationContent) -> Void)? var bestAttemptContent: UNMutableNotificationContent? - + override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) if let bestAttemptContent { var notificationActions: [UNNotificationAction] = [] let userInfo = bestAttemptContent.userInfo - + os_log("didReceive userInfo %{PUBLIC}@", log: .default, type: .info, userInfo) - + if let title = userInfo["title"] as? String { bestAttemptContent.title = title } if let message = userInfo["message"] as? String { bestAttemptContent.body = message } - + // Check if the user has defined custom actions in the payload if let actionsArray = parseActions(userInfo), let category = parseCategory(userInfo) { for actionDict in actionsArray { @@ -56,12 +56,12 @@ class NotificationService: UNNotificationServiceExtension { if !notificationActions.isEmpty { os_log("didReceive registering %{PUBLIC}@ for category %{PUBLIC}@", log: .default, type: .info, notificationActions, category) let notificationCategory = - UNNotificationCategory( - identifier: category, - actions: notificationActions, - intentIdentifiers: [], - options: .customDismissAction - ) + UNNotificationCategory( + identifier: category, + actions: notificationActions, + intentIdentifiers: [], + options: .customDismissAction + ) UNUserNotificationCenter.current().getNotificationCategories { existingCategories in var updatedCategories = existingCategories os_log("handleNotification adding category %{PUBLIC}@", log: .default, type: .info, category) @@ -70,13 +70,13 @@ class NotificationService: UNNotificationServiceExtension { } } } - + // check if there is an attachment to put on the notification // this should be last as we need to wait for media // TODO: we should support relative paths and try the user's openHAB (local,remote) for content if let attachmentURLString = userInfo["media-attachment-url"] as? String { let isItem = attachmentURLString.starts(with: "item:") - + let downloadCompletionHandler: @Sendable (UNNotificationAttachment?) -> Void = { attachment in if let attachment { os_log("handleNotification attaching %{PUBLIC}@", log: .default, type: .info, attachmentURLString) @@ -86,7 +86,7 @@ class NotificationService: UNNotificationServiceExtension { } contentHandler(bestAttemptContent) } - + if isItem { downloadAndAttachItemImage(itemURI: attachmentURLString, completion: downloadCompletionHandler) } else { @@ -97,7 +97,7 @@ class NotificationService: UNNotificationServiceExtension { } } } - + override func serviceExtensionTimeWillExpire() { // Called just before the extension will be terminated by the system. // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. @@ -106,7 +106,7 @@ class NotificationService: UNNotificationServiceExtension { contentHandler(bestAttemptContent) } } - + private func parseActions(_ userInfo: [AnyHashable: Any]) -> [[String: String]]? { // Extract actions and convert it from JSON string to an array of dictionaries if let actionsString = userInfo["actions"] as? String, let actionsData = actionsString.data(using: .utf8) { @@ -120,7 +120,7 @@ class NotificationService: UNNotificationServiceExtension { } return nil } - + private func parseCategory(_ userInfo: [AnyHashable: Any]) -> String? { // Extract category from aps dictionary if let aps = userInfo["aps"] as? [String: Any], @@ -129,10 +129,10 @@ class NotificationService: UNNotificationServiceExtension { } return nil } - + private func downloadAndAttachMedia(url: String, completion: @escaping (UNNotificationAttachment?) -> Void) { let client = HTTPClient(username: Preferences.username, password: Preferences.username, alwaysSendBasicAuth: Preferences.alwaysSendCreds) - + let downloadCompletionHandler: @Sendable (URL?, URLResponse?, Error?) -> Void = { (localURL, response, error) in guard let localURL else { os_log("Error downloading media %{PUBLIC}@", log: .default, type: .error, error?.localizedDescription ?? "Unknown error") @@ -147,16 +147,16 @@ class NotificationService: UNNotificationServiceExtension { client.downloadFile(url: url, completionHandler: downloadCompletionHandler) } } - + func downloadAndAttachItemImage(itemURI: String, completion: @escaping (UNNotificationAttachment?) -> Void) { guard let itemURI = URL(string: itemURI), let scheme = itemURI.scheme else { os_log("Could not find scheme %{PUBLIC}@", log: .default, type: .info) completion(nil) return } - + let itemName = String(itemURI.absoluteString.dropFirst(scheme.count + 1)) - + let client = HTTPClient(username: Preferences.username, password: Preferences.password, alwaysSendBasicAuth: Preferences.alwaysSendCreds) client.getItem(baseURLs: [Preferences.localUrl, Preferences.remoteUrl], itemName: itemName) { item, error in guard let item else { @@ -199,16 +199,16 @@ class NotificationService: UNNotificationServiceExtension { completion(nil) } } - + func attachFile(localURL: URL, mimeType: String?, completion: @escaping (UNNotificationAttachment?) -> Void) { do { let fileManager = FileManager.default let tempDirectory = NSTemporaryDirectory() let tempFile = URL(fileURLWithPath: tempDirectory).appendingPathComponent(UUID().uuidString) - + try fileManager.moveItem(at: localURL, to: tempFile) let attachment: UNNotificationAttachment? - + if let mimeType, let utType = UTType(mimeType: mimeType), utType.conforms(to: .data) { diff --git a/OpenHABCore/Sources/OpenHABCore/Util/HTTPClient.swift b/OpenHABCore/Sources/OpenHABCore/Util/HTTPClient.swift index 9bd82403..e7a1cb0c 100644 --- a/OpenHABCore/Sources/OpenHABCore/Util/HTTPClient.swift +++ b/OpenHABCore/Sources/OpenHABCore/Util/HTTPClient.swift @@ -12,7 +12,7 @@ import Foundation import os.log -public class HTTPClient: NSObject, URLSessionDelegate, URLSessionTaskDelegate { +public class HTTPClient: NSObject { // MARK: - Properties private var session: URLSession! @@ -242,7 +242,6 @@ public class HTTPClient: NSObject, URLSessionDelegate, URLSessionTaskDelegate { request.httpBody = body.data(using: .utf8) request.setValue("text/plain", forHTTPHeaderField: "Content-Type") } - performRequest(request: request, download: download) { result, response, error in if let error { os_log("Error with URL %{public}@ : %{public}@", log: .networking, type: .error, url.absoluteString, error.localizedDescription) @@ -281,58 +280,73 @@ public class HTTPClient: NSObject, URLSessionDelegate, URLSessionTaskDelegate { task.resume() } + @available(watchOS 8.0, *) + @available(iOS 15.0, *) + private func performRequest(request: URLRequest, download: Bool) async throws -> (Any?, URLResponse?) { + var request = request + if alwaysSendBasicAuth { + request.setValue(basicAuthHeader(), forHTTPHeaderField: "Authorization") + } + if download { + return try await session.download(for: request) + } else { + return try await session.data(for: request) + } + } +} + +extension HTTPClient: URLSessionDelegate, URLSessionTaskDelegate { // MARK: - URLSessionDelegate for Client Certificates and Basic Auth - public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { - urlSessionInternal(session, task: nil, didReceive: challenge, completionHandler: completionHandler) + public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { + await urlSessionInternal(session, task: nil, didReceive: challenge) } - public func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { - urlSessionInternal(session, task: task, didReceive: challenge, completionHandler: completionHandler) + public func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { + await urlSessionInternal(session, task: task, didReceive: challenge) } - private func urlSessionInternal(_ session: URLSession, task: URLSessionTask?, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + private func urlSessionInternal(_ session: URLSession, task: URLSessionTask?, didReceive challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { os_log("URLAuthenticationChallenge: %{public}@", log: .networking, type: .info, challenge.protectionSpace.authenticationMethod) let authenticationMethod = challenge.protectionSpace.authenticationMethod switch authenticationMethod { case NSURLAuthenticationMethodServerTrust: - handleServerTrust(challenge: challenge, completionHandler: completionHandler) + return await handleServerTrust(challenge: challenge) case NSURLAuthenticationMethodDefault, NSURLAuthenticationMethodHTTPBasic: if let task { task.authAttemptCount += 1 if task.authAttemptCount > 1 { - completionHandler(.cancelAuthenticationChallenge, nil) + return (.cancelAuthenticationChallenge, nil) } else { - handleBasicAuth(challenge: challenge, completionHandler: completionHandler) + return await handleBasicAuth(challenge: challenge) } } else { - handleBasicAuth(challenge: challenge, completionHandler: completionHandler) + return await handleBasicAuth(challenge: challenge) } case NSURLAuthenticationMethodClientCertificate: - handleClientCertificateAuth(challenge: challenge, completionHandler: completionHandler) + return await handleClientCertificateAuth(challenge: challenge) default: - completionHandler(.performDefaultHandling, nil) + return (.performDefaultHandling, nil) } } - private func handleServerTrust(challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + private func handleServerTrust(challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { guard let serverTrust = challenge.protectionSpace.serverTrust else { - completionHandler(.performDefaultHandling, nil) - return + return (.performDefaultHandling, nil) } let credential = URLCredential(trust: serverTrust) - completionHandler(.useCredential, credential) + return (.useCredential, credential) } - private func handleBasicAuth(challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + private func handleBasicAuth(challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { let credential = URLCredential(user: username, password: password, persistence: .forSession) - completionHandler(.useCredential, credential) + return (.useCredential, credential) } - private func handleClientCertificateAuth(challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + private func handleClientCertificateAuth(challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { let certificateManager = ClientCertificateManager() let (disposition, credential) = certificateManager.evaluateTrust(with: challenge) - completionHandler(disposition, credential) + return (disposition, credential) } } From 237940ec56707b196354debbcf7db40ff58f5fa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=BCller-Seydlitz?= Date: Wed, 7 Aug 2024 21:24:24 +0200 Subject: [PATCH 02/13] Got the swift-openapi-generator working on openHAB iOS app: -Properly gets data every 30s -Able to send commands -Making use of structured concurrency, ie async/await, actors -Still a lot to do Renamed OpenHABSitemapPage into OpenHABPage to avoid confusion Reworked OpenHABSitemap to properly handle embedded OpenHABPage Created convenience initializers for OpenHAB models to map from openAPI generated models Properly decoding widgets within a widget Manually modifying the OpenHAB's openAPI schema Manually adding X-Atmosphere-Transport in header parameters for pollDataPage Transferred code to package - requires workaround to invoke the CLI manually: https://swiftpackageindex.com/apple/swift-openapi-generator/1.2.1/documentation/swift-openapi-generator/manually-invoking-the-generator-cli : - clone the generator package locally - run locally swift run swift-openapi-generator generate --config ../Sources/OpenHABCore/openapi/openapi-generator-config.yml --output-directory ../GeneratedSources/openapi ../Sources/OpenHABCore/openapi/openapi.json Exclude the package and the generated code from swiftlint Async update for actor APIActor and initialiser with URL about:blank Using APIActor throughout the app Upgrade target to iOS 16 Helper function openHABpollPage(sitemapname: String, longPolling: Bool) for access without Making use internal accesModifier to properly isolate the internals in OpenHABCore Using openAPI generated interface to send command Support for basic authorization Making use of os logger --- .gitignore | 3 + BuildTools/.swiftlint.yml | 3 +- NotificationService/NotificationService.swift | 48 +- OpenHABCore/Package.swift | 14 +- .../Sources/OpenHABCore/Model/APIActor.swift | 340 + .../Model/OpenHABCommandDescription.swift | 2 +- .../Model/OpenHABCommandOptions.swift | 5 + .../OpenHABCore/Model/OpenHABItem.swift | 3 + .../OpenHABCore/Model/OpenHABOptions.swift | 5 + ...HABSitemapPage.swift => OpenHABPage.swift} | 16 +- .../OpenHABCore/Model/OpenHABSitemap.swift | 55 +- .../Model/OpenHABStateDescription.swift | 2 +- .../OpenHABCore/Model/OpenHABWidget.swift | 10 +- .../Model/OpenHABWidgetMapping.swift | 9 +- .../Sources/OpenHABCore/Util/Future.swift | 121 - .../OpenHABCore/Util/StringExtension.swift | 2 +- .../openapi/openapi-generator-config.yml | 9 + .../Sources/OpenHABCore/openapi/openapi.json | 9770 +++++++++++++++++ .../OpenHABCoreTests/JSONParserTests.swift | 16 +- openHAB.xcodeproj/project.pbxproj | 49 +- .../xcshareddata/swiftpm/Package.resolved | 476 +- .../OpenHABDrawerTableViewController.swift | 67 +- openHAB/OpenHABSitemapViewController.swift | 131 +- .../openapi/openapitest/openapiCorrected.json | 9756 ++++++++++++++++ .../Model/ObservableOpenHABWidget.swift | 6 +- .../openHABWatch Extension/UserData.swift | 61 - 26 files changed, 20350 insertions(+), 629 deletions(-) create mode 100644 OpenHABCore/Sources/OpenHABCore/Model/APIActor.swift rename OpenHABCore/Sources/OpenHABCore/Model/{OpenHABSitemapPage.swift => OpenHABPage.swift} (83%) delete mode 100644 OpenHABCore/Sources/OpenHABCore/Util/Future.swift create mode 100644 OpenHABCore/Sources/OpenHABCore/openapi/openapi-generator-config.yml create mode 100644 OpenHABCore/Sources/OpenHABCore/openapi/openapi.json create mode 100644 openHAB/openapi/openapitest/openapiCorrected.json diff --git a/.gitignore b/.gitignore index e716fd90..92c6fa79 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,6 @@ openHAB.ipa build/ BuildTools/.build OpenHABCore/Package.resolved + +OpenHABCore/Sources/OpenHABCore/GeneratedSources +OpenHABCore/swift-openapi-generator diff --git a/BuildTools/.swiftlint.yml b/BuildTools/.swiftlint.yml index c6622e78..5646cc17 100644 --- a/BuildTools/.swiftlint.yml +++ b/BuildTools/.swiftlint.yml @@ -29,7 +29,8 @@ excluded: - ../fastlane - ../OpenHABCore/.build - .build - + - ../OpenHABCore/Sources/OpenHABCore/GeneratedSources/* + - ../OpenHABCore/swift-openapi-generator nesting: type_level: 2 diff --git a/NotificationService/NotificationService.swift b/NotificationService/NotificationService.swift index 038aacdc..a030ec68 100644 --- a/NotificationService/NotificationService.swift +++ b/NotificationService/NotificationService.swift @@ -18,23 +18,23 @@ import UserNotifications class NotificationService: UNNotificationServiceExtension { var contentHandler: ((UNNotificationContent) -> Void)? var bestAttemptContent: UNMutableNotificationContent? - + override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) if let bestAttemptContent { var notificationActions: [UNNotificationAction] = [] let userInfo = bestAttemptContent.userInfo - + os_log("didReceive userInfo %{PUBLIC}@", log: .default, type: .info, userInfo) - + if let title = userInfo["title"] as? String { bestAttemptContent.title = title } if let message = userInfo["message"] as? String { bestAttemptContent.body = message } - + // Check if the user has defined custom actions in the payload if let actionsArray = parseActions(userInfo), let category = parseCategory(userInfo) { for actionDict in actionsArray { @@ -56,12 +56,12 @@ class NotificationService: UNNotificationServiceExtension { if !notificationActions.isEmpty { os_log("didReceive registering %{PUBLIC}@ for category %{PUBLIC}@", log: .default, type: .info, notificationActions, category) let notificationCategory = - UNNotificationCategory( - identifier: category, - actions: notificationActions, - intentIdentifiers: [], - options: .customDismissAction - ) + UNNotificationCategory( + identifier: category, + actions: notificationActions, + intentIdentifiers: [], + options: .customDismissAction + ) UNUserNotificationCenter.current().getNotificationCategories { existingCategories in var updatedCategories = existingCategories os_log("handleNotification adding category %{PUBLIC}@", log: .default, type: .info, category) @@ -70,13 +70,13 @@ class NotificationService: UNNotificationServiceExtension { } } } - + // check if there is an attachment to put on the notification // this should be last as we need to wait for media // TODO: we should support relative paths and try the user's openHAB (local,remote) for content if let attachmentURLString = userInfo["media-attachment-url"] as? String { let isItem = attachmentURLString.starts(with: "item:") - + let downloadCompletionHandler: @Sendable (UNNotificationAttachment?) -> Void = { attachment in if let attachment { os_log("handleNotification attaching %{PUBLIC}@", log: .default, type: .info, attachmentURLString) @@ -86,7 +86,7 @@ class NotificationService: UNNotificationServiceExtension { } contentHandler(bestAttemptContent) } - + if isItem { downloadAndAttachItemImage(itemURI: attachmentURLString, completion: downloadCompletionHandler) } else { @@ -97,7 +97,7 @@ class NotificationService: UNNotificationServiceExtension { } } } - + override func serviceExtensionTimeWillExpire() { // Called just before the extension will be terminated by the system. // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. @@ -106,7 +106,7 @@ class NotificationService: UNNotificationServiceExtension { contentHandler(bestAttemptContent) } } - + private func parseActions(_ userInfo: [AnyHashable: Any]) -> [[String: String]]? { // Extract actions and convert it from JSON string to an array of dictionaries if let actionsString = userInfo["actions"] as? String, let actionsData = actionsString.data(using: .utf8) { @@ -120,7 +120,7 @@ class NotificationService: UNNotificationServiceExtension { } return nil } - + private func parseCategory(_ userInfo: [AnyHashable: Any]) -> String? { // Extract category from aps dictionary if let aps = userInfo["aps"] as? [String: Any], @@ -129,10 +129,10 @@ class NotificationService: UNNotificationServiceExtension { } return nil } - + private func downloadAndAttachMedia(url: String, completion: @escaping (UNNotificationAttachment?) -> Void) { let client = HTTPClient(username: Preferences.username, password: Preferences.username, alwaysSendBasicAuth: Preferences.alwaysSendCreds) - + let downloadCompletionHandler: @Sendable (URL?, URLResponse?, Error?) -> Void = { (localURL, response, error) in guard let localURL else { os_log("Error downloading media %{PUBLIC}@", log: .default, type: .error, error?.localizedDescription ?? "Unknown error") @@ -147,16 +147,16 @@ class NotificationService: UNNotificationServiceExtension { client.downloadFile(url: url, completionHandler: downloadCompletionHandler) } } - + func downloadAndAttachItemImage(itemURI: String, completion: @escaping (UNNotificationAttachment?) -> Void) { guard let itemURI = URL(string: itemURI), let scheme = itemURI.scheme else { os_log("Could not find scheme %{PUBLIC}@", log: .default, type: .info) completion(nil) return } - + let itemName = String(itemURI.absoluteString.dropFirst(scheme.count + 1)) - + let client = HTTPClient(username: Preferences.username, password: Preferences.password, alwaysSendBasicAuth: Preferences.alwaysSendCreds) client.getItem(baseURLs: [Preferences.localUrl, Preferences.remoteUrl], itemName: itemName) { item, error in guard let item else { @@ -199,16 +199,16 @@ class NotificationService: UNNotificationServiceExtension { completion(nil) } } - + func attachFile(localURL: URL, mimeType: String?, completion: @escaping (UNNotificationAttachment?) -> Void) { do { let fileManager = FileManager.default let tempDirectory = NSTemporaryDirectory() let tempFile = URL(fileURLWithPath: tempDirectory).appendingPathComponent(UUID().uuidString) - + try fileManager.moveItem(at: localURL, to: tempFile) let attachment: UNNotificationAttachment? - + if let mimeType, let utType = UTType(mimeType: mimeType), utType.conforms(to: .data) { diff --git a/OpenHABCore/Package.swift b/OpenHABCore/Package.swift index 8363eda5..ffe19e38 100644 --- a/OpenHABCore/Package.swift +++ b/OpenHABCore/Package.swift @@ -1,11 +1,11 @@ -// swift-tools-version:5.5 +// swift-tools-version:5.9 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "OpenHABCore", - platforms: [.iOS(.v12), .watchOS(.v6)], + platforms: [.iOS(.v16), .watchOS(.v10), .macOS(.v14)], products: [ // Products define the executables and libraries a package produces, and make them visible to other packages. .library( @@ -15,8 +15,10 @@ let package = Package( ], dependencies: [ // Dependencies declare other packages that this package depends on. - .package(name: "Alamofire", url: "https://github.com/Alamofire/Alamofire.git", from: "5.0.0"), - .package(name: "Kingfisher", url: "https://github.com/onevcat/Kingfisher.git", from: "7.0.0") + .package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.0.0"), + .package(url: "https://github.com/onevcat/Kingfisher.git", from: "7.0.0"), + .package(url: "https://github.com/apple/swift-openapi-runtime", from: "1.0.0"), + .package(url: "https://github.com/apple/swift-openapi-urlsession", from: "1.0.0") ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. @@ -25,7 +27,9 @@ let package = Package( name: "OpenHABCore", dependencies: [ .product(name: "Alamofire", package: "Alamofire", condition: .when(platforms: [.iOS, .watchOS])), - .product(name: "Kingfisher", package: "Kingfisher", condition: .when(platforms: [.iOS, .watchOS])) + .product(name: "Kingfisher", package: "Kingfisher", condition: .when(platforms: [.iOS, .watchOS])), + .product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"), + .product(name: "OpenAPIURLSession", package: "swift-openapi-urlsession") ] ), .testTarget( diff --git a/OpenHABCore/Sources/OpenHABCore/Model/APIActor.swift b/OpenHABCore/Sources/OpenHABCore/Model/APIActor.swift new file mode 100644 index 00000000..b0b70859 --- /dev/null +++ b/OpenHABCore/Sources/OpenHABCore/Model/APIActor.swift @@ -0,0 +1,340 @@ +// Copyright (c) 2010-2024 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +// +// File.swift +// +// +// Created by Tim on 10.08.24. +// +import Foundation +import HTTPTypes +import OpenAPIRuntime +import OpenAPIURLSession +import os + +let logger = Logger(subsystem: "org.openhab.app", category: "apiactor") + +public protocol OpenHABSitemapsService { + func openHABSitemaps() async throws -> [OpenHABSitemap] +} + +public protocol OpenHABUiTileService { + func openHABTiles() async throws -> [OpenHABUiTile] +} + +// swiftlint:disable file_types_order + +public actor APIActor { + var api: APIProtocol + var url: URL? + var longPolling = false + var alwaysSendBasicAuth = false + var username: String + var password: String + + public init(username: String = "", password: String = "", alwaysSendBasicAuth: Bool = true) { + let url = "about:blank" + // TODO: Make use of prepareURLSessionConfiguration + let config = URLSessionConfiguration.default +// config.timeoutIntervalForRequest = if longPolling { 35.0 } else { 20.0 } +// config.timeoutIntervalForResource = config.timeoutIntervalForRequest + 25 + let session = URLSession(configuration: config) + self.username = username + self.password = password + self.alwaysSendBasicAuth = alwaysSendBasicAuth + + api = Client( + serverURL: URL(string: url)!, + transport: URLSessionTransport(configuration: .init(session: session)), + middlewares: [AuthorisationMiddleware(username: username, password: password, alwaysSendBasicAuth: alwaysSendBasicAuth)] + ) + } + + private func prepareURLSessionConfiguration(longPolling: Bool) -> URLSessionConfiguration { + let config = URLSessionConfiguration.default +// config.timeoutIntervalForRequest = if longPolling { 35.0 } else { 20.0 } +// config.timeoutIntervalForResource = config.timeoutIntervalForRequest + 25 + return config + } + + public func updateBaseURL(with newURL: URL) async { + if newURL != url { + let config = prepareURLSessionConfiguration(longPolling: longPolling) + let session = URLSession(configuration: config) + url = newURL + api = Client( + serverURL: newURL.appending(path: "/rest"), + transport: URLSessionTransport(configuration: .init(session: session)), + middlewares: [AuthorisationMiddleware(username: username, password: password)] + ) + } + } + + // timeoutIntervalForRequest/timeoutIntervalForResource need to be passed through URLSessionConfiguration when URLSession is created. Therefore create a new APIClient to change values. + public func updateForLongPolling(_ newlongPolling: Bool) async { + if newlongPolling != longPolling { + let config = prepareURLSessionConfiguration(longPolling: longPolling) + let session = URLSession(configuration: config) + longPolling = newlongPolling + api = Client( + serverURL: url!.appending(path: "/rest"), + transport: URLSessionTransport(configuration: .init(session: session)), + middlewares: [AuthorisationMiddleware(username: username, password: password)] + ) + } + } +} + +extension APIActor: OpenHABSitemapsService { + public func openHABSitemaps() async throws -> [OpenHABSitemap] { + try await api.getSitemaps(.init()) + .ok.body.json + .map(OpenHABSitemap.init) + } +} + +extension APIActor: OpenHABUiTileService { + public func openHABTiles() async throws -> [OpenHABUiTile] { + try await api.getUITiles(.init()) + .ok.body.json + .map(OpenHABUiTile.init) + } +} + +extension APIActor { + func openHABSitemap(path: Operations.getSitemapByName.Input.Path) async throws -> OpenHABSitemap? { + let result = try await api.getSitemapByName(path: path) + .ok.body.json + return OpenHABSitemap(result) + } +} + +extension APIActor { + // Internal function for pollPage + func openHABpollPage(path: Operations.pollDataForPage.Input.Path, + headers: Operations.pollDataForPage.Input.Headers) async throws -> OpenHABPage? { + let result = try await api.pollDataForPage(path: path, headers: headers) + .ok.body.json + return OpenHABPage(result) + } + + /// Poll page data on sitemap + /// - Parameters: + /// - sitemapname: name of sitemap + /// - longPolling: set to true for long-polling + public func openHABpollPage(sitemapname: String, longPolling: Bool) async throws -> OpenHABPage? { + var headers = Operations.pollDataForPage.Input.Headers() + + if longPolling { + logger.info("Long-polling, setting X-Atmosphere-Transport") + headers.X_hyphen_Atmosphere_hyphen_Transport = "long-polling" + } else { + headers.X_hyphen_Atmosphere_hyphen_Transport = nil + } + let path = Operations.pollDataForPage.Input.Path(sitemapname: sitemapname, pageid: sitemapname) + await updateForLongPolling(longPolling) + return try await openHABpollPage(path: path, headers: headers) + } +} + +extension APIActor { + func openHABSitemap(path: Operations.getSitemapByName.Input.Path, + headers: Operations.getSitemapByName.Input.Headers) async throws -> OpenHABSitemap? { + let result = try await api.getSitemapByName(path: path, headers: headers) + .ok.body.json + return OpenHABSitemap(result) + } +} + +// MARK: State changes and commands + +public extension APIActor { + func openHABUpdateItemState(itemname: String, with state: String) async throws { + let path = Operations.updateItemState.Input.Path(itemname: itemname) + let body = Operations.updateItemState.Input.Body.plainText(.init(state)) + let response = try await api.updateItemState(path: path, body: body) + _ = try response.accepted + } + + func openHABSendItemCommand(itemname: String, command: String) async throws { + let path = Operations.sendItemCommand.Input.Path(itemname: itemname) + let body = Operations.sendItemCommand.Input.Body.plainText(.init(command)) + let response = try await api.sendItemCommand(path: path, body: body) + _ = try response.ok + } +} + +public struct AuthorisationMiddleware { + private let username: String + private let password: String + private let alwaysSendBasicAuth: Bool + + public init(username: String, password: String, alwaysSendBasicAuth: Bool = false) { + self.username = username + self.password = password + self.alwaysSendBasicAuth = alwaysSendBasicAuth + } +} + +extension AuthorisationMiddleware: ClientMiddleware { + private func basicAuthHeader() -> String { + let credential = Data("\(username):\(password)".utf8).base64EncodedString() + return "Basic \(credential)" + } + + public func intercept(_ request: HTTPRequest, + body: HTTPBody?, + baseURL: URL, + operationID: String, + next: @Sendable (HTTPRequest, HTTPBody?, URL) async throws -> (HTTPResponse, HTTPBody?)) async throws -> (HTTPResponse, HTTPBody?) { + // Use a mutable copy of request + var request = request + + if ((baseURL.host?.hasSuffix("myopenhab.org")) == nil), alwaysSendBasicAuth, !username.isEmpty, !password.isEmpty { + request.headerFields[.authorization] = basicAuthHeader() + } + logger.info("Outgoing request: \(request.headerFields.debugDescription, privacy: .public)") + let (response, body) = try await next(request, body, baseURL) + logger.debug("Incoming response \(response.headerFields.debugDescription)") + return (response, body) + } +} + +extension OpenHABUiTile { + convenience init(_ tile: Components.Schemas.TileDTO) { + self.init(name: tile.name.orEmpty, url: tile.url.orEmpty, imageUrl: tile.imageUrl.orEmpty) + } +} + +extension OpenHABSitemap { + convenience init(_ sitemap: Components.Schemas.SitemapDTO) { + self.init( + name: sitemap.name.orEmpty, + icon: sitemap.icon.orEmpty, + label: sitemap.label.orEmpty, + link: sitemap.link.orEmpty, + page: OpenHABPage(sitemap.homepage) + ) + } +} + +extension OpenHABPage { + convenience init?(_ page: Components.Schemas.PageDTO?) { + if let page { + self.init( + pageId: page.id.orEmpty, + title: page.title.orEmpty, + link: page.link.orEmpty, + leaf: page.leaf ?? false, + widgets: page.widgets?.compactMap { OpenHABWidget($0) } ?? [], + icon: page.icon.orEmpty + ) + } else { + return nil + } + } +} + +extension OpenHABWidgetMapping { + convenience init(_ mapping: Components.Schemas.MappingDTO) { + self.init(command: mapping.command, label: mapping.label) + } +} + +extension OpenHABCommandOptions { + convenience init?(_ options: Components.Schemas.CommandOption?) { + if let options { + self.init(command: options.command.orEmpty, label: options.label.orEmpty) + } else { + return nil + } + } +} + +extension OpenHABOptions { + convenience init?(_ options: Components.Schemas.StateOption?) { + if let options { + self.init(value: options.value.orEmpty, label: options.label.orEmpty) + } else { + return nil + } + } +} + +extension OpenHABStateDescription { + convenience init?(_ state: Components.Schemas.StateDescription?) { + if let state { + self.init(minimum: state.minimum, maximum: state.maximum, step: state.step, readOnly: state.readOnly, options: state.options?.compactMap { OpenHABOptions($0) }, pattern: state.pattern) + } else { + return nil + } + } +} + +extension OpenHABCommandDescription { + convenience init?(_ commands: Components.Schemas.CommandDescription?) { + if let commands { + self.init(commandOptions: commands.commandOptions?.compactMap { OpenHABCommandOptions($0) }) + } else { + return nil + } + } +} + +// swiftlint:disable line_length +extension OpenHABItem { + convenience init?(_ item: Components.Schemas.EnrichedItemDTO?) { + if let item { + self.init(name: item.name.orEmpty, type: item._type.orEmpty, state: item.state.orEmpty, link: item.link.orEmpty, label: item.label.orEmpty, groupType: nil, stateDescription: OpenHABStateDescription(item.stateDescription), commandDescription: OpenHABCommandDescription(item.commandDescription), members: [], category: item.category, options: []) + } else { + return nil + } + } +} + +// swiftlint:enable line_length + +extension OpenHABWidget { + convenience init(_ widget: Components.Schemas.WidgetDTO) { + self.init( + widgetId: widget.widgetId.orEmpty, + label: widget.label.orEmpty, + icon: widget.icon.orEmpty, + type: OpenHABWidget.WidgetType(rawValue: widget._type!), + url: widget.url, + period: widget.period, + minValue: widget.minValue, + maxValue: widget.maxValue, + step: widget.step, + refresh: widget.refresh.map(Int.init), + height: 50, // TODO: + isLeaf: true, + iconColor: widget.iconcolor, + labelColor: widget.labelcolor, + valueColor: widget.valuecolor, + service: widget.service, + state: widget.state, + text: "", + legend: widget.legend, + encoding: widget.encoding, + item: OpenHABItem(widget.item), + linkedPage: OpenHABPage(widget.linkedPage), + mappings: widget.mappings?.compactMap(OpenHABWidgetMapping.init) ?? [], + widgets: widget.widgets?.compactMap { OpenHABWidget($0) } ?? [], + visibility: widget.visibility, + switchSupport: widget.switchSupport, + forceAsItem: widget.forceAsItem + ) + } +} + +// swiftlint:enable file_types_order diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABCommandDescription.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABCommandDescription.swift index 9cf6d397..ce8eff96 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABCommandDescription.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABCommandDescription.swift @@ -14,7 +14,7 @@ import Foundation public class OpenHABCommandDescription { public var commandOptions: [OpenHABCommandOptions] = [] - init(commandOptions: [OpenHABCommandOptions]?) { + public init(commandOptions: [OpenHABCommandOptions]?) { self.commandOptions = commandOptions ?? [] } } diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABCommandOptions.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABCommandOptions.swift index 5484d214..8010dc58 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABCommandOptions.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABCommandOptions.swift @@ -14,4 +14,9 @@ import Foundation public class OpenHABCommandOptions: Decodable { public var command = "" public var label = "" + + public init(command: String = "", label: String = "") { + self.command = command + self.label = label + } } diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABItem.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABItem.swift index f759251b..9c2e97ad 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABItem.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABItem.swift @@ -139,6 +139,7 @@ public extension OpenHABItem { } } +// swiftlint:disable line_length public extension OpenHABItem.CodingData { var openHABItem: OpenHABItem { let mappedMembers = members?.map(\.openHABItem) ?? [] @@ -147,6 +148,8 @@ public extension OpenHABItem.CodingData { } } +// swiftlint:enable line_length + extension CGFloat { init(state string: String, divisor: Float) { let numberFormatter = NumberFormatter() diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABOptions.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABOptions.swift index c98f5e1b..d9a9983e 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABOptions.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABOptions.swift @@ -14,4 +14,9 @@ import Foundation public class OpenHABOptions: Decodable { public var value = "" public var label = "" + + public init(value: String = "", label: String = "") { + self.value = value + self.label = label + } } diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemapPage.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABPage.swift similarity index 83% rename from OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemapPage.swift rename to OpenHABCore/Sources/OpenHABCore/Model/OpenHABPage.swift index bc16248a..0c9632df 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemapPage.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABPage.swift @@ -12,7 +12,7 @@ import Foundation import os.log -public class OpenHABSitemapPage: NSObject { +public class OpenHABPage: NSObject { public var sendCommand: ((_ item: OpenHABItem, _ command: String?) -> Void)? public var widgets: [OpenHABWidget] = [] public var pageId = "" @@ -46,9 +46,9 @@ public class OpenHABSitemapPage: NSObject { } } -public extension OpenHABSitemapPage { - func filter(_ isIncluded: (OpenHABWidget) throws -> Bool) rethrows -> OpenHABSitemapPage { - let filteredOpenHABSitemapPage = try OpenHABSitemapPage( +public extension OpenHABPage { + func filter(_ isIncluded: (OpenHABWidget) throws -> Bool) rethrows -> OpenHABPage { + let filteredOpenHABSitemapPage = try OpenHABPage( pageId: pageId, title: title, link: link, @@ -60,7 +60,7 @@ public extension OpenHABSitemapPage { } } -public extension OpenHABSitemapPage { +public extension OpenHABPage { struct CodingData: Decodable { let pageId: String? let title: String? @@ -80,9 +80,9 @@ public extension OpenHABSitemapPage { } } -public extension OpenHABSitemapPage.CodingData { - var openHABSitemapPage: OpenHABSitemapPage { +public extension OpenHABPage.CodingData { + var openHABSitemapPage: OpenHABPage { let mappedWidgets = widgets?.map(\.openHABWidget) ?? [] - return OpenHABSitemapPage(pageId: pageId.orEmpty, title: title.orEmpty, link: link.orEmpty, leaf: leaf ?? false, widgets: mappedWidgets, icon: icon.orEmpty) + return OpenHABPage(pageId: pageId.orEmpty, title: title.orEmpty, link: link.orEmpty, leaf: leaf ?? false, widgets: mappedWidgets, icon: icon.orEmpty) } } diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemap.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemap.swift index 1eaeda6b..00a03e86 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemap.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemap.swift @@ -32,16 +32,22 @@ public final class OpenHABSitemap: NSObject { public var icon = "" public var label = "" public var link = "" - public var leaf: Bool? - public var homepageLink = "" + public var page: OpenHABPage? - public init(name: String, icon: String, label: String, link: String, leaf: Bool, homepageLink: String) { + public var leaf: Bool? { + page?.leaf + } + + public var homepageLink: String { + page?.link ?? "" + } + + public init(name: String, icon: String, label: String, link: String, page: OpenHABPage?) { self.name = name self.icon = icon self.label = label self.link = link - self.leaf = leaf - self.homepageLink = homepageLink + self.page = page } } @@ -49,7 +55,7 @@ public extension OpenHABSitemap { struct CodingData: Decodable { public let name: String public let label: String - public let page: HomePage + public let page: OpenHABPage.CodingData? public let link: String public let icon: String? @@ -71,40 +77,6 @@ public extension OpenHABSitemap { icon = try container.decodeIfPresent(forKey: .icon) } } - - internal enum PageType: Decodable { - case homepage(HomePage) - case linkedPage(HomePage) - - private enum CodingKeys: String, CodingKey { - case homepage - case linkedPage - } - - enum PostTypeCodingError: Error { - case decoding(String) - } - - init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - if let homePageValue = try? container.decode(HomePage.self, forKey: .homepage) { - self = .homepage(homePageValue) - return - } - if let linkedPageValue = try? container.decode(HomePage.self, forKey: .linkedPage) { - self = .linkedPage(linkedPageValue) - return - } - throw PostTypeCodingError.decoding("Whoops! \(dump(container))") - } - } - - struct HomePage: Decodable { - public let link: String - public let leaf: Bool - public let timeout: ValueOrFalse? - public let widgets: [OpenHABWidget.CodingData]? - } } public extension OpenHABSitemap.CodingData { @@ -114,8 +86,7 @@ public extension OpenHABSitemap.CodingData { icon: icon.orEmpty, label: label, link: link, - leaf: page.leaf, - homepageLink: page.link + page: page?.openHABSitemapPage ) } } diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABStateDescription.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABStateDescription.swift index 03511972..65bebcee 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABStateDescription.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABStateDescription.swift @@ -21,7 +21,7 @@ public class OpenHABStateDescription { public var numberPattern: String? - init(minimum: Double?, maximum: Double?, step: Double?, readOnly: Bool?, options: [OpenHABOptions]?, pattern: String?) { + public init(minimum: Double?, maximum: Double?, step: Double?, readOnly: Bool?, options: [OpenHABOptions]?, pattern: String?) { self.minimum = minimum ?? 0.0 self.maximum = maximum ?? 100.0 self.step = step ?? 1.0 diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidget.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidget.swift index 44773b73..e6b894a2 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidget.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidget.swift @@ -40,7 +40,7 @@ protocol Widget: AnyObject { var legend: Bool { get set } var encoding: String { get set } var item: OpenHABItem? { get set } - var linkedPage: OpenHABSitemapPage? { get set } + var linkedPage: OpenHABPage? { get set } var mappings: [OpenHABWidgetMapping] { get set } var image: UIImage? { get set } var widgets: [ChildWidget] { get set } @@ -92,7 +92,7 @@ public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { public var encoding = "" public var forceAsItem: Bool? public var item: OpenHABItem? - public var linkedPage: OpenHABSitemapPage? + public var linkedPage: OpenHABPage? public var mappings: [OpenHABWidgetMapping] = [] public var image: UIImage? public var widgets: [OpenHABWidget] = [] @@ -212,9 +212,9 @@ extension OpenHABWidget.WidgetType: UnknownCaseRepresentable { static var unknownCase: OpenHABWidget.WidgetType = .unknown } -extension OpenHABWidget { +public extension OpenHABWidget { // This is an ugly initializer - convenience init(widgetId: String, label: String, icon: String, type: WidgetType, url: String?, period: String?, minValue: Double?, maxValue: Double?, step: Double?, refresh: Int?, height: Double?, isLeaf: Bool?, iconColor: String?, labelColor: String?, valueColor: String?, service: String?, state: String?, text: String?, legend: Bool?, encoding: String?, item: OpenHABItem?, linkedPage: OpenHABSitemapPage?, mappings: [OpenHABWidgetMapping], widgets: [OpenHABWidget], visibility: Bool?, switchSupport: Bool?, forceAsItem: Bool?) { + convenience init(widgetId: String, label: String, icon: String, type: WidgetType, url: String?, period: String?, minValue: Double?, maxValue: Double?, step: Double?, refresh: Int?, height: Double?, isLeaf: Bool?, iconColor: String?, labelColor: String?, valueColor: String?, service: String?, state: String?, text: String?, legend: Bool?, encoding: String?, item: OpenHABItem?, linkedPage: OpenHABPage?, mappings: [OpenHABWidgetMapping], widgets: [OpenHABWidget], visibility: Bool?, switchSupport: Bool?, forceAsItem: Bool?) { self.init() id = widgetId self.widgetId = widgetId @@ -281,7 +281,7 @@ public extension OpenHABWidget { let encoding: String? let groupType: String? let item: OpenHABItem.CodingData? - let linkedPage: OpenHABSitemapPage.CodingData? + let linkedPage: OpenHABPage.CodingData? let mappings: [OpenHABWidgetMapping] let widgets: [OpenHABWidget.CodingData] let visibility: Bool? diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidgetMapping.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidgetMapping.swift index a899bc90..6d2d1499 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidgetMapping.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidgetMapping.swift @@ -14,12 +14,9 @@ import Foundation public class OpenHABWidgetMapping: NSObject, Decodable { public var command = "" public var label = "" -} -public extension OpenHABWidgetMapping { - convenience init(command: String, label: String) { - self.init() - self.command = command - self.label = label + public init(command: String?, label: String?) { + self.command = command.orEmpty + self.label = label.orEmpty } } diff --git a/OpenHABCore/Sources/OpenHABCore/Util/Future.swift b/OpenHABCore/Sources/OpenHABCore/Util/Future.swift deleted file mode 100644 index a2cc029d..00000000 --- a/OpenHABCore/Sources/OpenHABCore/Util/Future.swift +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (c) 2010-2024 Contributors to the openHAB project -// -// See the NOTICE file(s) distributed with this work for additional -// information. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0 -// -// SPDX-License-Identifier: EPL-2.0 - -import Foundation - -// swiftlint:disable:next file_types_order -public class Future { - public typealias Result = Swift.Result - - fileprivate var result: Result? { - // Observe whenever a result is assigned, and report it: - didSet { result.map(report) } - } - - private var callbacks = [(Result) -> Void]() - - public func observe(using callback: @escaping (Result) -> Void) { - // If a result has already been set, call the callback directly: - if let result { - return callback(result) - } - - callbacks.append(callback) - } - - private func report(result: Result) { - callbacks.forEach { $0(result) } - callbacks = [] - } -} - -public class Promise: Future { - public init(value: Value? = nil) { - super.init() - - // If the value was already known at the time the promise - // was constructed, we can report it directly: - result = value.map(Result.success) - } - - public func resolve(with value: Value) { - result = .success(value) - } - - public func reject(with error: Error) { - result = .failure(error) - } -} - -public enum NetworkingError: Error { - case invalidURL -} - -public typealias Networking = (Endpoint) -> Future - -extension Future { - func chained(using closure: @escaping (Value) throws -> Future) -> Future { - // We'll start by constructing a "wrapper" promise that will be - // returned from this method: - let promise = Promise() - - // Observe the current future: - observe { result in - switch result { - case let .success(value): - do { - // Attempt to construct a new future using the value - // returned from the first one: - let future = try closure(value) - - // Observe the "nested" future, and once it - // completes, resolve/reject the "wrapper" future: - future.observe { result in - switch result { - case let .success(value): - promise.resolve(with: value) - case let .failure(error): - promise.reject(with: error) - } - } - } catch { - promise.reject(with: error) - } - case let .failure(error): - promise.reject(with: error) - } - } - - return promise - } -} - -public extension Future { - func transformed(with closure: @escaping (Value) throws -> T) -> Future { - chained { value in - try Promise(value: closure(value)) - } - } -} - -// extension Future where Value == Data { -// func decoded() -> Future { -// decoded(as: T.self, using: JSONDecoder()) -// } -// } - -public extension Future where Value == Data { - func decoded(as type: T.Type = T.self, using decoder: JSONDecoder = .init()) -> Future { - transformed { data in - try decoder.decode(T.self, from: data) - } - } -} diff --git a/OpenHABCore/Sources/OpenHABCore/Util/StringExtension.swift b/OpenHABCore/Sources/OpenHABCore/Util/StringExtension.swift index 7ff82430..dc725c77 100644 --- a/OpenHABCore/Sources/OpenHABCore/Util/StringExtension.swift +++ b/OpenHABCore/Sources/OpenHABCore/Util/StringExtension.swift @@ -136,7 +136,7 @@ public extension String { } } -extension String? { +public extension String? { var orEmpty: String { switch self { case let .some(value): diff --git a/OpenHABCore/Sources/OpenHABCore/openapi/openapi-generator-config.yml b/OpenHABCore/Sources/OpenHABCore/openapi/openapi-generator-config.yml new file mode 100644 index 00000000..3a3188b2 --- /dev/null +++ b/OpenHABCore/Sources/OpenHABCore/openapi/openapi-generator-config.yml @@ -0,0 +1,9 @@ +generate: + - types + - client +accessModifier: internal +filter: + tags: + - sitemaps + - ui + - items diff --git a/OpenHABCore/Sources/OpenHABCore/openapi/openapi.json b/OpenHABCore/Sources/OpenHABCore/openapi/openapi.json new file mode 100644 index 00000000..facdf003 --- /dev/null +++ b/OpenHABCore/Sources/OpenHABCore/openapi/openapi.json @@ -0,0 +1,9770 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "openHAB REST API", + "contact": { + "name": "openHAB", + "url": "https://www.openhab.org/docs/" + }, + "version": "8" + }, + "servers": [ + { + "url": "/rest" + } + ], + "paths": { + "/module-types": { + "get": { + "tags": [ + "module-types" + ], + "summary": "Get all available module types.", + "operationId": "getModuleTypes", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "tags", + "in": "query", + "description": "tags for filtering", + "schema": { + "type": "string" + } + }, + { + "name": "type", + "in": "query", + "description": "filtering by action, condition or trigger", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ModuleTypeDTO" + } + } + } + } + } + } + } + }, + "/module-types/{moduleTypeUID}": { + "get": { + "tags": [ + "module-types" + ], + "summary": "Gets a module type corresponding to the given UID.", + "operationId": "getModuleTypeById", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "moduleTypeUID", + "in": "path", + "description": "moduleTypeUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModuleTypeDTO" + } + } + } + }, + "404": { + "description": "Module Type corresponding to the given UID does not found." + } + } + } + }, + "/rules": { + "get": { + "tags": [ + "rules" + ], + "summary": "Get available rules, optionally filtered by tags and/or prefix.", + "operationId": "getRules", + "parameters": [ + { + "name": "prefix", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "tags", + "in": "query", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "summary", + "in": "query", + "description": "summary fields only", + "schema": { + "type": "boolean" + } + }, + { + "name": "staticDataOnly", + "in": "query", + "description": "provides a cacheable list of values not expected to change regularly and honors the If-Modified-Since header, all other parameters are ignored", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EnrichedRuleDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "post": { + "tags": [ + "rules" + ], + "summary": "Creates a rule.", + "operationId": "createRule", + "requestBody": { + "description": "rule data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuleDTO" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Created", + "headers": { + "Location": { + "description": "Newly created Rule", + "schema": { + "type": "string" + } + } + } + }, + "400": { + "description": "Creation of the rule is refused. Missing required parameter." + }, + "409": { + "description": "Creation of the rule is refused. Rule with the same UID already exists." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}/enable": { + "post": { + "tags": [ + "rules" + ], + "summary": "Sets the rule enabled status.", + "operationId": "enableRule", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "enable", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Rule corresponding to the given UID does not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}/actions": { + "get": { + "tags": [ + "rules" + ], + "summary": "Gets the rule actions.", + "operationId": "getRuleActions", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ActionDTO" + } + } + } + } + }, + "404": { + "description": "Rule corresponding to the given UID does not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}": { + "get": { + "tags": [ + "rules" + ], + "summary": "Gets the rule corresponding to the given UID.", + "operationId": "getRuleById", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnrichedRuleDTO" + } + } + } + }, + "404": { + "description": "Rule not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "rules" + ], + "summary": "Updates an existing rule corresponding to the given UID.", + "operationId": "updateRule", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "rule data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuleDTO" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Rule corresponding to the given UID does not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "rules" + ], + "summary": "Removes an existing rule corresponding to the given UID.", + "operationId": "deleteRule", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Rule corresponding to the given UID does not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}/conditions": { + "get": { + "tags": [ + "rules" + ], + "summary": "Gets the rule conditions.", + "operationId": "getRuleConditions", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConditionDTO" + } + } + } + } + }, + "404": { + "description": "Rule corresponding to the given UID does not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}/config": { + "get": { + "tags": [ + "rules" + ], + "summary": "Gets the rule configuration values.", + "operationId": "getRuleConfiguration", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "404": { + "description": "Rule corresponding to the given UID does not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "rules" + ], + "summary": "Sets the rule configuration values.", + "operationId": "updateRuleConfiguration", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "config", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Rule corresponding to the given UID does not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}/{moduleCategory}/{id}": { + "get": { + "tags": [ + "rules" + ], + "summary": "Gets the rule's module corresponding to the given Category and ID.", + "operationId": "getRuleModuleById", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "moduleCategory", + "in": "path", + "description": "moduleCategory", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "path", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModuleDTO" + } + } + } + }, + "404": { + "description": "Rule corresponding to the given UID does not found or does not have a module with such Category and ID." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}/{moduleCategory}/{id}/config": { + "get": { + "tags": [ + "rules" + ], + "summary": "Gets the module's configuration.", + "operationId": "getRuleModuleConfig", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "moduleCategory", + "in": "path", + "description": "moduleCategory", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "path", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "404": { + "description": "Rule corresponding to the given UID does not found or does not have a module with such Category and ID." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}/{moduleCategory}/{id}/config/{param}": { + "get": { + "tags": [ + "rules" + ], + "summary": "Gets the module's configuration parameter.", + "operationId": "getRuleModuleConfigParameter", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "moduleCategory", + "in": "path", + "description": "moduleCategory", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "path", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "param", + "in": "path", + "description": "param", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + }, + "404": { + "description": "Rule corresponding to the given UID does not found or does not have a module with such Category and ID." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "rules" + ], + "summary": "Sets the module's configuration parameter value.", + "operationId": "setRuleModuleConfigParameter", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "moduleCategory", + "in": "path", + "description": "moduleCategory", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "path", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "param", + "in": "path", + "description": "param", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "value", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Rule corresponding to the given UID does not found or does not have a module with such Category and ID." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}/triggers": { + "get": { + "tags": [ + "rules" + ], + "summary": "Gets the rule triggers.", + "operationId": "getRuleTriggers", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TriggerDTO" + } + } + } + } + }, + "404": { + "description": "Rule corresponding to the given UID does not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}/runnow": { + "post": { + "tags": [ + "rules" + ], + "summary": "Executes actions of the rule.", + "operationId": "runRuleNow_1", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "the context for running this rule", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Rule corresponding to the given UID does not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/schedule/simulations": { + "get": { + "tags": [ + "rules" + ], + "summary": "Simulates the executions of rules filtered by tag 'Schedule' within the given times.", + "operationId": "getScheduleRuleSimulations", + "parameters": [ + { + "name": "from", + "in": "query", + "description": "Start time of the simulated rule executions. Will default to the current time. [yyyy-MM-dd'T'HH:mm:ss.SSSZ]", + "schema": { + "type": "string" + } + }, + { + "name": "until", + "in": "query", + "description": "End time of the simulated rule executions. Will default to 30 days after the start time. Must be less than 180 days after the given start time. [yyyy-MM-dd'T'HH:mm:ss.SSSZ]", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RuleExecution" + } + } + } + } + }, + "400": { + "description": "The max. simulation duration of 180 days is exceeded." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/templates": { + "get": { + "tags": [ + "templates" + ], + "summary": "Get all available templates.", + "operationId": "getTemplates", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Template" + } + } + } + } + } + } + } + }, + "/templates/{templateUID}": { + "get": { + "tags": [ + "templates" + ], + "summary": "Gets a template corresponding to the given UID.", + "operationId": "getTemplateById", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "templateUID", + "in": "path", + "description": "templateUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Template" + } + } + } + }, + "404": { + "description": "Template corresponding to the given UID does not found." + } + } + } + }, + "/actions/{thingUID}/{actionUid}": { + "post": { + "tags": [ + "actions" + ], + "summary": "Executes a thing action.", + "operationId": "executeThingAction", + "parameters": [ + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "actionUid", + "in": "path", + "description": "action type UID (including scope, separated by '.')", + "required": true, + "schema": { + "pattern": "[a-zA-Z0-9]+\\.[a-zA-Z0-9]+", + "type": "string" + } + }, + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "action inputs as map (parameter name as key / argument as value)", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "404": { + "description": "Action not found" + }, + "500": { + "description": "Creation of action handler or execution failed" + } + } + } + }, + "/actions/{thingUID}": { + "get": { + "tags": [ + "actions" + ], + "summary": "Get all available actions for provided thing UID", + "operationId": "getAvailableActionsForThing", + "parameters": [ + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/ThingActionDTO" + } + } + } + } + }, + "204": { + "description": "No actions found." + } + } + } + }, + "/uuid": { + "get": { + "tags": [ + "uuid" + ], + "summary": "A unified unique id.", + "operationId": "getUUID", + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + } + } + } + }, + "/audio/defaultsink": { + "get": { + "tags": [ + "audio" + ], + "summary": "Get the default sink if defined or the first available sink.", + "operationId": "getAudioDefaultSink", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AudioSinkDTO" + } + } + } + }, + "404": { + "description": "Sink not found" + } + } + } + }, + "/audio/defaultsource": { + "get": { + "tags": [ + "audio" + ], + "summary": "Get the default source if defined or the first available source.", + "operationId": "getAudioDefaultSource", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AudioSourceDTO" + } + } + } + }, + "404": { + "description": "Source not found" + } + } + } + }, + "/audio/sinks": { + "get": { + "tags": [ + "audio" + ], + "summary": "Get the list of all sinks.", + "operationId": "getAudioSinks", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AudioSinkDTO" + } + } + } + } + } + } + } + }, + "/audio/sources": { + "get": { + "tags": [ + "audio" + ], + "summary": "Get the list of all sources.", + "operationId": "getAudioSources", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AudioSourceDTO" + } + } + } + } + } + } + } + }, + "/auth/logout": { + "post": { + "tags": [ + "auth" + ], + "summary": "Delete the session associated with a refresh token.", + "operationId": "deleteSession", + "requestBody": { + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "type": "object", + "properties": { + "refresh_token": { + "type": "string" + }, + "id": { + "type": "string" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "User is not authenticated" + }, + "404": { + "description": "User or refresh token not found" + } + } + } + }, + "/auth/apitokens": { + "get": { + "tags": [ + "auth" + ], + "summary": "List the API tokens associated to the authenticated user.", + "operationId": "getApiTokens", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserApiTokenDTO" + } + } + } + } + }, + "401": { + "description": "User is not authenticated" + }, + "404": { + "description": "User not found" + } + } + } + }, + "/auth/sessions": { + "get": { + "tags": [ + "auth" + ], + "summary": "List the sessions associated to the authenticated user.", + "operationId": "getSessionsForCurrentUser", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserSessionDTO" + } + } + } + } + }, + "401": { + "description": "User is not authenticated" + }, + "404": { + "description": "User not found" + } + } + } + }, + "/auth/token": { + "post": { + "tags": [ + "auth" + ], + "summary": "Get access and refresh tokens.", + "operationId": "getOAuthToken", + "parameters": [ + { + "name": "useCookie", + "in": "query", + "schema": { + "type": "boolean" + } + } + ], + "requestBody": { + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "type": "object", + "properties": { + "grant_type": { + "type": "string" + }, + "code": { + "type": "string" + }, + "redirect_uri": { + "type": "string" + }, + "client_id": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "code_verifier": { + "type": "string" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResponseDTO" + } + } + } + }, + "400": { + "description": "Invalid request parameters" + } + } + } + }, + "/auth/apitokens/{name}": { + "delete": { + "tags": [ + "auth" + ], + "summary": "Revoke a specified API token associated to the authenticated user.", + "operationId": "removeApiToken", + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "User is not authenticated" + }, + "404": { + "description": "User or API token not found" + } + } + } + }, + "/addons": { + "get": { + "tags": [ + "addons" + ], + "summary": "Get all add-ons.", + "operationId": "getAddons", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "serviceId", + "in": "query", + "description": "service ID", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Addon" + } + } + } + } + }, + "404": { + "description": "Service not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/addons/{addonId}": { + "get": { + "tags": [ + "addons" + ], + "summary": "Get add-on with given ID.", + "operationId": "getAddonById", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "addonId", + "in": "path", + "description": "addon ID", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9-:]+", + "type": "string" + } + }, + { + "name": "serviceId", + "in": "query", + "description": "service ID", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Addon" + } + } + } + }, + "404": { + "description": "Not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/addons/{addonId}/config": { + "get": { + "tags": [ + "addons" + ], + "summary": "Get add-on configuration for given add-on ID.", + "operationId": "getAddonConfiguration", + "parameters": [ + { + "name": "addonId", + "in": "path", + "description": "addon ID", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9-:]+", + "type": "string" + } + }, + { + "name": "serviceId", + "in": "query", + "description": "service ID", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "404": { + "description": "Add-on does not exist" + }, + "500": { + "description": "Configuration can not be read due to internal error" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "addons" + ], + "summary": "Updates an add-on configuration for given ID and returns the old configuration.", + "operationId": "updateAddonConfiguration", + "parameters": [ + { + "name": "addonId", + "in": "path", + "description": "Add-on id", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9-:]+", + "type": "string" + } + }, + { + "name": "serviceId", + "in": "query", + "description": "service ID", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "204": { + "description": "No old configuration" + }, + "404": { + "description": "Add-on does not exist" + }, + "500": { + "description": "Configuration can not be updated due to internal error" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/addons/services": { + "get": { + "tags": [ + "addons" + ], + "summary": "Get all add-on types.", + "operationId": "getAddonTypes", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AddonType" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/addons/suggestions": { + "get": { + "tags": [ + "addons" + ], + "summary": "Get suggested add-ons to be installed.", + "operationId": "getSuggestedAddons", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Addon" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/addons/types": { + "get": { + "tags": [ + "addons" + ], + "summary": "Get add-on services.", + "operationId": "getAddonServices", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "serviceId", + "in": "query", + "description": "service ID", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AddonType" + } + } + } + } + }, + "404": { + "description": "Service not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/addons/{addonId}/install": { + "post": { + "tags": [ + "addons" + ], + "summary": "Installs the add-on with the given ID.", + "operationId": "installAddonById", + "parameters": [ + { + "name": "addonId", + "in": "path", + "description": "addon ID", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9-:]+", + "type": "string" + } + }, + { + "name": "serviceId", + "in": "query", + "description": "service ID", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/addons/url/{url}/install": { + "post": { + "tags": [ + "addons" + ], + "summary": "Installs the add-on from the given URL.", + "operationId": "installAddonFromURL", + "parameters": [ + { + "name": "url", + "in": "path", + "description": "addon install URL", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "The given URL is malformed or not valid." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/addons/{addonId}/uninstall": { + "post": { + "tags": [ + "addons" + ], + "summary": "Uninstalls the add-on with the given ID.", + "operationId": "uninstallAddon", + "parameters": [ + { + "name": "addonId", + "in": "path", + "description": "addon ID", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9-:]+", + "type": "string" + } + }, + { + "name": "serviceId", + "in": "query", + "description": "service ID", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/channel-types": { + "get": { + "tags": [ + "channel-types" + ], + "summary": "Gets all available channel types.", + "operationId": "getChannelTypes", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "prefixes", + "in": "query", + "description": "filter UIDs by prefix (multiple comma-separated prefixes allowed, for example: 'system,mqtt')", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/ChannelTypeDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/channel-types/{channelTypeUID}": { + "get": { + "tags": [ + "channel-types" + ], + "summary": "Gets channel type by UID.", + "operationId": "getChannelTypeByUID", + "parameters": [ + { + "name": "channelTypeUID", + "in": "path", + "description": "channelTypeUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Channel type with provided channelTypeUID does not exist.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChannelTypeDTO" + } + } + } + }, + "404": { + "description": "No content" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/channel-types/{channelTypeUID}/linkableItemTypes": { + "get": { + "tags": [ + "channel-types" + ], + "summary": "Gets the item types the given trigger channel type UID can be linked to.", + "operationId": "getLinkableItemTypesByChannelTypeUID", + "parameters": [ + { + "name": "channelTypeUID", + "in": "path", + "description": "channelTypeUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "204": { + "description": "No content: channel type has no linkable items or is no trigger channel." + }, + "404": { + "description": "Given channel type UID not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/config-descriptions": { + "get": { + "tags": [ + "config-descriptions" + ], + "summary": "Gets all available config descriptions.", + "operationId": "getConfigDescriptions", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "scheme", + "in": "query", + "description": "scheme filter", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/config-descriptions/{uri}": { + "get": { + "tags": [ + "config-descriptions" + ], + "summary": "Gets a config description by URI.", + "operationId": "getConfigDescriptionByURI", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "uri", + "in": "path", + "description": "uri", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConfigDescriptionDTO" + } + } + } + }, + "400": { + "description": "Invalid URI syntax" + }, + "404": { + "description": "Not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/discovery": { + "get": { + "tags": [ + "discovery" + ], + "summary": "Gets all bindings that support discovery.", + "operationId": "getBindingsWithDiscoverySupport", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/discovery/bindings/{bindingId}/scan": { + "post": { + "tags": [ + "discovery" + ], + "summary": "Starts asynchronous discovery process for a binding and returns the timeout in seconds of the discovery operation.", + "operationId": "scan", + "parameters": [ + { + "name": "bindingId", + "in": "path", + "description": "bindingId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "type": "integer", + "format": "int32" + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/inbox/{thingUID}/approve": { + "post": { + "tags": [ + "inbox" + ], + "summary": "Approves the discovery result by adding the thing to the registry.", + "operationId": "approveInboxItemById", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "newThingId", + "in": "query", + "description": "new thing ID", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "thing label", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid new thing ID." + }, + "404": { + "description": "Thing unable to be approved." + }, + "409": { + "description": "No binding found that supports this thing." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/inbox/{thingUID}": { + "delete": { + "tags": [ + "inbox" + ], + "summary": "Removes the discovery result from the inbox.", + "operationId": "removeItemFromInbox", + "parameters": [ + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Discovery result not found in the inbox." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/inbox": { + "get": { + "tags": [ + "inbox" + ], + "summary": "Get all discovered things.", + "operationId": "getDiscoveredInboxItems", + "parameters": [ + { + "name": "includeIgnored", + "in": "query", + "description": "If true, include ignored inbox entries. Defaults to true", + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DiscoveryResultDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/inbox/{thingUID}/ignore": { + "post": { + "tags": [ + "inbox" + ], + "summary": "Flags a discovery result as ignored for further processing.", + "operationId": "flagInboxItemAsIgnored", + "parameters": [ + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/inbox/{thingUID}/unignore": { + "post": { + "tags": [ + "inbox" + ], + "summary": "Removes ignore flag from a discovery result.", + "operationId": "removeIgnoreFlagOnInboxItem", + "parameters": [ + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/items/{itemName}/members/{memberItemName}": { + "put": { + "tags": [ + "items" + ], + "summary": "Adds a new member to a group item.", + "operationId": "addMemberToGroupItem", + "parameters": [ + { + "name": "itemName", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "memberItemName", + "in": "path", + "description": "member item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Item or member item not found or item is not of type group item." + }, + "405": { + "description": "Member item is not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "items" + ], + "summary": "Removes an existing member from a group item.", + "operationId": "removeMemberFromGroupItem", + "parameters": [ + { + "name": "itemName", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "memberItemName", + "in": "path", + "description": "member item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Item or member item not found or item is not of type group item." + }, + "405": { + "description": "Member item is not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/items/{itemname}/metadata/{namespace}": { + "put": { + "tags": [ + "items" + ], + "summary": "Adds metadata to an item.", + "operationId": "addMetadataToItem", + "parameters": [ + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "namespace", + "in": "path", + "description": "namespace", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "metadata", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetadataDTO" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "201": { + "description": "Created" + }, + "400": { + "description": "Metadata value empty." + }, + "404": { + "description": "Item not found." + }, + "405": { + "description": "Metadata not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "items" + ], + "summary": "Removes metadata from an item.", + "operationId": "removeMetadataFromItem", + "parameters": [ + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "namespace", + "in": "path", + "description": "namespace", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Item not found." + }, + "405": { + "description": "Meta data not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/items/{itemname}/tags/{tag}": { + "put": { + "tags": [ + "items" + ], + "summary": "Adds a tag to an item.", + "operationId": "addTagToItem", + "parameters": [ + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "tag", + "in": "path", + "description": "tag", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Item not found." + }, + "405": { + "description": "Item not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "items" + ], + "summary": "Removes a tag from an item.", + "operationId": "removeTagFromItem", + "parameters": [ + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "tag", + "in": "path", + "description": "tag", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Item not found." + }, + "405": { + "description": "Item not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/items/{itemname}": { + "get": { + "tags": [ + "items" + ], + "summary": "Gets a single item.", + "operationId": "getItemByName", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "metadata", + "in": "query", + "description": "metadata selector - a comma separated list or a regular expression (returns all if no value given)", + "schema": { + "type": "string", + "default": ".*" + } + }, + { + "name": "recursive", + "in": "query", + "description": "get member items if the item is a group item", + "schema": { + "type": "boolean", + "default": true + } + }, + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnrichedItemDTO" + } + } + } + }, + "404": { + "description": "Item not found" + } + } + }, + "put": { + "tags": [ + "items" + ], + "summary": "Adds a new item to the registry or updates the existing item.", + "operationId": "addOrUpdateItemInRegistry", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + } + ], + "requestBody": { + "description": "item data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GroupItemDTO" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/EnrichedItemDTO" + } + } + } + }, + "201": { + "description": "Item created." + }, + "400": { + "description": "Payload invalid." + }, + "404": { + "description": "Item not found or name in path invalid." + }, + "405": { + "description": "Item not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "post": { + "tags": [ + "items" + ], + "summary": "Sends a command to an item.", + "operationId": "sendItemCommand", + "parameters": [ + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + } + ], + "requestBody": { + "description": "valid item command (e.g. ON, OFF, UP, DOWN, REFRESH)", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Item command null" + }, + "404": { + "description": "Item not found" + } + } + }, + "delete": { + "tags": [ + "items" + ], + "summary": "Removes an item from the registry.", + "operationId": "removeItemFromRegistry", + "parameters": [ + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Item not found or item is not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/items": { + "get": { + "tags": [ + "items" + ], + "summary": "Get all available items.", + "operationId": "getItems", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "type", + "in": "query", + "description": "item type filter", + "schema": { + "type": "string" + } + }, + { + "name": "tags", + "in": "query", + "description": "item tag filter", + "schema": { + "type": "string" + } + }, + { + "name": "metadata", + "in": "query", + "description": "metadata selector - a comma separated list or a regular expression (returns all if no value given)", + "schema": { + "type": "string", + "default": ".*" + } + }, + { + "name": "recursive", + "in": "query", + "description": "get member items recursively", + "schema": { + "type": "boolean", + "default": false + } + }, + { + "name": "fields", + "in": "query", + "description": "limit output to the given fields (comma separated)", + "schema": { + "type": "string" + } + }, + { + "name": "staticDataOnly", + "in": "query", + "description": "provides a cacheable list of values not expected to change regularly and checks the If-Modified-Since header, all other parameters are ignored except \"metadata\"", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EnrichedItemDTO" + } + } + } + } + } + } + }, + "put": { + "tags": [ + "items" + ], + "summary": "Adds a list of items to the registry or updates the existing items.", + "operationId": "addOrUpdateItemsInRegistry", + "requestBody": { + "description": "array of item data", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GroupItemDTO" + } + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "type": "string" + } + } + } + }, + "400": { + "description": "Payload is invalid." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/items/{itemname}/state": { + "get": { + "tags": [ + "items" + ], + "summary": "Gets the state of an item.", + "operationId": "getItemState_1", + "parameters": [ + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + }, + "404": { + "description": "Item not found" + } + } + }, + "put": { + "tags": [ + "items" + ], + "summary": "Updates the state of an item.", + "operationId": "updateItemState", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + } + ], + "requestBody": { + "description": "valid item state (e.g. ON, OFF)", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "Item state null" + }, + "404": { + "description": "Item not found" + } + } + } + }, + "/items/{itemname}/metadata/namespaces": { + "get": { + "tags": [ + "items" + ], + "summary": "Gets the namespace of an item.", + "operationId": "getItemNamespaces", + "parameters": [ + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "404": { + "description": "Item not found" + } + } + } + }, + "/items/{itemName}/semantic/{semanticClass}": { + "get": { + "tags": [ + "items" + ], + "summary": "Gets the item which defines the requested semantics of an item.", + "operationId": "getSemanticItem", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "itemName", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "\\w+", + "type": "string" + } + }, + { + "name": "semanticClass", + "in": "path", + "description": "semantic class", + "required": true, + "schema": { + "pattern": "\\w+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Item not found" + } + } + } + }, + "/items/metadata/purge": { + "post": { + "tags": [ + "items" + ], + "summary": "Remove unused/orphaned metadata.", + "operationId": "purgeDatabase", + "responses": { + "200": { + "description": "OK" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/links": { + "get": { + "tags": [ + "links" + ], + "summary": "Gets all available links.", + "operationId": "getItemLinks", + "parameters": [ + { + "name": "channelUID", + "in": "query", + "description": "filter by channel UID", + "schema": { + "type": "string" + } + }, + { + "name": "itemName", + "in": "query", + "description": "filter by item name", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EnrichedItemChannelLinkDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/links/{itemName}/{channelUID}": { + "get": { + "tags": [ + "links" + ], + "summary": "Retrieves an individual link.", + "operationId": "getItemLink", + "parameters": [ + { + "name": "itemName", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "channelUID", + "in": "path", + "description": "channel UID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnrichedItemChannelLinkDTO" + } + } + } + }, + "404": { + "description": "Content does not match the path" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "links" + ], + "summary": "Links an item to a channel.", + "operationId": "linkItemToChannel", + "parameters": [ + { + "name": "itemName", + "in": "path", + "description": "itemName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "channelUID", + "in": "path", + "description": "channelUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "link data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ItemChannelLinkDTO" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Content does not match the path" + }, + "405": { + "description": "Link is not editable" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "links" + ], + "summary": "Unlinks an item from a channel.", + "operationId": "unlinkItemFromChannel", + "parameters": [ + { + "name": "itemName", + "in": "path", + "description": "itemName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "channelUID", + "in": "path", + "description": "channelUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Link not found." + }, + "405": { + "description": "Link not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/links/orphans": { + "get": { + "tags": [ + "links" + ], + "summary": "Get orphan links between items and broken/non-existent thing channels", + "operationId": "getOrphanLinks", + "responses": { + "200": { + "description": "List of broken links" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/links/purge": { + "post": { + "tags": [ + "links" + ], + "summary": "Remove unused/orphaned links.", + "operationId": "purgeDatabase_1", + "responses": { + "200": { + "description": "OK" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/links/{object}": { + "delete": { + "tags": [ + "links" + ], + "summary": "Delete all links that refer to an item or thing.", + "operationId": "removeAllLinksForObject", + "parameters": [ + { + "name": "object", + "in": "path", + "description": "item name or thing UID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/persistence/{serviceId}": { + "get": { + "tags": [ + "persistence" + ], + "summary": "Gets a persistence service configuration.", + "operationId": "getPersistenceServiceConfiguration", + "parameters": [ + { + "name": "serviceId", + "in": "path", + "description": "Id of the persistence service.", + "required": true, + "schema": { + "pattern": "[a-zA-Z0-9]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersistenceServiceConfigurationDTO" + } + } + } + }, + "404": { + "description": "Service configuration not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "persistence" + ], + "summary": "Sets a persistence service configuration.", + "operationId": "putPersistenceServiceConfiguration", + "parameters": [ + { + "name": "serviceId", + "in": "path", + "description": "Id of the persistence service.", + "required": true, + "schema": { + "pattern": "[a-zA-Z0-9]+", + "type": "string" + } + } + ], + "requestBody": { + "description": "service configuration", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersistenceServiceConfigurationDTO" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersistenceServiceConfigurationDTO" + } + } + } + }, + "201": { + "description": "PersistenceServiceConfiguration created." + }, + "400": { + "description": "Payload invalid." + }, + "405": { + "description": "PersistenceServiceConfiguration not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "persistence" + ], + "summary": "Deletes a persistence service configuration.", + "operationId": "deletePersistenceServiceConfiguration", + "parameters": [ + { + "name": "serviceId", + "in": "path", + "description": "Id of the persistence service.", + "required": true, + "schema": { + "pattern": "[a-zA-Z0-9]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Persistence service configuration not found." + }, + "405": { + "description": "Persistence service configuration not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/persistence/items/{itemname}": { + "get": { + "tags": [ + "persistence" + ], + "summary": "Gets item persistence data from the persistence service.", + "operationId": "getItemDataFromPersistenceService", + "parameters": [ + { + "name": "serviceId", + "in": "query", + "description": "Id of the persistence service. If not provided the default service will be used", + "schema": { + "type": "string" + } + }, + { + "name": "itemname", + "in": "path", + "description": "The item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "starttime", + "in": "query", + "description": "Start time of the data to return. Will default to 1 day before endtime. [yyyy-MM-dd'T'HH:mm:ss.SSSZ]", + "schema": { + "type": "string" + } + }, + { + "name": "endtime", + "in": "query", + "description": "End time of the data to return. Will default to current time. [yyyy-MM-dd'T'HH:mm:ss.SSSZ]", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "Page number of data to return. This parameter will enable paging.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "pagelength", + "in": "query", + "description": "The length of each page.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "boundary", + "in": "query", + "description": "Gets one value before and after the requested period.", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ItemHistoryDTO" + } + } + } + }, + "404": { + "description": "Unknown Item or persistence service" + } + } + }, + "put": { + "tags": [ + "persistence" + ], + "summary": "Stores item persistence data into the persistence service.", + "operationId": "storeItemDataInPersistenceService", + "parameters": [ + { + "name": "serviceId", + "in": "query", + "description": "Id of the persistence service. If not provided the default service will be used", + "schema": { + "type": "string" + } + }, + { + "name": "itemname", + "in": "path", + "description": "The item name.", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "Time of the data to be stored. Will default to current time. [yyyy-MM-dd'T'HH:mm:ss.SSSZ]", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "state", + "in": "query", + "description": "The state to store.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Unknown Item or persistence service" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "persistence" + ], + "summary": "Deletes item persistence data from a specific persistence service in a given time range.", + "operationId": "deleteItemFromPersistenceService", + "parameters": [ + { + "name": "serviceId", + "in": "query", + "description": "Id of the persistence service.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "itemname", + "in": "path", + "description": "The item name.", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "starttime", + "in": "query", + "description": "Start of the time range to be deleted. [yyyy-MM-dd'T'HH:mm:ss.SSSZ]", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "endtime", + "in": "query", + "description": "End of the time range to be deleted. [yyyy-MM-dd'T'HH:mm:ss.SSSZ]", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "400": { + "description": "Invalid filter parameters" + }, + "404": { + "description": "Unknown persistence service" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/persistence/items": { + "get": { + "tags": [ + "persistence" + ], + "summary": "Gets a list of items available via a specific persistence service.", + "operationId": "getItemsForPersistenceService", + "parameters": [ + { + "name": "serviceId", + "in": "query", + "description": "Id of the persistence service. If not provided the default service will be used", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistenceItemInfo" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/persistence": { + "get": { + "tags": [ + "persistence" + ], + "summary": "Gets a list of persistence services.", + "operationId": "getPersistenceServices", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistenceServiceDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/profile-types": { + "get": { + "tags": [ + "profile-types" + ], + "summary": "Gets all available profile types.", + "operationId": "getProfileTypes", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "channelTypeUID", + "in": "query", + "description": "channel type filter", + "schema": { + "type": "string" + } + }, + { + "name": "itemType", + "in": "query", + "description": "item type filter", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/ProfileTypeDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/services/{serviceId}/config": { + "get": { + "tags": [ + "services" + ], + "summary": "Get service configuration for given service ID.", + "operationId": "getServiceConfig", + "parameters": [ + { + "name": "serviceId", + "in": "path", + "description": "service ID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "500": { + "description": "Configuration can not be read due to internal error" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "services" + ], + "summary": "Updates a service configuration for given service ID and returns the old configuration.", + "operationId": "updateServiceConfig", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "serviceId", + "in": "path", + "description": "service ID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "204": { + "description": "No old configuration" + }, + "500": { + "description": "Configuration can not be updated due to internal error" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "services" + ], + "summary": "Deletes a service configuration for given service ID and returns the old configuration.", + "operationId": "deleteServiceConfig", + "parameters": [ + { + "name": "serviceId", + "in": "path", + "description": "service ID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "204": { + "description": "No old configuration" + }, + "500": { + "description": "Configuration can not be deleted due to internal error" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/services": { + "get": { + "tags": [ + "services" + ], + "summary": "Get all configurable services.", + "operationId": "getServices", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigurableServiceDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/services/{serviceId}": { + "get": { + "tags": [ + "services" + ], + "summary": "Get configurable service for given service ID.", + "operationId": "getServicesById", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "serviceId", + "in": "path", + "description": "service ID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConfigurableServiceDTO" + } + } + } + }, + "404": { + "description": "Not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/services/{serviceId}/contexts": { + "get": { + "tags": [ + "services" + ], + "summary": "Get existing multiple context service configurations for the given factory PID.", + "operationId": "getServiceContext", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "serviceId", + "in": "path", + "description": "service ID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigurableServiceDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/tags": { + "get": { + "tags": [ + "tags" + ], + "summary": "Get all available semantic tags.", + "operationId": "getSemanticTags", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EnrichedSemanticTagDTO" + } + } + } + } + } + } + }, + "post": { + "tags": [ + "tags" + ], + "summary": "Creates a new semantic tag and adds it to the registry.", + "operationId": "createSemanticTag", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "tag data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnrichedSemanticTagDTO" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/EnrichedSemanticTagDTO" + } + } + } + }, + "400": { + "description": "The tag identifier is invalid or the tag label is missing." + }, + "409": { + "description": "A tag with the same identifier already exists." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/tags/{tagId}": { + "get": { + "tags": [ + "tags" + ], + "summary": "Gets a semantic tag and its sub tags.", + "operationId": "getSemanticTagAndSubTags", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "tagId", + "in": "path", + "description": "tag id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EnrichedSemanticTagDTO" + } + } + } + } + }, + "404": { + "description": "Semantic tag not found." + } + } + }, + "put": { + "tags": [ + "tags" + ], + "summary": "Updates a semantic tag.", + "operationId": "updateSemanticTag", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "tagId", + "in": "path", + "description": "tag id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "tag data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnrichedSemanticTagDTO" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/EnrichedSemanticTagDTO" + } + } + } + }, + "404": { + "description": "Semantic tag not found." + }, + "405": { + "description": "Semantic tag not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "tags" + ], + "summary": "Removes a semantic tag and its sub tags from the registry.", + "operationId": "removeSemanticTag", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "tagId", + "in": "path", + "description": "tag id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK, was deleted." + }, + "404": { + "description": "Semantic tag not found." + }, + "405": { + "description": "Semantic tag not removable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/things": { + "get": { + "tags": [ + "things" + ], + "summary": "Get all available things.", + "operationId": "getThings", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "summary", + "in": "query", + "description": "summary fields only", + "schema": { + "type": "boolean" + } + }, + { + "name": "staticDataOnly", + "in": "query", + "description": "provides a cacheable list of values not expected to change regularly and checks the If-Modified-Since header", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/EnrichedThingDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "post": { + "tags": [ + "things" + ], + "summary": "Creates a new thing and adds it to the registry.", + "operationId": "createThingInRegistry", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "thing data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThingDTO" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/EnrichedThingDTO" + } + } + } + }, + "400": { + "description": "A uid must be provided, if no binding can create a thing of this type." + }, + "409": { + "description": "A thing with the same uid already exists." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/things/{thingUID}": { + "get": { + "tags": [ + "things" + ], + "summary": "Gets thing by UID.", + "operationId": "getThingById", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnrichedThingDTO" + } + } + } + }, + "404": { + "description": "Thing not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "things" + ], + "summary": "Updates a thing.", + "operationId": "updateThing", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "thing", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThingDTO" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/EnrichedThingDTO" + } + } + } + }, + "404": { + "description": "Thing not found." + }, + "409": { + "description": "Thing could not be updated as it is not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "things" + ], + "summary": "Removes a thing from the registry. Set 'force' to __true__ if you want the thing to be removed immediately.", + "operationId": "removeThingById", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "force", + "in": "query", + "description": "force", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "OK, was deleted." + }, + "202": { + "description": "ACCEPTED for asynchronous deletion." + }, + "404": { + "description": "Thing not found." + }, + "409": { + "description": "Thing could not be deleted because it's not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/things/{thingUID}/config/status": { + "get": { + "tags": [ + "things" + ], + "summary": "Gets thing config status.", + "operationId": "getThingConfigStatus", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thing", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigStatusMessage" + } + } + } + } + }, + "404": { + "description": "Thing not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/things/{thingUID}/firmware/status": { + "get": { + "tags": [ + "things" + ], + "summary": "Gets thing's firmware status.", + "operationId": "getThingFirmwareStatus", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thing", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/FirmwareStatusDTO" + } + } + } + }, + "204": { + "description": "No firmware status provided by this Thing." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/things/{thingUID}/firmwares": { + "get": { + "tags": [ + "things" + ], + "summary": "Get all available firmwares for provided thing UID", + "operationId": "getAvailableFirmwaresForThing", + "parameters": [ + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/FirmwareDTO" + } + } + } + } + }, + "204": { + "description": "No firmwares found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/things/{thingUID}/status": { + "get": { + "tags": [ + "things" + ], + "summary": "Gets thing status.", + "operationId": "getThingStatus", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thing", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThingStatusInfo" + } + } + } + }, + "404": { + "description": "Thing not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/things/{thingUID}/enable": { + "put": { + "tags": [ + "things" + ], + "summary": "Sets the thing enabled status.", + "operationId": "enableThing", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thing", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "enabled", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/EnrichedThingDTO" + } + } + } + }, + "404": { + "description": "Thing not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/things/{thingUID}/config": { + "put": { + "tags": [ + "things" + ], + "summary": "Updates thing's configuration.", + "operationId": "updateThingConfig", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thing", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "configuration parameters", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/EnrichedThingDTO" + } + } + } + }, + "400": { + "description": "Configuration of the thing is not valid." + }, + "404": { + "description": "Thing not found" + }, + "409": { + "description": "Thing could not be updated as it is not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/things/{thingUID}/firmware/{firmwareVersion}": { + "put": { + "tags": [ + "things" + ], + "summary": "Update thing firmware.", + "operationId": "updateThingFirmware", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thing", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "firmwareVersion", + "in": "path", + "description": "version", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Firmware update preconditions not satisfied." + }, + "404": { + "description": "Thing not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/thing-types": { + "get": { + "tags": [ + "thing-types" + ], + "summary": "Gets all available thing types without config description, channels and properties.", + "operationId": "getThingTypes", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "bindingId", + "in": "query", + "description": "filter by binding Id", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/StrippedThingTypeDTO" + } + } + } + } + } + } + } + }, + "/thing-types/{thingTypeUID}": { + "get": { + "tags": [ + "thing-types" + ], + "summary": "Gets thing type by UID.", + "operationId": "getThingTypeById", + "parameters": [ + { + "name": "thingTypeUID", + "in": "path", + "description": "thingTypeUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Thing type with provided thingTypeUID does not exist.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThingTypeDTO" + } + } + } + }, + "404": { + "description": "No content" + } + } + } + }, + "/": { + "get": { + "tags": [ + "root" + ], + "summary": "Gets information about the runtime, the API version and links to resources.", + "operationId": "getRoot", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootBean" + } + } + } + } + } + } + }, + "/systeminfo": { + "get": { + "tags": [ + "systeminfo" + ], + "summary": "Gets information about the system.", + "operationId": "getSystemInformation", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SystemInfoBean" + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/systeminfo/uom": { + "get": { + "tags": [ + "systeminfo" + ], + "summary": "Get all supported dimensions and their system units.", + "operationId": "getUoMInformation", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UoMInfoBean" + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/sitemaps/events/subscribe": { + "post": { + "tags": [ + "sitemaps" + ], + "summary": "Creates a sitemap event subscription.", + "operationId": "createSitemapEventSubscription", + "responses": { + "201": { + "description": "Subscription created." + }, + "503": { + "description": "Subscriptions limit reached." + } + } + } + }, + "/sitemaps/{sitemapname}/{pageid}": { + "get": { + "tags": [ + "sitemaps" + ], + "summary": "Polls the data for one page of a sitemap.", + "operationId": "pollDataForPage", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "X-Atmosphere-Transport", + "in": "header", + "description": "X-Atmosphere-Transport for long polling", + "schema": { + "type": "string" + } + }, + { + "name": "sitemapname", + "in": "path", + "description": "sitemap name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "pageid", + "in": "path", + "description": "page id", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "subscriptionid", + "in": "query", + "description": "subscriptionid", + "schema": { + "type": "string" + } + }, + { + "name": "includeHidden", + "in": "query", + "description": "include hidden widgets", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageDTO" + } + } + } + }, + "400": { + "description": "Invalid subscription id has been provided." + }, + "404": { + "description": "Sitemap with requested name does not exist or page does not exist, or page refers to a non-linkable widget" + } + } + } + }, + "/sitemaps/{sitemapname}/*": { + "get": { + "tags": [ + "sitemaps" + ], + "summary": "Polls the data for a whole sitemap. Not recommended due to potentially high traffic.", + "operationId": "pollDataForSitemap", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "sitemapname", + "in": "path", + "description": "sitemap name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "subscriptionid", + "in": "query", + "description": "subscriptionid", + "schema": { + "type": "string" + } + }, + { + "name": "includeHidden", + "in": "query", + "description": "include hidden widgets", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SitemapDTO" + } + } + } + }, + "400": { + "description": "Invalid subscription id has been provided." + }, + "404": { + "description": "Sitemap with requested name does not exist" + } + } + } + }, + "/sitemaps/{sitemapname}": { + "get": { + "tags": [ + "sitemaps" + ], + "summary": "Get sitemap by name.", + "operationId": "getSitemapByName", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "sitemapname", + "in": "path", + "description": "sitemap name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "type", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "jsoncallback", + "in": "query", + "schema": { + "type": "string", + "default": "callback" + } + }, + { + "name": "includeHidden", + "in": "query", + "description": "include hidden widgets", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SitemapDTO" + } + } + } + } + } + } + }, + "/sitemaps/events/{subscriptionid}/*": { + "get": { + "tags": [ + "sitemaps" + ], + "summary": "Get sitemap events for a whole sitemap. Not recommended due to potentially high traffic.", + "operationId": "getSitemapEvents", + "parameters": [ + { + "name": "subscriptionid", + "in": "path", + "description": "subscription id", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9-]+", + "type": "string" + } + }, + { + "name": "sitemap", + "in": "query", + "description": "sitemap name", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Missing sitemap parameter, or sitemap not linked successfully to the subscription." + }, + "404": { + "description": "Subscription not found." + } + } + } + }, + "/sitemaps/events/{subscriptionid}": { + "get": { + "tags": [ + "sitemaps" + ], + "summary": "Get sitemap events.", + "operationId": "getSitemapEvents_1", + "parameters": [ + { + "name": "subscriptionid", + "in": "path", + "description": "subscription id", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9-]+", + "type": "string" + } + }, + { + "name": "sitemap", + "in": "query", + "description": "sitemap name", + "schema": { + "type": "string" + } + }, + { + "name": "pageid", + "in": "query", + "description": "page id", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Missing sitemap or page parameter, or page not linked successfully to the subscription." + }, + "404": { + "description": "Subscription not found." + } + } + } + }, + "/sitemaps": { + "get": { + "tags": [ + "sitemaps" + ], + "summary": "Get all available sitemaps.", + "operationId": "getSitemaps", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SitemapDTO" + } + } + } + } + } + } + } + }, + "/events/states": { + "get": { + "tags": [ + "events" + ], + "summary": "Initiates a new item state tracker connection", + "operationId": "initNewStateTacker", + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/events": { + "get": { + "tags": [ + "events" + ], + "summary": "Get all events.", + "operationId": "getEvents", + "parameters": [ + { + "name": "topics", + "in": "query", + "description": "topics", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Topic is empty or contains invalid characters" + } + } + } + }, + "/events/states/{connectionId}": { + "post": { + "tags": [ + "events" + ], + "summary": "Changes the list of items a SSE connection will receive state updates to.", + "operationId": "updateItemListForStateUpdates", + "parameters": [ + { + "name": "connectionId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "items", + "content": { + "*/*": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Unknown connectionId" + } + } + } + }, + "/transformations/{uid}": { + "get": { + "tags": [ + "transformations" + ], + "summary": "Get a single transformation", + "operationId": "getTransformation", + "parameters": [ + { + "name": "uid", + "in": "path", + "description": "Transformation UID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Transformation" + } + } + } + }, + "404": { + "description": "Not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "transformations" + ], + "summary": "Put a single transformation", + "operationId": "putTransformation", + "parameters": [ + { + "name": "uid", + "in": "path", + "description": "Transformation UID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "transformation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TransformationDTO" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request (content missing or invalid)" + }, + "405": { + "description": "Transformation not editable" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "transformations" + ], + "summary": "Get a single transformation", + "operationId": "deleteTransformation", + "parameters": [ + { + "name": "uid", + "in": "path", + "description": "Transformation UID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "UID not found" + }, + "405": { + "description": "Transformation not editable" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/transformations/services": { + "get": { + "tags": [ + "transformations" + ], + "summary": "Get all transformation services", + "operationId": "getTransformationServices", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/transformations": { + "get": { + "tags": [ + "transformations" + ], + "summary": "Get a list of all transformations", + "operationId": "getTransformations", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TransformationDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/ui/components/{namespace}": { + "get": { + "tags": [ + "ui" + ], + "summary": "Get all registered UI components in the specified namespace.", + "operationId": "getRegisteredUIComponentsInNamespace", + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "summary", + "in": "query", + "description": "summary fields only", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RootUIComponent" + } + } + } + } + } + } + }, + "post": { + "tags": [ + "ui" + ], + "summary": "Add a UI component in the specified namespace.", + "operationId": "addUIComponentToNamespace", + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootUIComponent" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootUIComponent" + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/ui/components/{namespace}/{componentUID}": { + "get": { + "tags": [ + "ui" + ], + "summary": "Get a specific UI component in the specified namespace.", + "operationId": "getUIComponentInNamespace", + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "componentUID", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootUIComponent" + } + } + } + }, + "404": { + "description": "Component not found" + } + } + }, + "put": { + "tags": [ + "ui" + ], + "summary": "Update a specific UI component in the specified namespace.", + "operationId": "updateUIComponentInNamespace", + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "componentUID", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootUIComponent" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootUIComponent" + } + } + } + }, + "404": { + "description": "Component not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "ui" + ], + "summary": "Remove a specific UI component in the specified namespace.", + "operationId": "removeUIComponentFromNamespace", + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "componentUID", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Component not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/ui/tiles": { + "get": { + "tags": [ + "ui" + ], + "summary": "Get all registered UI tiles.", + "operationId": "getUITiles", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TileDTO" + } + } + } + } + } + } + } + }, + "/voice/defaultvoice": { + "get": { + "tags": [ + "voice" + ], + "summary": "Gets the default voice.", + "operationId": "getDefaultVoice", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VoiceDTO" + } + } + } + }, + "404": { + "description": "No default voice was found." + } + } + } + }, + "/voice/interpreters/{id}": { + "get": { + "tags": [ + "voice" + ], + "summary": "Gets a single interpreter.", + "operationId": "getVoiceInterpreterByUID", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "path", + "description": "interpreter id", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HumanLanguageInterpreterDTO" + } + } + } + } + }, + "404": { + "description": "Interpreter not found" + } + } + } + }, + "/voice/interpreters": { + "get": { + "tags": [ + "voice" + ], + "summary": "Get the list of all interpreters.", + "operationId": "getVoiceInterpreters", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HumanLanguageInterpreterDTO" + } + } + } + } + } + } + }, + "post": { + "tags": [ + "voice" + ], + "summary": "Sends a text to the default human language interpreter.", + "operationId": "interpretTextByDefaultInterpreter", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "text to interpret", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "interpretation exception occurs" + }, + "404": { + "description": "No human language interpreter was found." + } + } + } + }, + "/voice/voices": { + "get": { + "tags": [ + "voice" + ], + "summary": "Get the list of all voices.", + "operationId": "getVoices", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/VoiceDTO" + } + } + } + } + } + } + } + }, + "/voice/interpreters/{ids}": { + "post": { + "tags": [ + "voice" + ], + "summary": "Sends a text to a given human language interpreter(s).", + "operationId": "interpretText", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "ids", + "in": "path", + "description": "comma separated list of interpreter ids", + "required": true, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "requestBody": { + "description": "text to interpret", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "interpretation exception occurs" + }, + "404": { + "description": "No human language interpreter was found." + } + } + } + }, + "/voice/listenandanswer": { + "post": { + "tags": [ + "voice" + ], + "summary": "Executes a simple dialog sequence without keyword spotting for a given audio source.", + "operationId": "listenAndAnswer", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "sourceId", + "in": "query", + "description": "source ID", + "schema": { + "type": "string" + } + }, + { + "name": "sttId", + "in": "query", + "description": "Speech-to-Text ID", + "schema": { + "type": "string" + } + }, + { + "name": "ttsId", + "in": "query", + "description": "Text-to-Speech ID", + "schema": { + "type": "string" + } + }, + { + "name": "voiceId", + "in": "query", + "description": "voice ID", + "schema": { + "type": "string" + } + }, + { + "name": "hliIds", + "in": "query", + "description": "interpreter IDs", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "sinkId", + "in": "query", + "description": "audio sink ID", + "schema": { + "type": "string" + } + }, + { + "name": "listeningItem", + "in": "query", + "description": "listening item", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Services are missing or language is not supported by services or dialog processing is already started for the audio source." + }, + "404": { + "description": "One of the given ids is wrong." + } + } + } + }, + "/voice/say": { + "post": { + "tags": [ + "voice" + ], + "summary": "Speaks a given text with a given voice through the given audio sink.", + "operationId": "textToSpeech", + "parameters": [ + { + "name": "voiceid", + "in": "query", + "description": "voice id", + "schema": { + "type": "string" + } + }, + { + "name": "sinkid", + "in": "query", + "description": "audio sink id", + "schema": { + "type": "string" + } + }, + { + "name": "volume", + "in": "query", + "description": "volume level", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "text to speak", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/voice/dialog/start": { + "post": { + "tags": [ + "voice" + ], + "summary": "Start dialog processing for a given audio source.", + "operationId": "startDialog", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "sourceId", + "in": "query", + "description": "source ID", + "schema": { + "type": "string" + } + }, + { + "name": "ksId", + "in": "query", + "description": "keywork spotter ID", + "schema": { + "type": "string" + } + }, + { + "name": "sttId", + "in": "query", + "description": "Speech-to-Text ID", + "schema": { + "type": "string" + } + }, + { + "name": "ttsId", + "in": "query", + "description": "Text-to-Speech ID", + "schema": { + "type": "string" + } + }, + { + "name": "voiceId", + "in": "query", + "description": "voice ID", + "schema": { + "type": "string" + } + }, + { + "name": "hliIds", + "in": "query", + "description": "comma separated list of interpreter IDs", + "schema": { + "type": "string" + } + }, + { + "name": "sinkId", + "in": "query", + "description": "audio sink ID", + "schema": { + "type": "string" + } + }, + { + "name": "keyword", + "in": "query", + "description": "keyword", + "schema": { + "type": "string" + } + }, + { + "name": "listeningItem", + "in": "query", + "description": "listening item", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Services are missing or language is not supported by services or dialog processing is already started for the audio source." + }, + "404": { + "description": "One of the given ids is wrong." + } + } + } + }, + "/voice/dialog/stop": { + "post": { + "tags": [ + "voice" + ], + "summary": "Stop dialog processing for a given audio source.", + "operationId": "stopDialog", + "parameters": [ + { + "name": "sourceId", + "in": "query", + "description": "source ID", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "No dialog processing is started for the audio source." + }, + "404": { + "description": "No audio source was found." + } + } + } + }, + "/logging/{loggerName}": { + "get": { + "tags": [ + "logging" + ], + "summary": "Get a single logger.", + "operationId": "getLogger", + "parameters": [ + { + "name": "loggerName", + "in": "path", + "description": "logger name", + "required": true, + "schema": { + "pattern": "[a-zA-Z0-9.]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LoggerInfo" + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "logging" + ], + "summary": "Modify or add logger", + "operationId": "putLogger", + "parameters": [ + { + "name": "loggerName", + "in": "path", + "description": "logger name", + "required": true, + "schema": { + "pattern": "[a-zA-Z0-9.]+", + "type": "string" + } + } + ], + "requestBody": { + "description": "logger", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LoggerInfo" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Payload is invalid." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "logging" + ], + "summary": "Remove a single logger.", + "operationId": "removeLogger", + "parameters": [ + { + "name": "loggerName", + "in": "path", + "description": "logger name", + "required": true, + "schema": { + "pattern": "[a-zA-Z0-9.]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/logging": { + "get": { + "tags": [ + "logging" + ], + "summary": "Get all loggers", + "operationId": "getLogger_1", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LoggerBean" + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/iconsets": { + "get": { + "tags": [ + "iconsets" + ], + "summary": "Gets all icon sets.", + "operationId": "getIconSets", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IconSet" + } + } + } + } + } + } + } + }, + "/habpanel/gallery/{galleryName}/widgets": { + "get": { + "tags": [ + "habpanel" + ], + "summary": "Gets the list of widget gallery items.", + "operationId": "getGalleryWidgetList", + "parameters": [ + { + "name": "galleryName", + "in": "path", + "description": "gallery name e.g. 'community'", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]*", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GalleryWidgetsListItem" + } + } + } + } + }, + "404": { + "description": "Unknown gallery" + } + } + } + }, + "/habpanel/gallery/{galleryName}/widgets/{id}": { + "get": { + "tags": [ + "habpanel" + ], + "summary": "Gets the details about a widget gallery item.", + "operationId": "getGalleryWidgetsItem", + "parameters": [ + { + "name": "galleryName", + "in": "path", + "description": "gallery name e.g. 'community'", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]*", + "type": "string" + } + }, + { + "name": "id", + "in": "path", + "description": "id within the gallery", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]*", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GalleryItem" + } + } + } + }, + "404": { + "description": "Unknown gallery or gallery item not found" + } + } + } + } + }, + "components": { + "schemas": { + "ConfigDescriptionParameterDTO": { + "type": "object", + "properties": { + "context": { + "type": "string" + }, + "defaultValue": { + "type": "string" + }, + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "required": { + "type": "boolean" + }, + "type": { + "type": "string", + "enum": [ + "TEXT", + "INTEGER", + "DECIMAL", + "BOOLEAN" + ] + }, + "min": { + "type": "number" + }, + "max": { + "type": "number" + }, + "stepsize": { + "type": "number" + }, + "pattern": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + }, + "multiple": { + "type": "boolean" + }, + "multipleLimit": { + "type": "integer", + "format": "int32" + }, + "groupName": { + "type": "string" + }, + "advanced": { + "type": "boolean" + }, + "verify": { + "type": "boolean" + }, + "limitToOptions": { + "type": "boolean" + }, + "unit": { + "type": "string" + }, + "unitLabel": { + "type": "string" + }, + "options": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ParameterOptionDTO" + } + }, + "filterCriteria": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FilterCriteriaDTO" + } + } + } + }, + "FilterCriteriaDTO": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "ModuleTypeDTO": { + "type": "object", + "properties": { + "uid": { + "type": "string" + }, + "visibility": { + "type": "string", + "enum": [ + "VISIBLE", + "HIDDEN", + "EXPERT" + ] + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "configDescriptions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameterDTO" + } + } + } + }, + "ParameterOptionDTO": { + "type": "object", + "properties": { + "label": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "ActionDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "type": { + "type": "string" + }, + "inputs": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "ConditionDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "type": { + "type": "string" + }, + "inputs": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "RuleDTO": { + "type": "object", + "properties": { + "triggers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TriggerDTO" + } + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConditionDTO" + } + }, + "actions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ActionDTO" + } + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "configDescriptions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameterDTO" + } + }, + "templateUID": { + "type": "string" + }, + "uid": { + "type": "string" + }, + "name": { + "type": "string" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "visibility": { + "type": "string", + "enum": [ + "VISIBLE", + "HIDDEN", + "EXPERT" + ] + }, + "description": { + "type": "string" + } + } + }, + "TriggerDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "type": { + "type": "string" + } + } + }, + "EnrichedRuleDTO": { + "type": "object", + "properties": { + "triggers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TriggerDTO" + } + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConditionDTO" + } + }, + "actions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ActionDTO" + } + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "configDescriptions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameterDTO" + } + }, + "templateUID": { + "type": "string" + }, + "uid": { + "type": "string" + }, + "name": { + "type": "string" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "visibility": { + "type": "string", + "enum": [ + "VISIBLE", + "HIDDEN", + "EXPERT" + ] + }, + "description": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/RuleStatusInfo" + }, + "editable": { + "type": "boolean" + } + } + }, + "RuleStatusInfo": { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "UNINITIALIZED", + "INITIALIZING", + "IDLE", + "RUNNING" + ] + }, + "statusDetail": { + "type": "string", + "enum": [ + "NONE", + "HANDLER_MISSING_ERROR", + "HANDLER_INITIALIZING_ERROR", + "CONFIGURATION_ERROR", + "TEMPLATE_MISSING_ERROR", + "INVALID_RULE", + "DISABLED" + ] + }, + "description": { + "type": "string" + } + } + }, + "ModuleDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "type": { + "type": "string" + } + } + }, + "Action": { + "type": "object", + "properties": { + "inputs": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "typeUID": { + "type": "string" + }, + "configuration": { + "$ref": "#/components/schemas/Configuration" + }, + "id": { + "type": "string" + } + } + }, + "Condition": { + "type": "object", + "properties": { + "inputs": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "typeUID": { + "type": "string" + }, + "configuration": { + "$ref": "#/components/schemas/Configuration" + }, + "id": { + "type": "string" + } + } + }, + "ConfigDescriptionParameter": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "TEXT", + "INTEGER", + "DECIMAL", + "BOOLEAN" + ] + }, + "groupName": { + "type": "string" + }, + "pattern": { + "type": "string" + }, + "required": { + "type": "boolean" + }, + "readOnly": { + "type": "boolean" + }, + "multiple": { + "type": "boolean" + }, + "multipleLimit": { + "type": "integer", + "format": "int32" + }, + "unit": { + "type": "string" + }, + "unitLabel": { + "type": "string" + }, + "context": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "options": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ParameterOption" + } + }, + "filterCriteria": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FilterCriteria" + } + }, + "limitToOptions": { + "type": "boolean" + }, + "advanced": { + "type": "boolean" + }, + "minimum": { + "type": "number" + }, + "maximum": { + "type": "number" + }, + "stepSize": { + "type": "number" + }, + "verifyable": { + "type": "boolean" + }, + "default": { + "type": "string" + } + } + }, + "Configuration": { + "type": "object", + "properties": { + "properties": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + }, + "FilterCriteria": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "Module": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "typeUID": { + "type": "string" + }, + "configuration": { + "$ref": "#/components/schemas/Configuration" + }, + "id": { + "type": "string" + } + } + }, + "ParameterOption": { + "type": "object", + "properties": { + "label": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "Rule": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "visibility": { + "type": "string", + "enum": [ + "VISIBLE", + "HIDDEN", + "EXPERT" + ] + }, + "configurationDescriptions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameter" + } + }, + "templateUID": { + "type": "string" + }, + "triggers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Trigger" + } + }, + "uid": { + "type": "string" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "configuration": { + "$ref": "#/components/schemas/Configuration" + }, + "modules": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Module" + } + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Condition" + } + }, + "name": { + "type": "string" + }, + "actions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Action" + } + } + } + }, + "RuleExecution": { + "type": "object", + "properties": { + "date": { + "type": "string", + "format": "date-time" + }, + "rule": { + "$ref": "#/components/schemas/Rule" + } + } + }, + "Trigger": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "typeUID": { + "type": "string" + }, + "configuration": { + "$ref": "#/components/schemas/Configuration" + }, + "id": { + "type": "string" + } + } + }, + "Template": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "visibility": { + "type": "string", + "enum": [ + "VISIBLE", + "HIDDEN", + "EXPERT" + ] + }, + "uid": { + "type": "string" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "Input": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "required": { + "type": "boolean" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "reference": { + "type": "string" + }, + "defaultValue": { + "type": "string" + } + } + }, + "Output": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "reference": { + "type": "string" + }, + "defaultValue": { + "type": "string" + } + } + }, + "ThingActionDTO": { + "type": "object", + "properties": { + "actionUid": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "inputs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Input" + } + }, + "outputs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Output" + } + } + } + }, + "AudioSinkDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + } + } + }, + "AudioSourceDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + } + } + }, + "UserApiTokenDTO": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "createdTime": { + "type": "string", + "format": "date-time" + }, + "scope": { + "type": "string" + } + } + }, + "UserSessionDTO": { + "type": "object", + "properties": { + "sessionId": { + "type": "string" + }, + "createdTime": { + "type": "string", + "format": "date-time" + }, + "lastRefreshTime": { + "type": "string", + "format": "date-time" + }, + "clientId": { + "type": "string" + }, + "scope": { + "type": "string" + } + } + }, + "TokenResponseDTO": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "expires_in": { + "type": "integer", + "format": "int32" + }, + "refresh_token": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "user": { + "$ref": "#/components/schemas/UserDTO" + } + } + }, + "UserDTO": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "Addon": { + "type": "object", + "properties": { + "uid": { + "type": "string" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "version": { + "type": "string" + }, + "maturity": { + "type": "string" + }, + "compatible": { + "type": "boolean" + }, + "contentType": { + "type": "string" + }, + "link": { + "type": "string" + }, + "author": { + "type": "string" + }, + "verifiedAuthor": { + "type": "boolean" + }, + "installed": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "description": { + "type": "string" + }, + "detailedDescription": { + "type": "string" + }, + "configDescriptionURI": { + "type": "string" + }, + "keywords": { + "type": "string" + }, + "countries": { + "type": "array", + "items": { + "type": "string" + } + }, + "license": { + "type": "string" + }, + "connection": { + "type": "string" + }, + "backgroundColor": { + "type": "string" + }, + "imageLink": { + "type": "string" + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "loggerPackages": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "AddonType": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + } + } + }, + "ChannelTypeDTO": { + "type": "object", + "properties": { + "parameters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameterDTO" + } + }, + "parameterGroups": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameterGroupDTO" + } + }, + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "category": { + "type": "string" + }, + "itemType": { + "type": "string" + }, + "unitHint": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "stateDescription": { + "$ref": "#/components/schemas/StateDescription" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "UID": { + "type": "string" + }, + "advanced": { + "type": "boolean" + }, + "commandDescription": { + "$ref": "#/components/schemas/CommandDescription" + } + } + }, + "CommandDescription": { + "type": "object", + "properties": { + "commandOptions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CommandOption" + } + } + } + }, + "CommandOption": { + "type": "object", + "properties": { + "command": { + "type": "string" + }, + "label": { + "type": "string" + } + } + }, + "ConfigDescriptionParameterGroupDTO": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "context": { + "type": "string" + }, + "advanced": { + "type": "boolean" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + } + } + }, + "StateDescription": { + "type": "object", + "properties": { + "minimum": { + "type": "number" + }, + "maximum": { + "type": "number" + }, + "step": { + "type": "number" + }, + "pattern": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + }, + "options": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StateOption" + } + } + } + }, + "StateOption": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + } + }, + "ConfigDescriptionDTO": { + "type": "object", + "properties": { + "uri": { + "type": "string" + }, + "parameters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameterDTO" + } + }, + "parameterGroups": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameterGroupDTO" + } + } + } + }, + "DiscoveryResultDTO": { + "type": "object", + "properties": { + "bridgeUID": { + "type": "string" + }, + "flag": { + "type": "string", + "enum": [ + "NEW", + "IGNORED" + ] + }, + "label": { + "type": "string" + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "representationProperty": { + "type": "string" + }, + "thingUID": { + "type": "string" + }, + "thingTypeUID": { + "type": "string" + } + } + }, + "MetadataDTO": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "config": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + }, + "EnrichedItemDTO": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "label": { + "type": "string" + }, + "category": { + "type": "string" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "groupNames": { + "type": "array", + "items": { + "type": "string" + } + }, + "link": { + "type": "string" + }, + "state": { + "type": "string" + }, + "transformedState": { + "type": "string" + }, + "stateDescription": { + "$ref": "#/components/schemas/StateDescription" + }, + "unitSymbol": { + "type": "string" + }, + "commandDescription": { + "$ref": "#/components/schemas/CommandDescription" + }, + "metadata": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "editable": { + "type": "boolean" + } + } + }, + "GroupFunctionDTO": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "params": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "GroupItemDTO": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "label": { + "type": "string" + }, + "category": { + "type": "string" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "groupNames": { + "type": "array", + "items": { + "type": "string" + } + }, + "groupType": { + "type": "string" + }, + "function": { + "$ref": "#/components/schemas/GroupFunctionDTO" + } + } + }, + "EnrichedItemChannelLinkDTO": { + "type": "object", + "properties": { + "itemName": { + "type": "string" + }, + "channelUID": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "editable": { + "type": "boolean" + } + } + }, + "ItemChannelLinkDTO": { + "type": "object", + "properties": { + "itemName": { + "type": "string" + }, + "channelUID": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + }, + "HistoryDataBean": { + "type": "object", + "properties": { + "time": { + "type": "integer", + "format": "int64" + }, + "state": { + "type": "string" + } + } + }, + "ItemHistoryDTO": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "totalrecords": { + "type": "string" + }, + "datapoints": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HistoryDataBean" + } + } + } + }, + "PersistenceCronStrategyDTO": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "cronExpression": { + "type": "string" + } + } + }, + "PersistenceFilterDTO": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "number" + }, + "relative": { + "type": "boolean" + }, + "unit": { + "type": "string" + }, + "lower": { + "type": "number" + }, + "upper": { + "type": "number" + }, + "values": { + "type": "array", + "items": { + "type": "string" + } + }, + "inverted": { + "type": "boolean" + } + } + }, + "PersistenceItemConfigurationDTO": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "string" + } + }, + "strategies": { + "type": "array", + "items": { + "type": "string" + } + }, + "filters": { + "type": "array", + "items": { + "type": "string" + } + }, + "alias": { + "type": "string" + } + } + }, + "PersistenceServiceConfigurationDTO": { + "type": "object", + "properties": { + "serviceId": { + "type": "string" + }, + "configs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistenceItemConfigurationDTO" + } + }, + "defaults": { + "type": "array", + "items": { + "type": "string" + } + }, + "cronStrategies": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistenceCronStrategyDTO" + } + }, + "thresholdFilters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistenceFilterDTO" + } + }, + "timeFilters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistenceFilterDTO" + } + }, + "equalsFilters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistenceFilterDTO" + } + }, + "includeFilters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistenceFilterDTO" + } + }, + "editable": { + "type": "boolean" + } + } + }, + "PersistenceItemInfo": { + "type": "object", + "properties": { + "earliest": { + "type": "string", + "format": "date-time" + }, + "latest": { + "type": "string", + "format": "date-time" + }, + "name": { + "type": "string" + }, + "count": { + "type": "integer", + "format": "int32" + } + } + }, + "PersistenceServiceDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "ProfileTypeDTO": { + "type": "object", + "properties": { + "uid": { + "type": "string" + }, + "label": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "supportedItemTypes": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "ConfigurableServiceDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "category": { + "type": "string" + }, + "configDescriptionURI": { + "type": "string" + }, + "multiple": { + "type": "boolean" + } + } + }, + "EnrichedSemanticTagDTO": { + "type": "object" + }, + "EnrichedChannelDTO": { + "type": "object", + "properties": { + "uid": { + "type": "string" + }, + "id": { + "type": "string" + }, + "channelTypeUID": { + "type": "string" + }, + "itemType": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "defaultTags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "autoUpdatePolicy": { + "type": "string" + }, + "linkedItems": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "EnrichedThingDTO": { + "type": "object", + "properties": { + "label": { + "type": "string" + }, + "bridgeUID": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "UID": { + "type": "string" + }, + "thingTypeUID": { + "type": "string" + }, + "location": { + "type": "string" + }, + "channels": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EnrichedChannelDTO" + } + }, + "statusInfo": { + "$ref": "#/components/schemas/ThingStatusInfo" + }, + "firmwareStatus": { + "$ref": "#/components/schemas/FirmwareStatusDTO" + }, + "editable": { + "type": "boolean" + } + } + }, + "FirmwareStatusDTO": { + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "updatableVersion": { + "type": "string" + } + } + }, + "ThingStatusInfo": { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "UNINITIALIZED", + "INITIALIZING", + "UNKNOWN", + "ONLINE", + "OFFLINE", + "REMOVING", + "REMOVED" + ] + }, + "statusDetail": { + "type": "string", + "enum": [ + "NONE", + "NOT_YET_READY", + "HANDLER_MISSING_ERROR", + "HANDLER_REGISTERING_ERROR", + "HANDLER_INITIALIZING_ERROR", + "HANDLER_CONFIGURATION_PENDING", + "CONFIGURATION_PENDING", + "COMMUNICATION_ERROR", + "CONFIGURATION_ERROR", + "BRIDGE_OFFLINE", + "FIRMWARE_UPDATING", + "DUTY_CYCLE", + "BRIDGE_UNINITIALIZED", + "GONE", + "DISABLED" + ] + }, + "description": { + "type": "string" + } + } + }, + "ChannelDTO": { + "type": "object", + "properties": { + "uid": { + "type": "string" + }, + "id": { + "type": "string" + }, + "channelTypeUID": { + "type": "string" + }, + "itemType": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "defaultTags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "autoUpdatePolicy": { + "type": "string" + } + } + }, + "ThingDTO": { + "type": "object", + "properties": { + "label": { + "type": "string" + }, + "bridgeUID": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "UID": { + "type": "string" + }, + "thingTypeUID": { + "type": "string" + }, + "location": { + "type": "string" + }, + "channels": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ChannelDTO" + } + } + } + }, + "ConfigStatusMessage": { + "type": "object", + "properties": { + "parameterName": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "INFORMATION", + "WARNING", + "ERROR", + "PENDING" + ] + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "integer", + "format": "int32" + } + } + }, + "FirmwareDTO": { + "type": "object", + "properties": { + "thingTypeUID": { + "type": "string" + }, + "vendor": { + "type": "string" + }, + "model": { + "type": "string" + }, + "modelRestricted": { + "type": "boolean" + }, + "description": { + "type": "string" + }, + "version": { + "type": "string" + }, + "changelog": { + "type": "string" + }, + "prerequisiteVersion": { + "type": "string" + } + } + }, + "StrippedThingTypeDTO": { + "type": "object", + "properties": { + "UID": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "category": { + "type": "string" + }, + "listed": { + "type": "boolean" + }, + "supportedBridgeTypeUIDs": { + "type": "array", + "items": { + "type": "string" + } + }, + "bridge": { + "type": "boolean" + } + } + }, + "ChannelDefinitionDTO": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "category": { + "type": "string" + }, + "stateDescription": { + "$ref": "#/components/schemas/StateDescription" + }, + "advanced": { + "type": "boolean" + }, + "typeUID": { + "type": "string" + } + } + }, + "ChannelGroupDefinitionDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "channels": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ChannelDefinitionDTO" + } + } + } + }, + "ThingTypeDTO": { + "type": "object", + "properties": { + "UID": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "category": { + "type": "string" + }, + "listed": { + "type": "boolean" + }, + "supportedBridgeTypeUIDs": { + "type": "array", + "items": { + "type": "string" + } + }, + "bridge": { + "type": "boolean" + }, + "channels": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ChannelDefinitionDTO" + } + }, + "channelGroups": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ChannelGroupDefinitionDTO" + } + }, + "configParameters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameterDTO" + } + }, + "parameterGroups": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameterGroupDTO" + } + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "extensibleChannelTypeIds": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "Links": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, + "RootBean": { + "type": "object", + "properties": { + "version": { + "type": "string" + }, + "locale": { + "type": "string" + }, + "measurementSystem": { + "type": "string" + }, + "runtimeInfo": { + "$ref": "#/components/schemas/RuntimeInfo" + }, + "links": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Links" + } + } + } + }, + "RuntimeInfo": { + "type": "object", + "properties": { + "version": { + "type": "string" + }, + "buildString": { + "type": "string" + } + } + }, + "SystemInfo": { + "type": "object", + "properties": { + "configFolder": { + "type": "string" + }, + "userdataFolder": { + "type": "string" + }, + "logFolder": { + "type": "string" + }, + "javaVersion": { + "type": "string" + }, + "javaVendor": { + "type": "string" + }, + "javaVendorVersion": { + "type": "string" + }, + "osName": { + "type": "string" + }, + "osVersion": { + "type": "string" + }, + "osArchitecture": { + "type": "string" + }, + "availableProcessors": { + "type": "integer", + "format": "int32" + }, + "freeMemory": { + "type": "integer", + "format": "int64" + }, + "totalMemory": { + "type": "integer", + "format": "int64" + }, + "uptime": { + "type": "integer", + "format": "int64" + }, + "startLevel": { + "type": "integer", + "format": "int32" + } + } + }, + "SystemInfoBean": { + "type": "object", + "properties": { + "systemInfo": { + "$ref": "#/components/schemas/SystemInfo" + } + } + }, + "DimensionInfo": { + "type": "object", + "properties": { + "dimension": { + "type": "string" + }, + "systemUnit": { + "type": "string" + } + } + }, + "UoMInfo": { + "type": "object", + "properties": { + "dimensions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DimensionInfo" + } + } + } + }, + "UoMInfoBean": { + "type": "object", + "properties": { + "uomInfo": { + "$ref": "#/components/schemas/UoMInfo" + } + } + }, + "MappingDTO": { + "type": "object", + "properties": { + "row": { + "type": "integer", + "format": "int32" + }, + "column": { + "type": "integer", + "format": "int32" + }, + "command": { + "type": "string" + }, + "releaseCommand": { + "type": "string" + }, + "label": { + "type": "string" + }, + "icon": { + "type": "string" + } + } + }, + "PageDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "link": { + "type": "string" + }, + "parent": { + "$ref": "#/components/schemas/PageDTO" + }, + "leaf": { + "type": "boolean" + }, + "timeout": { + "type": "boolean" + }, + "widgets": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WidgetDTO" + } + } + } + }, + "WidgetDTO": { + "type": "object", + "properties": { + "widgetId": { + "type": "string" + }, + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "visibility": { + "type": "boolean" + }, + "label": { + "type": "string" + }, + "labelSource": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "staticIcon": { + "type": "boolean" + }, + "labelcolor": { + "type": "string" + }, + "valuecolor": { + "type": "string" + }, + "iconcolor": { + "type": "string" + }, + "pattern": { + "type": "string" + }, + "unit": { + "type": "string" + }, + "mappings": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MappingDTO" + } + }, + "switchSupport": { + "type": "boolean" + }, + "releaseOnly": { + "type": "boolean" + }, + "sendFrequency": { + "type": "integer", + "format": "int32" + }, + "refresh": { + "type": "integer", + "format": "int32" + }, + "height": { + "type": "integer", + "format": "int32" + }, + "minValue": { + "type": "number" + }, + "maxValue": { + "type": "number" + }, + "step": { + "type": "number" + }, + "inputHint": { + "type": "string" + }, + "url": { + "type": "string" + }, + "encoding": { + "type": "string" + }, + "service": { + "type": "string" + }, + "period": { + "type": "string" + }, + "yAxisDecimalPattern": { + "type": "string" + }, + "legend": { + "type": "boolean" + }, + "forceAsItem": { + "type": "boolean" + }, + "row": { + "type": "integer", + "format": "int32" + }, + "column": { + "type": "integer", + "format": "int32" + }, + "command": { + "type": "string" + }, + "releaseCommand": { + "type": "string" + }, + "stateless": { + "type": "boolean" + }, + "state": { + "type": "string" + }, + "item": { + "$ref": "#/components/schemas/EnrichedItemDTO" + }, + "linkedPage": { + "$ref": "#/components/schemas/PageDTO" + }, + "widgets": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WidgetDTO" + } + } + } + }, + "SitemapDTO": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "label": { + "type": "string" + }, + "link": { + "type": "string" + }, + "homepage": { + "$ref": "#/components/schemas/PageDTO" + } + } + }, + "Transformation": { + "type": "object", + "properties": { + "uid": { + "type": "string" + }, + "label": { + "type": "string" + }, + "type": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "TransformationDTO": { + "type": "object", + "properties": { + "uid": { + "type": "string" + }, + "label": { + "type": "string" + }, + "type": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "editable": { + "type": "boolean" + } + } + }, + "RootUIComponent": { + "type": "object", + "properties": { + "component": { + "type": "string" + }, + "config": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "slots": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UIComponent" + } + } + }, + "uid": { + "type": "string" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "props": { + "$ref": "#/components/schemas/ConfigDescriptionDTO" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "type": { + "type": "string" + } + } + }, + "UIComponent": { + "type": "object", + "properties": { + "component": { + "type": "string" + }, + "config": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "type": { + "type": "string" + } + } + }, + "TileDTO": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "url": { + "type": "string" + }, + "overlay": { + "type": "string" + }, + "imageUrl": { + "type": "string" + } + } + }, + "VoiceDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "locale": { + "type": "string" + } + } + }, + "HumanLanguageInterpreterDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "locales": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "LoggerInfo": { + "type": "object", + "properties": { + "loggerName": { + "type": "string" + }, + "level": { + "type": "string" + } + } + }, + "LoggerBean": { + "type": "object", + "properties": { + "loggers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/LoggerInfo" + } + } + } + }, + "IconSet": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "formats": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string", + "enum": [ + "PNG", + "SVG" + ] + } + } + } + }, + "GalleryWidgetsListItem": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "likes": { + "type": "integer", + "format": "int32" + }, + "views": { + "type": "integer", + "format": "int32" + }, + "posts": { + "type": "integer", + "format": "int32" + }, + "imageUrl": { + "type": "string" + }, + "createdDate": { + "type": "string", + "format": "date-time" + } + } + }, + "GalleryItem": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "likes": { + "type": "integer", + "format": "int32" + }, + "views": { + "type": "integer", + "format": "int32" + }, + "posts": { + "type": "integer", + "format": "int32" + }, + "imageUrl": { + "type": "string" + }, + "author": { + "type": "string" + }, + "authorName": { + "type": "string" + }, + "authorAvatarUrl": { + "type": "string" + }, + "createdDate": { + "type": "string", + "format": "date-time" + }, + "updatedDate": { + "type": "string", + "format": "date-time" + }, + "readme": { + "type": "string" + } + } + } + }, + "securitySchemes": { + "oauth2": { + "type": "oauth2", + "flows": { + "authorizationCode": { + "authorizationUrl": "/auth/authorize", + "tokenUrl": "/rest/auth/token", + "scopes": { + "admin": "Administration operations" + } + } + } + } + } + } +} diff --git a/OpenHABCore/Tests/OpenHABCoreTests/JSONParserTests.swift b/OpenHABCore/Tests/OpenHABCoreTests/JSONParserTests.swift index 29a423fb..dca4e4b7 100644 --- a/OpenHABCore/Tests/OpenHABCoreTests/JSONParserTests.swift +++ b/OpenHABCore/Tests/OpenHABCoreTests/JSONParserTests.swift @@ -146,7 +146,7 @@ final class JSONParserTests: XCTestCase { """ let data = Data(json.utf8) do { - let codingData = try decoder.decode(OpenHABSitemapPage.CodingData.self, from: data) + let codingData = try decoder.decode(OpenHABPage.CodingData.self, from: data) let decoded = codingData.openHABSitemapPage XCTAssertEqual(decoded.pageId, "1302", "LinkedPage properly parsed") } catch { @@ -255,7 +255,7 @@ final class JSONParserTests: XCTestCase { } """.data(using: .utf8)! do { - let sitemapPageCodingData = try decoder.decode(OpenHABSitemapPage.CodingData.self, from: json) + let sitemapPageCodingData = try decoder.decode(OpenHABPage.CodingData.self, from: json) let sitemapPage = sitemapPageCodingData.openHABSitemapPage XCTAssertEqual(sitemapPage.pageId, "1304", "OpenHABLinkedPage properly parsed") } catch { @@ -357,7 +357,7 @@ final class JSONParserTests: XCTestCase { func testJSONSitemapPage() { do { - let codingData = try decoder.decode(OpenHABSitemapPage.CodingData.self, from: jsonSitemap) + let codingData = try decoder.decode(OpenHABPage.CodingData.self, from: jsonSitemap) XCTAssertEqual(codingData.leaf, false, "OpenHABSitemapPage properly parsed") XCTAssertEqual(codingData.widgets?[0].widgetId, "00", "widget properly parsed") } catch { @@ -367,7 +367,7 @@ final class JSONParserTests: XCTestCase { func testJSONSitemapPage2() { do { - let codingData = try decoder.decode(OpenHABSitemapPage.CodingData.self, from: jsonSitemap2) + let codingData = try decoder.decode(OpenHABPage.CodingData.self, from: jsonSitemap2) XCTAssertEqual(codingData.leaf, false, "OpenHABSitemapPage properly parsed") XCTAssertEqual(codingData.widgets?[0].widgetId, "00", "widget properly parsed") XCTAssertEqual(codingData.widgets?[4].widgets[3].item?.stateDescription?.options?[0].label, "New moon", "State description properly parsed") @@ -385,7 +385,7 @@ final class JSONParserTests: XCTestCase { """.data(using: .utf8)! do { let codingData = try decoder.decode(OpenHABSitemap.CodingData.self, from: json) - XCTAssertEqual(codingData.page.link, "https://192.168.2.15:8444/rest/sitemaps/watch/watch", "OpenHABSitemapPage properly parsed") + XCTAssertEqual(codingData.page?.link, "https://192.168.2.15:8444/rest/sitemaps/watch/watch", "OpenHABSitemapPage properly parsed") // XCTAssert(codingData.openHABSitemapPage. widgets[0].type == "Frame", "") // XCTAssert(.widgets[0].linkedPage?.pageId == "0000", "widget properly parsed") } catch { @@ -433,7 +433,7 @@ final class JSONParserTests: XCTestCase { """ let data = Data(jsonInputForGroup.utf8) do { - let codingData = try decoder.decode(OpenHABSitemapPage.CodingData.self, from: data) + let codingData = try decoder.decode(OpenHABPage.CodingData.self, from: data) let widget = codingData.widgets?[0] XCTAssert(widget?.item?.type == "Group" && widget?.item?.groupType == "Rollershutter", "") XCTAssertEqual(codingData.widgets?[0].item?.groupType, "Rollershutter") @@ -490,11 +490,11 @@ final class JSONParserTests: XCTestCase { "End" ) - let widgets: [OpenHABWidget.CodingData] = try XCTUnwrap(codingData.page.widgets) + let widgets: [OpenHABWidget.CodingData] = try XCTUnwrap(codingData.page?.widgets) let widget = widgets[0] XCTAssertEqual(widget.label, "Flat Scenes") XCTAssertEqual(widget.widgets[0].label, "Scenes") - XCTAssertEqual(codingData.page.link, "https://192.168.0.9:8443/rest/sitemaps/default/default") + XCTAssertEqual(codingData.page?.link, "https://192.168.0.9:8443/rest/sitemaps/default/default") let widget2 = widgets[10] XCTAssertEqual(widget2.widgets[0].label, "Admin Items") } diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 4cb5a094..19974b6d 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -119,6 +119,8 @@ DAC9AF4924F966FA006DAE93 /* LazyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC9AF4824F966FA006DAE93 /* LazyView.swift */; }; DACB636227D3FC6500041931 /* error.png in Resources */ = {isa = PBXBuildFile; fileRef = DACB636127D3FC6500041931 /* error.png */; }; DACB636327D3FC6500041931 /* error.png in Resources */ = {isa = PBXBuildFile; fileRef = DACB636127D3FC6500041931 /* error.png */; }; + DACE664A2C63B0760069E514 /* OpenAPIURLSession in Frameworks */ = {isa = PBXBuildFile; productRef = DACE66492C63B0760069E514 /* OpenAPIURLSession */; }; + DACE664D2C63B0840069E514 /* OpenAPIRuntime in Frameworks */ = {isa = PBXBuildFile; productRef = DACE664C2C63B0840069E514 /* OpenAPIRuntime */; }; DAEAA89B21E2611000267EA3 /* OpenHABNotificationsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAEAA89A21E2611000267EA3 /* OpenHABNotificationsViewController.swift */; }; DAEAA89D21E6B06400267EA3 /* ReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAEAA89C21E6B06300267EA3 /* ReusableView.swift */; }; DAEAA89F21E6B16600267EA3 /* UITableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAEAA89E21E6B16600267EA3 /* UITableView.swift */; }; @@ -435,6 +437,7 @@ DAF4581723DC4A050018B495 /* ImageRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageRow.swift; sourceTree = ""; }; DAF4581D23DC60020018B495 /* ImageRawRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageRawRow.swift; sourceTree = ""; }; DAF4F6BF222734D200C24876 /* NewImageUITableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewImageUITableViewCell.swift; sourceTree = ""; }; + DAF6F4112C67E83B0083883E /* openapiCorrected.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = openapiCorrected.json; sourceTree = ""; }; DF05EF111D00696200DD646D /* DrawerUITableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DrawerUITableViewCell.swift; sourceTree = ""; }; DF05FF1F18965B5400FF2F9B /* RollershutterUITableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RollershutterUITableViewCell.swift; sourceTree = ""; }; DF05FF221896BD2D00FF2F9B /* SelectionUITableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectionUITableViewCell.swift; sourceTree = ""; }; @@ -525,10 +528,12 @@ DFB2622B18830A3600D3244D /* Foundation.framework in Frameworks */, 937E4485270B379900A98C26 /* DeviceKit in Frameworks */, DFB2622F18830A3600D3244D /* UIKit.framework in Frameworks */, + DACE664A2C63B0760069E514 /* OpenAPIURLSession in Frameworks */, 93F8064A27AE7A2E0035A6B0 /* FlexColorPicker in Frameworks */, 93F8063227AE6B940035A6B0 /* AlamofireNetworkActivityIndicator in Frameworks */, 93F8065327AE7B580035A6B0 /* SVGKit in Frameworks */, DA28C362225241DE00AB409C /* WebKit.framework in Frameworks */, + DACE664D2C63B0840069E514 /* OpenAPIRuntime in Frameworks */, 93F8061B27AE615D0035A6B0 /* Alamofire in Frameworks */, 93F8065027AE7A830035A6B0 /* SideMenu in Frameworks */, DFE10414197415F900D94943 /* Security.framework in Frameworks */, @@ -772,6 +777,15 @@ path = Views; sourceTree = ""; }; + DACE66522C63B2070069E514 /* openapitest */ = { + isa = PBXGroup; + children = ( + DAF6F4112C67E83B0083883E /* openapiCorrected.json */, + ); + name = openapitest; + path = openapi/openapitest; + sourceTree = ""; + }; DAE238252806E5C800196467 /* Recovered References */ = { isa = PBXGroup; children = ( @@ -952,6 +966,7 @@ DFB2623018830A3600D3244D /* openHAB */ = { isa = PBXGroup; children = ( + DACE66522C63B2070069E514 /* openapitest */, 938BF9C324EFCB9F00E6B52F /* Main.storyboard */, A3F4C3A41A49A5940019A09F /* MainLaunchScreen.xib */, DFB2623A18830A3600D3244D /* AppDelegate.swift */, @@ -1150,6 +1165,8 @@ 93F8064F27AE7A830035A6B0 /* SideMenu */, 93F8065227AE7B580035A6B0 /* SVGKit */, 6557AF912C039D140094D0C8 /* FirebaseMessaging */, + DACE66492C63B0760069E514 /* OpenAPIURLSession */, + DACE664C2C63B0840069E514 /* OpenAPIRuntime */, ); productName = openHAB; productReference = DFB2622718830A3600D3244D /* openHAB.app */; @@ -1236,6 +1253,8 @@ 93F8064B27AE7A4D0035A6B0 /* XCRemoteSwiftPackageReference "DynamicButton" */, 93F8064E27AE7A820035A6B0 /* XCRemoteSwiftPackageReference "SideMenu" */, 93F8065127AE7B580035A6B0 /* XCRemoteSwiftPackageReference "SVGKit" */, + DACE66482C63B0760069E514 /* XCRemoteSwiftPackageReference "swift-openapi-urlsession" */, + DACE664B2C63B0840069E514 /* XCRemoteSwiftPackageReference "swift-openapi-runtime" */, ); productRefGroup = DFB2622818830A3600D3244D /* Products */; projectDirPath = ""; @@ -1909,7 +1928,7 @@ SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 4; VERSIONING_SYSTEM = "apple-generic"; - WATCHOS_DEPLOYMENT_TARGET = 7.0; + WATCHOS_DEPLOYMENT_TARGET = 10.0; }; name = Debug; }; @@ -1956,7 +1975,7 @@ SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 4; VERSIONING_SYSTEM = "apple-generic"; - WATCHOS_DEPLOYMENT_TARGET = 7.0; + WATCHOS_DEPLOYMENT_TARGET = 10.0; }; name = Release; }; @@ -2404,6 +2423,22 @@ kind = branch; }; }; + DACE66482C63B0760069E514 /* XCRemoteSwiftPackageReference "swift-openapi-urlsession" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/apple/swift-openapi-urlsession"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.0.2; + }; + }; + DACE664B2C63B0840069E514 /* XCRemoteSwiftPackageReference "swift-openapi-runtime" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/apple/swift-openapi-runtime"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.5.0; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -2517,6 +2552,16 @@ package = 93F8065127AE7B580035A6B0 /* XCRemoteSwiftPackageReference "SVGKit" */; productName = SVGKit; }; + DACE66492C63B0760069E514 /* OpenAPIURLSession */ = { + isa = XCSwiftPackageProductDependency; + package = DACE66482C63B0760069E514 /* XCRemoteSwiftPackageReference "swift-openapi-urlsession" */; + productName = OpenAPIURLSession; + }; + DACE664C2C63B0840069E514 /* OpenAPIRuntime */ = { + isa = XCSwiftPackageProductDependency; + package = DACE664B2C63B0840069E514 /* XCRemoteSwiftPackageReference "swift-openapi-runtime" */; + productName = OpenAPIRuntime; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = DFB2621F18830A3600D3244D /* Project object */; diff --git a/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved b/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved index 08b6dad7..9636f6eb 100644 --- a/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,223 +1,257 @@ { - "object": { - "pins": [ - { - "package": "abseil", - "repositoryURL": "https://github.com/google/abseil-cpp-binary.git", - "state": { - "branch": null, - "revision": "748c7837511d0e6a507737353af268484e1745e2", - "version": "1.2024011601.1" - } - }, - { - "package": "Alamofire", - "repositoryURL": "https://github.com/Alamofire/Alamofire.git", - "state": { - "branch": null, - "revision": "f455c2975872ccd2d9c81594c658af65716e9b9a", - "version": "5.9.1" - } - }, - { - "package": "AlamofireNetworkActivityIndicator", - "repositoryURL": "https://github.com/Alamofire/AlamofireNetworkActivityIndicator.git", - "state": { - "branch": null, - "revision": "392bed083e8d193aca16bfa684ee24e4bcff0510", - "version": "3.1.0" - } - }, - { - "package": "AppCheck", - "repositoryURL": "https://github.com/google/app-check.git", - "state": { - "branch": null, - "revision": "076b241a625e25eac22f8849be256dfb960fcdfe", - "version": "10.19.1" - } - }, - { - "package": "CocoaLumberjack", - "repositoryURL": "https://github.com/CocoaLumberjack/CocoaLumberjack.git", - "state": { - "branch": null, - "revision": "4b8714a7fb84d42393314ce897127b3939885ec3", - "version": "3.8.5" - } - }, - { - "package": "DeviceKit", - "repositoryURL": "https://github.com/devicekit/DeviceKit.git", - "state": { - "branch": null, - "revision": "d37e70cb2646666dcf276d7d3d4a9760a41ff8a6", - "version": "4.9.0" - } - }, - { - "package": "DynamicButton", - "repositoryURL": "https://github.com/yannickl/DynamicButton.git", - "state": { - "branch": null, - "revision": "4fbd60e46a548e77fd118483bbb4e58d3c11c5ed", - "version": "6.2.1" - } - }, - { - "package": "Firebase", - "repositoryURL": "https://github.com/firebase/firebase-ios-sdk.git", - "state": { - "branch": null, - "revision": "9d17b500cd98d9a7009751ad62f802e152e97021", - "version": "10.26.0" - } - }, - { - "package": "FlexColorPicker", - "repositoryURL": "https://github.com/RastislavMirek/FlexColorPicker.git", - "state": { - "branch": null, - "revision": "72a5c2c5e28074e6c5f13efe3c98eb780ae2f906", - "version": "1.4.4" - } - }, - { - "package": "GoogleAppMeasurement", - "repositoryURL": "https://github.com/google/GoogleAppMeasurement.git", - "state": { - "branch": null, - "revision": "16244d177c4e989f87b25e9db1012b382cfedc55", - "version": "10.25.0" - } - }, - { - "package": "GoogleDataTransport", - "repositoryURL": "https://github.com/google/GoogleDataTransport.git", - "state": { - "branch": null, - "revision": "a637d318ae7ae246b02d7305121275bc75ed5565", - "version": "9.4.0" - } - }, - { - "package": "GoogleUtilities", - "repositoryURL": "https://github.com/google/GoogleUtilities.git", - "state": { - "branch": null, - "revision": "57a1d307f42df690fdef2637f3e5b776da02aad6", - "version": "7.13.3" - } - }, - { - "package": "gRPC", - "repositoryURL": "https://github.com/google/grpc-binary.git", - "state": { - "branch": null, - "revision": "e9fad491d0673bdda7063a0341fb6b47a30c5359", - "version": "1.62.2" - } - }, - { - "package": "GTMSessionFetcher", - "repositoryURL": "https://github.com/google/gtm-session-fetcher.git", - "state": { - "branch": null, - "revision": "0382ca27f22fb3494cf657d8dc356dc282cd1193", - "version": "3.4.1" - } - }, - { - "package": "InteropForGoogle", - "repositoryURL": "https://github.com/google/interop-ios-for-google-sdks.git", - "state": { - "branch": null, - "revision": "2d12673670417654f08f5f90fdd62926dc3a2648", - "version": "100.0.0" - } - }, - { - "package": "Kingfisher", - "repositoryURL": "https://github.com/onevcat/Kingfisher.git", - "state": { - "branch": null, - "revision": "5b92f029fab2cce44386d28588098b5be0824ef5", - "version": "7.11.0" - } - }, - { - "package": "leveldb", - "repositoryURL": "https://github.com/firebase/leveldb.git", - "state": { - "branch": null, - "revision": "a0bc79961d7be727d258d33d5a6b2f1023270ba1", - "version": "1.22.5" - } - }, - { - "package": "nanopb", - "repositoryURL": "https://github.com/firebase/nanopb.git", - "state": { - "branch": null, - "revision": "b7e1104502eca3a213b46303391ca4d3bc8ddec1", - "version": "2.30910.0" - } - }, - { - "package": "Promises", - "repositoryURL": "https://github.com/google/promises.git", - "state": { - "branch": null, - "revision": "540318ecedd63d883069ae7f1ed811a2df00b6ac", - "version": "2.4.0" - } - }, - { - "package": "SideMenu", - "repositoryURL": "https://github.com/jonkykong/SideMenu.git", - "state": { - "branch": null, - "revision": "8bd4fd128923cf5494fa726839af8afe12908ad9", - "version": "6.5.0" - } - }, - { - "package": "SVGKit", - "repositoryURL": "https://github.com/SVGKit/SVGKit.git", - "state": { - "branch": "3.x", - "revision": "02421928cab787faaffb2403d47c39392936fbc7", - "version": null - } - }, - { - "package": "swift-log", - "repositoryURL": "https://github.com/apple/swift-log", - "state": { - "branch": null, - "revision": "e97a6fcb1ab07462881ac165fdbb37f067e205d5", - "version": "1.5.4" - } - }, - { - "package": "SwiftProtobuf", - "repositoryURL": "https://github.com/apple/swift-protobuf.git", - "state": { - "branch": null, - "revision": "9f0c76544701845ad98716f3f6a774a892152bcb", - "version": "1.26.0" - } - }, - { - "package": "SwiftMessages", - "repositoryURL": "https://github.com/SwiftKickMobile/SwiftMessages.git", - "state": { - "branch": null, - "revision": "62e12e138fc3eedf88c7553dd5d98712aa119f40", - "version": "9.0.9" - } - } - ] - }, - "version": 1 + "pins" : [ + { + "identity" : "abseil-cpp-binary", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/abseil-cpp-binary.git", + "state" : { + "revision" : "748c7837511d0e6a507737353af268484e1745e2", + "version" : "1.2024011601.1" + } + }, + { + "identity" : "alamofire", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Alamofire/Alamofire.git", + "state" : { + "revision" : "f455c2975872ccd2d9c81594c658af65716e9b9a", + "version" : "5.9.1" + } + }, + { + "identity" : "alamofirenetworkactivityindicator", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Alamofire/AlamofireNetworkActivityIndicator.git", + "state" : { + "revision" : "392bed083e8d193aca16bfa684ee24e4bcff0510", + "version" : "3.1.0" + } + }, + { + "identity" : "app-check", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/app-check.git", + "state" : { + "revision" : "076b241a625e25eac22f8849be256dfb960fcdfe", + "version" : "10.19.1" + } + }, + { + "identity" : "cocoalumberjack", + "kind" : "remoteSourceControl", + "location" : "https://github.com/CocoaLumberjack/CocoaLumberjack.git", + "state" : { + "revision" : "4b8714a7fb84d42393314ce897127b3939885ec3", + "version" : "3.8.5" + } + }, + { + "identity" : "devicekit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/devicekit/DeviceKit.git", + "state" : { + "revision" : "d37e70cb2646666dcf276d7d3d4a9760a41ff8a6", + "version" : "4.9.0" + } + }, + { + "identity" : "dynamicbutton", + "kind" : "remoteSourceControl", + "location" : "https://github.com/yannickl/DynamicButton.git", + "state" : { + "revision" : "4fbd60e46a548e77fd118483bbb4e58d3c11c5ed", + "version" : "6.2.1" + } + }, + { + "identity" : "firebase-ios-sdk", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/firebase-ios-sdk.git", + "state" : { + "revision" : "9d17b500cd98d9a7009751ad62f802e152e97021", + "version" : "10.26.0" + } + }, + { + "identity" : "flexcolorpicker", + "kind" : "remoteSourceControl", + "location" : "https://github.com/RastislavMirek/FlexColorPicker.git", + "state" : { + "revision" : "72a5c2c5e28074e6c5f13efe3c98eb780ae2f906", + "version" : "1.4.4" + } + }, + { + "identity" : "googleappmeasurement", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleAppMeasurement.git", + "state" : { + "revision" : "16244d177c4e989f87b25e9db1012b382cfedc55", + "version" : "10.25.0" + } + }, + { + "identity" : "googledatatransport", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleDataTransport.git", + "state" : { + "revision" : "a637d318ae7ae246b02d7305121275bc75ed5565", + "version" : "9.4.0" + } + }, + { + "identity" : "googleutilities", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleUtilities.git", + "state" : { + "revision" : "57a1d307f42df690fdef2637f3e5b776da02aad6", + "version" : "7.13.3" + } + }, + { + "identity" : "grpc-binary", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/grpc-binary.git", + "state" : { + "revision" : "e9fad491d0673bdda7063a0341fb6b47a30c5359", + "version" : "1.62.2" + } + }, + { + "identity" : "gtm-session-fetcher", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/gtm-session-fetcher.git", + "state" : { + "revision" : "0382ca27f22fb3494cf657d8dc356dc282cd1193", + "version" : "3.4.1" + } + }, + { + "identity" : "interop-ios-for-google-sdks", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/interop-ios-for-google-sdks.git", + "state" : { + "revision" : "2d12673670417654f08f5f90fdd62926dc3a2648", + "version" : "100.0.0" + } + }, + { + "identity" : "kingfisher", + "kind" : "remoteSourceControl", + "location" : "https://github.com/onevcat/Kingfisher.git", + "state" : { + "revision" : "5b92f029fab2cce44386d28588098b5be0824ef5", + "version" : "7.11.0" + } + }, + { + "identity" : "leveldb", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/leveldb.git", + "state" : { + "revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1", + "version" : "1.22.5" + } + }, + { + "identity" : "nanopb", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/nanopb.git", + "state" : { + "revision" : "b7e1104502eca3a213b46303391ca4d3bc8ddec1", + "version" : "2.30910.0" + } + }, + { + "identity" : "promises", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/promises.git", + "state" : { + "revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac", + "version" : "2.4.0" + } + }, + { + "identity" : "sidemenu", + "kind" : "remoteSourceControl", + "location" : "https://github.com/jonkykong/SideMenu.git", + "state" : { + "revision" : "8bd4fd128923cf5494fa726839af8afe12908ad9", + "version" : "6.5.0" + } + }, + { + "identity" : "svgkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SVGKit/SVGKit.git", + "state" : { + "branch" : "3.x", + "revision" : "02421928cab787faaffb2403d47c39392936fbc7" + } + }, + { + "identity" : "swift-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-collections", + "state" : { + "revision" : "3d2dc41a01f9e49d84f0a3925fb858bed64f702d", + "version" : "1.1.2" + } + }, + { + "identity" : "swift-http-types", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-http-types", + "state" : { + "revision" : "ae67c8178eb46944fd85e4dc6dd970e1f3ed6ccd", + "version" : "1.3.0" + } + }, + { + "identity" : "swift-log", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-log", + "state" : { + "revision" : "e97a6fcb1ab07462881ac165fdbb37f067e205d5", + "version" : "1.5.4" + } + }, + { + "identity" : "swift-openapi-runtime", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-openapi-runtime", + "state" : { + "revision" : "26e8ae3515d1ff3607e924ac96fc0094775f55e8", + "version" : "1.5.0" + } + }, + { + "identity" : "swift-openapi-urlsession", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-openapi-urlsession", + "state" : { + "revision" : "9bf4c712ad7989d6a91dbe68748b8829a50837e4", + "version" : "1.0.2" + } + }, + { + "identity" : "swift-protobuf", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-protobuf.git", + "state" : { + "revision" : "9f0c76544701845ad98716f3f6a774a892152bcb", + "version" : "1.26.0" + } + }, + { + "identity" : "swiftmessages", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SwiftKickMobile/SwiftMessages.git", + "state" : { + "revision" : "62e12e138fc3eedf88c7553dd5d98712aa119f40", + "version" : "9.0.9" + } + } + ], + "version" : 2 } diff --git a/openHAB/OpenHABDrawerTableViewController.swift b/openHAB/OpenHABDrawerTableViewController.swift index 9449d28c..cbe48ed7 100644 --- a/openHAB/OpenHABDrawerTableViewController.swift +++ b/openHAB/OpenHABDrawerTableViewController.swift @@ -10,30 +10,12 @@ // SPDX-License-Identifier: EPL-2.0 import DynamicButton +import OpenAPIURLSession import OpenHABCore import os.log import SafariServices import UIKit -func deriveSitemaps(_ response: Data?) -> [OpenHABSitemap] { - var sitemaps = [OpenHABSitemap]() - - if let response { - do { - os_log("Response will be decoded by JSON", log: .remoteAccess, type: .info) - let sitemapsCodingData = try response.decoded(as: [OpenHABSitemap.CodingData].self) - for sitemapCodingDatum in sitemapsCodingData { - os_log("Sitemap %{PUBLIC}@", log: .remoteAccess, type: .info, sitemapCodingDatum.label) - sitemaps.append(sitemapCodingDatum.openHABSitemap) - } - } catch { - os_log("Should not throw %{PUBLIC}@", log: .notifications, type: .error, error.localizedDescription) - } - } - - return sitemaps -} - struct UiTile: Decodable { var name: String var url: String @@ -55,11 +37,15 @@ class OpenHABDrawerTableViewController: UITableViewController { AppDelegate.appDelegate.appData } + private let apiactor: APIActor + init() { + apiactor = APIActor() super.init(nibName: nil, bundle: nil) } required init?(coder aDecoder: NSCoder) { + apiactor = APIActor() super.init(coder: aDecoder) } @@ -77,27 +63,24 @@ class OpenHABDrawerTableViewController: UITableViewController { super.viewWillAppear(animated) os_log("OpenHABDrawerTableViewController viewWillAppear", log: .viewCycle, type: .info) - NetworkConnection.sitemaps(openHABRootUrl: appData?.openHABRootUrl ?? "") { response in - switch response.result { - case let .success(data): - os_log("Sitemap response", log: .viewCycle, type: .info) - - self.sitemaps = deriveSitemaps(data) + Task { + do { + await apiactor.updateBaseURL(with: URL(string: appData?.openHABRootUrl ?? "")!) - if self.sitemaps.last?.name == "_default", self.sitemaps.count > 1 { - self.sitemaps = Array(self.sitemaps.dropLast()) + sitemaps = try await apiactor.openHABSitemaps() + if sitemaps.last?.name == "_default", sitemaps.count > 1 { + sitemaps = Array(sitemaps.dropLast()) } - // Sort the sitemaps according to Settings selection. switch SortSitemapsOrder(rawValue: Preferences.sortSitemapsby) ?? .label { - case .label: self.sitemaps.sort { $0.label < $1.label } - case .name: self.sitemaps.sort { $0.name < $1.name } + case .label: sitemaps.sort { $0.label < $1.label } + case .name: sitemaps.sort { $0.name < $1.name } } self.drawerItems.removeAll() self.setStandardDrawerItems() self.tableView.reloadData() - case let .failure(error): + } catch { os_log("%{PUBLIC}@", log: .default, type: .error, error.localizedDescription) self.drawerItems.removeAll() self.setStandardDrawerItems() @@ -105,23 +88,13 @@ class OpenHABDrawerTableViewController: UITableViewController { } } - NetworkConnection.uiTiles(openHABRootUrl: appData?.openHABRootUrl ?? "") { response in - switch response.result { - case .success: - UIApplication.shared.isNetworkActivityIndicatorVisible = false + Task { + do { + await apiactor.updateBaseURL(with: URL(string: appData?.openHABRootUrl ?? "")!) + uiTiles = try await apiactor.openHABTiles() os_log("ui tiles response", log: .viewCycle, type: .info) - guard let responseData = response.data else { - os_log("Error: did not receive data", log: OSLog.remoteAccess, type: .info) - return - } - do { - self.uiTiles = try JSONDecoder().decode([OpenHABUiTile].self, from: responseData) - self.tableView.reloadData() - } catch { - os_log("Error: did not receive data %{PUBLIC}@", log: OSLog.remoteAccess, type: .info, error.localizedDescription) - } - case let .failure(error): - UIApplication.shared.isNetworkActivityIndicatorVisible = false + self.tableView.reloadData() + } catch { os_log("%{PUBLIC}@", log: .default, type: .error, error.localizedDescription) } } diff --git a/openHAB/OpenHABSitemapViewController.swift b/openHAB/OpenHABSitemapViewController.swift index 53e7cf0c..9b01fb65 100644 --- a/openHAB/OpenHABSitemapViewController.swift +++ b/openHAB/OpenHABSitemapViewController.swift @@ -13,6 +13,8 @@ import Alamofire import AVFoundation import AVKit import Kingfisher +import OpenAPIRuntime +import OpenAPIURLSession import OpenHABCore import os.log import SafariServices @@ -71,20 +73,21 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel private var defaultSitemap = "" private var idleOff = false private var sitemaps: [OpenHABSitemap] = [] - private var currentPage: OpenHABSitemapPage? + private var currentPage: OpenHABPage? private var selectionPicker: UIPickerView? private var pageNetworkStatus: NetworkReachabilityManager.NetworkReachabilityStatus? private var pageNetworkStatusAvailable = false private var toggle: Int = 0 private var refreshControl: UIRefreshControl? - private var filteredPage: OpenHABSitemapPage? + private var filteredPage: OpenHABPage? private var serverProperties: OpenHABServerProperties? private let search = UISearchController(searchResultsController: nil) private var webViewController: OpenHABWebViewController? private var isUserInteracting = false private var isWaitingToReload = false + private var asyncOperation: Task? - var relevantPage: OpenHABSitemapPage? { + var relevantPage: OpenHABPage? { if isFiltering { filteredPage } else { @@ -109,6 +112,8 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel search.isActive && !searchBarIsEmpty } + private let apiactor = APIActor() + @IBOutlet private var widgetTableView: UITableView! // Here goes everything about view loading, appearing, disappearing, entering background and becoming active @@ -177,6 +182,7 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel OpenHABTracker.shared.multicastDelegate.add(self) OpenHABTracker.shared.restart() } else { + Task { await apiactor.updateBaseURL(with: URL(string: appData!.openHABRootUrl)!) } if !pageNetworkStatusChanged() { os_log("OpenHABSitemapViewController pageUrl = %{PUBLIC}@", log: .notifications, type: .info, pageUrl) loadPage(false) @@ -307,6 +313,11 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel currentPageOperation = nil } + // if asyncOperation != nil { + // asyncOperation?.cancel() + // asyncOperation = nil + // } + if pageUrl == "" { return } @@ -315,37 +326,14 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel // If this is the first request to the page make a bulk call to pageNetworkStatusChanged // to save current reachability status. if !longPolling { - _ = pageNetworkStatusChanged() + pageNetworkStatusChanged() } + asyncOperation = Task { + do { + await apiactor.updateBaseURL(with: URL(string: appData?.openHABRootUrl ?? "")!) - currentPageOperation = NetworkConnection.page( - pageUrl: pageUrl, - longPolling: longPolling - ) { [weak self] response in - guard let self else { return } + currentPage = try await apiactor.openHABpollPage(sitemapname: defaultSitemap, longPolling: longPolling) - switch response.result { - case let .success(data): - os_log("Page loaded with success", log: OSLog.remoteAccess, type: .info) - let headers = response.response?.allHeaderFields - - NetworkConnection.atmosphereTrackingId = headers?["X-Atmosphere-tracking-id"] as? String ?? "" - if !NetworkConnection.atmosphereTrackingId.isEmpty { - os_log("Found X-Atmosphere-tracking-id: %{PUBLIC}@", log: .remoteAccess, type: .info, NetworkConnection.atmosphereTrackingId) - } - var openHABSitemapPage: OpenHABSitemapPage? - do { - // Self-executing closure - // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift - openHABSitemapPage = try { - let sitemapPageCodingData = try data.decoded(as: OpenHABSitemapPage.CodingData.self) - return sitemapPageCodingData.openHABSitemapPage - }() - } catch { - os_log("Should not throw %{PUBLIC}@", log: OSLog.remoteAccess, type: .error, error.localizedDescription) - } - - currentPage = openHABSitemapPage if isFiltering { filterContentForSearchText(search.searchBar.text) } @@ -363,65 +351,64 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel parent?.navigationItem.title = currentPage?.title.components(separatedBy: "[")[0] loadPage(true) - case let .failure(error): - os_log("On LoadPage \"%{PUBLIC}@\" code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) - + } catch let error as DecodingError { + os_log("DecodingError %{PUBLIC}@", log: .default, type: .error, error.localizedDescription) + // } catch let error as NSError where error.code == -1001 { + // os_log("Timeout, restarting requests", log: OSLog.remoteAccess, type: .error) + // loadPage(false) + + } catch { + os_log("On LoadPage \"%{PUBLIC}@\" code: %d ", log: .remoteAccess, type: .error, error.localizedDescription) NetworkConnection.atmosphereTrackingId = "" - if (error as NSError?)?.code == -1001, longPolling { - os_log("Timeout, restarting requests", log: OSLog.remoteAccess, type: .error) - loadPage(false) - } else if error.isExplicitlyCancelledError { - os_log("Request was cancelled", log: OSLog.remoteAccess, type: .error) - } else { - // Error - DispatchQueue.main.async { - if (error as NSError?)?.code == -1012 { - self.showPopupMessage(seconds: 5, title: NSLocalizedString("error", comment: ""), message: NSLocalizedString("ssl_certificate_error", comment: ""), theme: .error) - } else { - self.showPopupMessage(seconds: 5, title: NSLocalizedString("error", comment: ""), message: error.localizedDescription, theme: .error) - } + // Error + DispatchQueue.main.async { + if (error as NSError?)?.code == -1012 { + self.showPopupMessage(seconds: 5, title: NSLocalizedString("error", comment: ""), message: NSLocalizedString("ssl_certificate_error", comment: ""), theme: .error) + } else { + self.showPopupMessage(seconds: 5, title: NSLocalizedString("error", comment: ""), message: error.localizedDescription, theme: .error) } } } + return 0 } - currentPageOperation?.resume() - os_log("OpenHABSitemapViewController request sent", log: .remoteAccess, type: .error) } // Select sitemap func selectSitemap() { - NetworkConnection.sitemaps(openHABRootUrl: openHABRootUrl) { response in - switch response.result { - case let .success(data): - self.sitemaps = deriveSitemaps(data) - switch self.sitemaps.count { + Task { + do { + await apiactor.updateBaseURL(with: URL(string: appData?.openHABRootUrl ?? "")!) + + sitemaps = try await apiactor.openHABSitemaps() + + switch sitemaps.count { case 2...: if !self.defaultSitemap.isEmpty { - if let sitemapToOpen = self.sitemap(byName: self.defaultSitemap) { + if let sitemapToOpen = sitemap(byName: self.defaultSitemap) { if self.currentPage?.pageId != sitemapToOpen.name { self.currentPage?.widgets.removeAll() // NOTE: remove all widgets to ensure cells get invalidated } - self.pageUrl = sitemapToOpen.homepageLink - self.loadPage(false) + pageUrl = sitemapToOpen.homepageLink + loadPage(false) } else { - self.showSideMenu() + showSideMenu() } } else { - self.showSideMenu() + showSideMenu() } case 1: - self.pageUrl = self.sitemaps[0].homepageLink - self.loadPage(false) + pageUrl = sitemaps[0].homepageLink + loadPage(false) case ...0: - self.showPopupMessage(seconds: 5, title: NSLocalizedString("warning", comment: ""), message: NSLocalizedString("empty_sitemap", comment: ""), theme: .warning) - self.showSideMenu() + showPopupMessage(seconds: 5, title: NSLocalizedString("warning", comment: ""), message: NSLocalizedString("empty_sitemap", comment: ""), theme: .warning) + showSideMenu() default: break } - self.widgetTableView.reloadData() - case let .failure(error): - os_log("%{PUBLIC}@ %d", log: .default, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) + widgetTableView.reloadData() + } catch { + os_log("%{PUBLIC}@", log: .default, type: .error, error.localizedDescription) DispatchQueue.main.async { // Error if (error as NSError?)?.code == -1012 { @@ -464,6 +451,7 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel return nil } + @discardableResult func pageNetworkStatusChanged() -> Bool { os_log("OpenHABSitemapViewController pageNetworkStatusChange", log: .remoteAccess, type: .info) if !pageUrl.isEmpty { @@ -497,16 +485,15 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel } func sendCommand(_ item: OpenHABItem?, commandToSend command: String?) { - if commandOperation != nil { - commandOperation?.cancel() - commandOperation = nil - } if let item, let command { - commandOperation = NetworkConnection.sendCommand(item: item, commandToSend: command) - commandOperation?.resume() + sendCommand(itemname: item.name, command: command) } } + func sendCommand(itemname: String, command: String) { + Task { try await apiactor.openHABSendItemCommand(itemname: itemname, command: command) } + } + override func reloadView() { defaultSitemap = Preferences.defaultSitemap selectSitemap() diff --git a/openHAB/openapi/openapitest/openapiCorrected.json b/openHAB/openapi/openapitest/openapiCorrected.json new file mode 100644 index 00000000..7a183fae --- /dev/null +++ b/openHAB/openapi/openapitest/openapiCorrected.json @@ -0,0 +1,9756 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "openHAB REST API", + "contact": { + "name": "openHAB", + "url": "https://www.openhab.org/docs/" + }, + "version": "8" + }, + "servers": [ + { + "url": "/rest" + } + ], + "paths": { + "/module-types": { + "get": { + "tags": [ + "module-types" + ], + "summary": "Get all available module types.", + "operationId": "getModuleTypes", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "tags", + "in": "query", + "description": "tags for filtering", + "schema": { + "type": "string" + } + }, + { + "name": "type", + "in": "query", + "description": "filtering by action, condition or trigger", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ModuleTypeDTO" + } + } + } + } + } + } + } + }, + "/module-types/{moduleTypeUID}": { + "get": { + "tags": [ + "module-types" + ], + "summary": "Gets a module type corresponding to the given UID.", + "operationId": "getModuleTypeById", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "moduleTypeUID", + "in": "path", + "description": "moduleTypeUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModuleTypeDTO" + } + } + } + }, + "404": { + "description": "Module Type corresponding to the given UID does not found." + } + } + } + }, + "/rules": { + "get": { + "tags": [ + "rules" + ], + "summary": "Get available rules, optionally filtered by tags and/or prefix.", + "operationId": "getRules", + "parameters": [ + { + "name": "prefix", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "tags", + "in": "query", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "summary", + "in": "query", + "description": "summary fields only", + "schema": { + "type": "boolean" + } + }, + { + "name": "staticDataOnly", + "in": "query", + "description": "provides a cacheable list of values not expected to change regularly and honors the If-Modified-Since header, all other parameters are ignored", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EnrichedRuleDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "post": { + "tags": [ + "rules" + ], + "summary": "Creates a rule.", + "operationId": "createRule", + "requestBody": { + "description": "rule data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuleDTO" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Created", + "headers": { + "Location": { + "description": "Newly created Rule", + "schema": { + "type": "string" + } + } + } + }, + "409": { + "description": "Creation of the rule is refused. Rule with the same UID already exists." + }, + "400": { + "description": "Creation of the rule is refused. Missing required parameter." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}/enable": { + "post": { + "tags": [ + "rules" + ], + "summary": "Sets the rule enabled status.", + "operationId": "enableRule", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "enable", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Rule corresponding to the given UID does not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}/actions": { + "get": { + "tags": [ + "rules" + ], + "summary": "Gets the rule actions.", + "operationId": "getRuleActions", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ActionDTO" + } + } + } + } + }, + "404": { + "description": "Rule corresponding to the given UID does not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}": { + "get": { + "tags": [ + "rules" + ], + "summary": "Gets the rule corresponding to the given UID.", + "operationId": "getRuleById", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnrichedRuleDTO" + } + } + } + }, + "404": { + "description": "Rule not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "rules" + ], + "summary": "Updates an existing rule corresponding to the given UID.", + "operationId": "updateRule", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "rule data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuleDTO" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Rule corresponding to the given UID does not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "rules" + ], + "summary": "Removes an existing rule corresponding to the given UID.", + "operationId": "deleteRule", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Rule corresponding to the given UID does not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}/conditions": { + "get": { + "tags": [ + "rules" + ], + "summary": "Gets the rule conditions.", + "operationId": "getRuleConditions", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConditionDTO" + } + } + } + } + }, + "404": { + "description": "Rule corresponding to the given UID does not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}/config": { + "get": { + "tags": [ + "rules" + ], + "summary": "Gets the rule configuration values.", + "operationId": "getRuleConfiguration", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "404": { + "description": "Rule corresponding to the given UID does not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "rules" + ], + "summary": "Sets the rule configuration values.", + "operationId": "updateRuleConfiguration", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "config", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Rule corresponding to the given UID does not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}/{moduleCategory}/{id}": { + "get": { + "tags": [ + "rules" + ], + "summary": "Gets the rule\u0027s module corresponding to the given Category and ID.", + "operationId": "getRuleModuleById", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "moduleCategory", + "in": "path", + "description": "moduleCategory", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "path", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModuleDTO" + } + } + } + }, + "404": { + "description": "Rule corresponding to the given UID does not found or does not have a module with such Category and ID." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}/{moduleCategory}/{id}/config": { + "get": { + "tags": [ + "rules" + ], + "summary": "Gets the module\u0027s configuration.", + "operationId": "getRuleModuleConfig", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "moduleCategory", + "in": "path", + "description": "moduleCategory", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "path", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "404": { + "description": "Rule corresponding to the given UID does not found or does not have a module with such Category and ID." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}/{moduleCategory}/{id}/config/{param}": { + "get": { + "tags": [ + "rules" + ], + "summary": "Gets the module\u0027s configuration parameter.", + "operationId": "getRuleModuleConfigParameter", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "moduleCategory", + "in": "path", + "description": "moduleCategory", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "path", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "param", + "in": "path", + "description": "param", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + }, + "404": { + "description": "Rule corresponding to the given UID does not found or does not have a module with such Category and ID." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "rules" + ], + "summary": "Sets the module\u0027s configuration parameter value.", + "operationId": "setRuleModuleConfigParameter", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "moduleCategory", + "in": "path", + "description": "moduleCategory", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "path", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "param", + "in": "path", + "description": "param", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "value", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Rule corresponding to the given UID does not found or does not have a module with such Category and ID." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}/triggers": { + "get": { + "tags": [ + "rules" + ], + "summary": "Gets the rule triggers.", + "operationId": "getRuleTriggers", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TriggerDTO" + } + } + } + } + }, + "404": { + "description": "Rule corresponding to the given UID does not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/{ruleUID}/runnow": { + "post": { + "tags": [ + "rules" + ], + "summary": "Executes actions of the rule.", + "operationId": "runRuleNow_1", + "parameters": [ + { + "name": "ruleUID", + "in": "path", + "description": "ruleUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "the context for running this rule", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Rule corresponding to the given UID does not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/rules/schedule/simulations": { + "get": { + "tags": [ + "rules" + ], + "summary": "Simulates the executions of rules filtered by tag \u0027Schedule\u0027 within the given times.", + "operationId": "getScheduleRuleSimulations", + "parameters": [ + { + "name": "from", + "in": "query", + "description": "Start time of the simulated rule executions. Will default to the current time. [yyyy-MM-dd\u0027T\u0027HH:mm:ss.SSSZ]", + "schema": { + "type": "string" + } + }, + { + "name": "until", + "in": "query", + "description": "End time of the simulated rule executions. Will default to 30 days after the start time. Must be less than 180 days after the given start time. [yyyy-MM-dd\u0027T\u0027HH:mm:ss.SSSZ]", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RuleExecution" + } + } + } + } + }, + "400": { + "description": "The max. simulation duration of 180 days is exceeded." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/templates": { + "get": { + "tags": [ + "templates" + ], + "summary": "Get all available templates.", + "operationId": "getTemplates", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Template" + } + } + } + } + } + } + } + }, + "/templates/{templateUID}": { + "get": { + "tags": [ + "templates" + ], + "summary": "Gets a template corresponding to the given UID.", + "operationId": "getTemplateById", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "templateUID", + "in": "path", + "description": "templateUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Template" + } + } + } + }, + "404": { + "description": "Template corresponding to the given UID does not found." + } + } + } + }, + "/actions/{thingUID}/{actionUid}": { + "post": { + "tags": [ + "actions" + ], + "summary": "Executes a thing action.", + "operationId": "executeThingAction", + "parameters": [ + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "actionUid", + "in": "path", + "description": "action type UID (including scope, separated by \u0027.\u0027)", + "required": true, + "schema": { + "pattern": "[a-zA-Z0-9]+\\.[a-zA-Z0-9]+", + "type": "string" + } + }, + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "action inputs as map (parameter name as key / argument as value)", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "404": { + "description": "Action not found" + }, + "500": { + "description": "Creation of action handler or execution failed" + } + } + } + }, + "/actions/{thingUID}": { + "get": { + "tags": [ + "actions" + ], + "summary": "Get all available actions for provided thing UID", + "operationId": "getAvailableActionsForThing", + "parameters": [ + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/ThingActionDTO" + } + } + } + } + }, + "204": { + "description": "No actions found." + } + } + } + }, + "/uuid": { + "get": { + "tags": [ + "uuid" + ], + "summary": "A unified unique id.", + "operationId": "getUUID", + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + } + } + } + }, + "/audio/defaultsink": { + "get": { + "tags": [ + "audio" + ], + "summary": "Get the default sink if defined or the first available sink.", + "operationId": "getAudioDefaultSink", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AudioSinkDTO" + } + } + } + }, + "404": { + "description": "Sink not found" + } + } + } + }, + "/audio/defaultsource": { + "get": { + "tags": [ + "audio" + ], + "summary": "Get the default source if defined or the first available source.", + "operationId": "getAudioDefaultSource", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AudioSourceDTO" + } + } + } + }, + "404": { + "description": "Source not found" + } + } + } + }, + "/audio/sinks": { + "get": { + "tags": [ + "audio" + ], + "summary": "Get the list of all sinks.", + "operationId": "getAudioSinks", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AudioSinkDTO" + } + } + } + } + } + } + } + }, + "/audio/sources": { + "get": { + "tags": [ + "audio" + ], + "summary": "Get the list of all sources.", + "operationId": "getAudioSources", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AudioSourceDTO" + } + } + } + } + } + } + } + }, + "/auth/logout": { + "post": { + "tags": [ + "auth" + ], + "summary": "Delete the session associated with a refresh token.", + "operationId": "deleteSession", + "requestBody": { + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "type": "object", + "properties": { + "refresh_token": { + "type": "string" + }, + "id": { + "type": "string" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "User is not authenticated" + }, + "404": { + "description": "User or refresh token not found" + } + } + } + }, + "/auth/apitokens": { + "get": { + "tags": [ + "auth" + ], + "summary": "List the API tokens associated to the authenticated user.", + "operationId": "getApiTokens", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserApiTokenDTO" + } + } + } + } + }, + "401": { + "description": "User is not authenticated" + }, + "404": { + "description": "User not found" + } + } + } + }, + "/auth/sessions": { + "get": { + "tags": [ + "auth" + ], + "summary": "List the sessions associated to the authenticated user.", + "operationId": "getSessionsForCurrentUser", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserSessionDTO" + } + } + } + } + }, + "401": { + "description": "User is not authenticated" + }, + "404": { + "description": "User not found" + } + } + } + }, + "/auth/token": { + "post": { + "tags": [ + "auth" + ], + "summary": "Get access and refresh tokens.", + "operationId": "getOAuthToken", + "parameters": [ + { + "name": "useCookie", + "in": "query", + "schema": { + "type": "boolean" + } + } + ], + "requestBody": { + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "type": "object", + "properties": { + "grant_type": { + "type": "string" + }, + "code": { + "type": "string" + }, + "redirect_uri": { + "type": "string" + }, + "client_id": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "code_verifier": { + "type": "string" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResponseDTO" + } + } + } + }, + "400": { + "description": "Invalid request parameters" + } + } + } + }, + "/auth/apitokens/{name}": { + "delete": { + "tags": [ + "auth" + ], + "summary": "Revoke a specified API token associated to the authenticated user.", + "operationId": "removeApiToken", + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "User is not authenticated" + }, + "404": { + "description": "User or API token not found" + } + } + } + }, + "/addons": { + "get": { + "tags": [ + "addons" + ], + "summary": "Get all add-ons.", + "operationId": "getAddons", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "serviceId", + "in": "query", + "description": "service ID", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Addon" + } + } + } + } + }, + "404": { + "description": "Service not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/addons/{addonId}": { + "get": { + "tags": [ + "addons" + ], + "summary": "Get add-on with given ID.", + "operationId": "getAddonById", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "addonId", + "in": "path", + "description": "addon ID", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9-:]+", + "type": "string" + } + }, + { + "name": "serviceId", + "in": "query", + "description": "service ID", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Addon" + } + } + } + }, + "404": { + "description": "Not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/addons/{addonId}/config": { + "get": { + "tags": [ + "addons" + ], + "summary": "Get add-on configuration for given add-on ID.", + "operationId": "getAddonConfiguration", + "parameters": [ + { + "name": "addonId", + "in": "path", + "description": "addon ID", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9-:]+", + "type": "string" + } + }, + { + "name": "serviceId", + "in": "query", + "description": "service ID", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "404": { + "description": "Add-on does not exist" + }, + "500": { + "description": "Configuration can not be read due to internal error" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "addons" + ], + "summary": "Updates an add-on configuration for given ID and returns the old configuration.", + "operationId": "updateAddonConfiguration", + "parameters": [ + { + "name": "addonId", + "in": "path", + "description": "Add-on id", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9-:]+", + "type": "string" + } + }, + { + "name": "serviceId", + "in": "query", + "description": "service ID", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "204": { + "description": "No old configuration" + }, + "404": { + "description": "Add-on does not exist" + }, + "500": { + "description": "Configuration can not be updated due to internal error" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/addons/services": { + "get": { + "tags": [ + "addons" + ], + "summary": "Get all add-on types.", + "operationId": "getAddonTypes", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AddonType" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/addons/suggestions": { + "get": { + "tags": [ + "addons" + ], + "summary": "Get suggested add-ons to be installed.", + "operationId": "getSuggestedAddons", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Addon" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/addons/types": { + "get": { + "tags": [ + "addons" + ], + "summary": "Get add-on services.", + "operationId": "getAddonServices", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "serviceId", + "in": "query", + "description": "service ID", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AddonType" + } + } + } + } + }, + "404": { + "description": "Service not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/addons/{addonId}/install": { + "post": { + "tags": [ + "addons" + ], + "summary": "Installs the add-on with the given ID.", + "operationId": "installAddonById", + "parameters": [ + { + "name": "addonId", + "in": "path", + "description": "addon ID", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9-:]+", + "type": "string" + } + }, + { + "name": "serviceId", + "in": "query", + "description": "service ID", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/addons/url/{url}/install": { + "post": { + "tags": [ + "addons" + ], + "summary": "Installs the add-on from the given URL.", + "operationId": "installAddonFromURL", + "parameters": [ + { + "name": "url", + "in": "path", + "description": "addon install URL", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "The given URL is malformed or not valid." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/addons/{addonId}/uninstall": { + "post": { + "tags": [ + "addons" + ], + "summary": "Uninstalls the add-on with the given ID.", + "operationId": "uninstallAddon", + "parameters": [ + { + "name": "addonId", + "in": "path", + "description": "addon ID", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9-:]+", + "type": "string" + } + }, + { + "name": "serviceId", + "in": "query", + "description": "service ID", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/channel-types": { + "get": { + "tags": [ + "channel-types" + ], + "summary": "Gets all available channel types.", + "operationId": "getChannelTypes", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "prefixes", + "in": "query", + "description": "filter UIDs by prefix (multiple comma-separated prefixes allowed, for example: \u0027system,mqtt\u0027)", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/ChannelTypeDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/channel-types/{channelTypeUID}": { + "get": { + "tags": [ + "channel-types" + ], + "summary": "Gets channel type by UID.", + "operationId": "getChannelTypeByUID", + "parameters": [ + { + "name": "channelTypeUID", + "in": "path", + "description": "channelTypeUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Channel type with provided channelTypeUID does not exist.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChannelTypeDTO" + } + } + } + }, + "404": { + "description": "No content" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/channel-types/{channelTypeUID}/linkableItemTypes": { + "get": { + "tags": [ + "channel-types" + ], + "summary": "Gets the item types the given trigger channel type UID can be linked to.", + "operationId": "getLinkableItemTypesByChannelTypeUID", + "parameters": [ + { + "name": "channelTypeUID", + "in": "path", + "description": "channelTypeUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "204": { + "description": "No content: channel type has no linkable items or is no trigger channel." + }, + "404": { + "description": "Given channel type UID not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/config-descriptions": { + "get": { + "tags": [ + "config-descriptions" + ], + "summary": "Gets all available config descriptions.", + "operationId": "getConfigDescriptions", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "scheme", + "in": "query", + "description": "scheme filter", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/config-descriptions/{uri}": { + "get": { + "tags": [ + "config-descriptions" + ], + "summary": "Gets a config description by URI.", + "operationId": "getConfigDescriptionByURI", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "uri", + "in": "path", + "description": "uri", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConfigDescriptionDTO" + } + } + } + }, + "400": { + "description": "Invalid URI syntax" + }, + "404": { + "description": "Not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/discovery": { + "get": { + "tags": [ + "discovery" + ], + "summary": "Gets all bindings that support discovery.", + "operationId": "getBindingsWithDiscoverySupport", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/discovery/bindings/{bindingId}/scan": { + "post": { + "tags": [ + "discovery" + ], + "summary": "Starts asynchronous discovery process for a binding and returns the timeout in seconds of the discovery operation.", + "operationId": "scan", + "parameters": [ + { + "name": "bindingId", + "in": "path", + "description": "bindingId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "type": "integer", + "format": "int32" + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/inbox/{thingUID}/approve": { + "post": { + "tags": [ + "inbox" + ], + "summary": "Approves the discovery result by adding the thing to the registry.", + "operationId": "approveInboxItemById", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "newThingId", + "in": "query", + "description": "new thing ID", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "thing label", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Invalid new thing ID." + }, + "404": { + "description": "Thing unable to be approved." + }, + "409": { + "description": "No binding found that supports this thing." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/inbox/{thingUID}": { + "delete": { + "tags": [ + "inbox" + ], + "summary": "Removes the discovery result from the inbox.", + "operationId": "removeItemFromInbox", + "parameters": [ + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Discovery result not found in the inbox." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/inbox": { + "get": { + "tags": [ + "inbox" + ], + "summary": "Get all discovered things.", + "operationId": "getDiscoveredInboxItems", + "parameters": [ + { + "name": "includeIgnored", + "in": "query", + "description": "If true, include ignored inbox entries. Defaults to true", + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DiscoveryResultDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/inbox/{thingUID}/ignore": { + "post": { + "tags": [ + "inbox" + ], + "summary": "Flags a discovery result as ignored for further processing.", + "operationId": "flagInboxItemAsIgnored", + "parameters": [ + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/inbox/{thingUID}/unignore": { + "post": { + "tags": [ + "inbox" + ], + "summary": "Removes ignore flag from a discovery result.", + "operationId": "removeIgnoreFlagOnInboxItem", + "parameters": [ + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/items/{itemName}/members/{memberItemName}": { + "put": { + "tags": [ + "items" + ], + "summary": "Adds a new member to a group item.", + "operationId": "addMemberToGroupItem", + "parameters": [ + { + "name": "itemName", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "memberItemName", + "in": "path", + "description": "member item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Item or member item not found or item is not of type group item." + }, + "405": { + "description": "Member item is not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "items" + ], + "summary": "Removes an existing member from a group item.", + "operationId": "removeMemberFromGroupItem", + "parameters": [ + { + "name": "itemName", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "memberItemName", + "in": "path", + "description": "member item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Item or member item not found or item is not of type group item." + }, + "405": { + "description": "Member item is not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/items/{itemname}/metadata/{namespace}": { + "put": { + "tags": [ + "items" + ], + "summary": "Adds metadata to an item.", + "operationId": "addMetadataToItem", + "parameters": [ + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "namespace", + "in": "path", + "description": "namespace", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "metadata", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetadataDTO" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "201": { + "description": "Created" + }, + "400": { + "description": "Metadata value empty." + }, + "404": { + "description": "Item not found." + }, + "405": { + "description": "Metadata not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "items" + ], + "summary": "Removes metadata from an item.", + "operationId": "removeMetadataFromItem", + "parameters": [ + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "namespace", + "in": "path", + "description": "namespace", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Item not found." + }, + "405": { + "description": "Meta data not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/items/{itemname}/tags/{tag}": { + "put": { + "tags": [ + "items" + ], + "summary": "Adds a tag to an item.", + "operationId": "addTagToItem", + "parameters": [ + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "tag", + "in": "path", + "description": "tag", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Item not found." + }, + "405": { + "description": "Item not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "items" + ], + "summary": "Removes a tag from an item.", + "operationId": "removeTagFromItem", + "parameters": [ + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "tag", + "in": "path", + "description": "tag", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Item not found." + }, + "405": { + "description": "Item not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/items/{itemname}": { + "get": { + "tags": [ + "items" + ], + "summary": "Gets a single item.", + "operationId": "getItemByName", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "metadata", + "in": "query", + "description": "metadata selector - a comma separated list or a regular expression (returns all if no value given)", + "schema": { + "type": "string", + "default": ".*" + } + }, + { + "name": "recursive", + "in": "query", + "description": "get member items if the item is a group item", + "schema": { + "type": "boolean", + "default": true + } + }, + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnrichedItemDTO" + } + } + } + }, + "404": { + "description": "Item not found" + } + } + }, + "put": { + "tags": [ + "items" + ], + "summary": "Adds a new item to the registry or updates the existing item.", + "operationId": "addOrUpdateItemInRegistry", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + } + ], + "requestBody": { + "description": "item data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GroupItemDTO" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/EnrichedItemDTO" + } + } + } + }, + "201": { + "description": "Item created." + }, + "400": { + "description": "Payload invalid." + }, + "404": { + "description": "Item not found or name in path invalid." + }, + "405": { + "description": "Item not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "post": { + "tags": [ + "items" + ], + "summary": "Sends a command to an item.", + "operationId": "sendItemCommand", + "parameters": [ + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + } + ], + "requestBody": { + "description": "valid item command (e.g. ON, OFF, UP, DOWN, REFRESH)", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Item not found" + }, + "400": { + "description": "Item command null" + } + } + }, + "delete": { + "tags": [ + "items" + ], + "summary": "Removes an item from the registry.", + "operationId": "removeItemFromRegistry", + "parameters": [ + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Item not found or item is not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/items": { + "get": { + "tags": [ + "items" + ], + "summary": "Get all available items.", + "operationId": "getItems", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "type", + "in": "query", + "description": "item type filter", + "schema": { + "type": "string" + } + }, + { + "name": "tags", + "in": "query", + "description": "item tag filter", + "schema": { + "type": "string" + } + }, + { + "name": "metadata", + "in": "query", + "description": "metadata selector - a comma separated list or a regular expression (returns all if no value given)", + "schema": { + "type": "string", + "default": ".*" + } + }, + { + "name": "recursive", + "in": "query", + "description": "get member items recursively", + "schema": { + "type": "boolean", + "default": false + } + }, + { + "name": "fields", + "in": "query", + "description": "limit output to the given fields (comma separated)", + "schema": { + "type": "string" + } + }, + { + "name": "staticDataOnly", + "in": "query", + "description": "provides a cacheable list of values not expected to change regularly and checks the If-Modified-Since header, all other parameters are ignored except \"metadata\"", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EnrichedItemDTO" + } + } + } + } + } + } + }, + "put": { + "tags": [ + "items" + ], + "summary": "Adds a list of items to the registry or updates the existing items.", + "operationId": "addOrUpdateItemsInRegistry", + "requestBody": { + "description": "array of item data", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GroupItemDTO" + } + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "type": "string" + } + } + } + }, + "400": { + "description": "Payload is invalid." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/items/{itemname}/state": { + "get": { + "tags": [ + "items" + ], + "summary": "Gets the state of an item.", + "operationId": "getItemState_1", + "parameters": [ + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + }, + "404": { + "description": "Item not found" + } + } + }, + "put": { + "tags": [ + "items" + ], + "summary": "Updates the state of an item.", + "operationId": "updateItemState", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + } + ], + "requestBody": { + "description": "valid item state (e.g. ON, OFF)", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "202": { + "description": "Accepted" + }, + "404": { + "description": "Item not found" + }, + "400": { + "description": "Item state null" + } + } + } + }, + "/items/{itemname}/metadata/namespaces": { + "get": { + "tags": [ + "items" + ], + "summary": "Gets the namespace of an item.", + "operationId": "getItemNamespaces", + "parameters": [ + { + "name": "itemname", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "404": { + "description": "Item not found" + } + } + } + }, + "/items/{itemName}/semantic/{semanticClass}": { + "get": { + "tags": [ + "items" + ], + "summary": "Gets the item which defines the requested semantics of an item.", + "operationId": "getSemanticItem", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "itemName", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "pattern": "\\w+", + "type": "string" + } + }, + { + "name": "semanticClass", + "in": "path", + "description": "semantic class", + "required": true, + "schema": { + "pattern": "\\w+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Item not found" + } + } + } + }, + "/items/metadata/purge": { + "post": { + "tags": [ + "items" + ], + "summary": "Remove unused/orphaned metadata.", + "operationId": "purgeDatabase", + "responses": { + "200": { + "description": "OK" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/links": { + "get": { + "tags": [ + "links" + ], + "summary": "Gets all available links.", + "operationId": "getItemLinks", + "parameters": [ + { + "name": "channelUID", + "in": "query", + "description": "filter by channel UID", + "schema": { + "type": "string" + } + }, + { + "name": "itemName", + "in": "query", + "description": "filter by item name", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EnrichedItemChannelLinkDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/links/{itemName}/{channelUID}": { + "get": { + "tags": [ + "links" + ], + "summary": "Retrieves an individual link.", + "operationId": "getItemLink", + "parameters": [ + { + "name": "itemName", + "in": "path", + "description": "item name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "channelUID", + "in": "path", + "description": "channel UID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnrichedItemChannelLinkDTO" + } + } + } + }, + "404": { + "description": "Content does not match the path" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "links" + ], + "summary": "Links an item to a channel.", + "operationId": "linkItemToChannel", + "parameters": [ + { + "name": "itemName", + "in": "path", + "description": "itemName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "channelUID", + "in": "path", + "description": "channelUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "link data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ItemChannelLinkDTO" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Content does not match the path" + }, + "405": { + "description": "Link is not editable" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "links" + ], + "summary": "Unlinks an item from a channel.", + "operationId": "unlinkItemFromChannel", + "parameters": [ + { + "name": "itemName", + "in": "path", + "description": "itemName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "channelUID", + "in": "path", + "description": "channelUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Link not found." + }, + "405": { + "description": "Link not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/links/orphans": { + "get": { + "tags": [ + "links" + ], + "summary": "Get orphan links between items and broken/non-existent thing channels", + "operationId": "getOrphanLinks", + "responses": { + "200": { + "description": "List of broken links" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/links/purge": { + "post": { + "tags": [ + "links" + ], + "summary": "Remove unused/orphaned links.", + "operationId": "purgeDatabase_1", + "responses": { + "200": { + "description": "OK" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/links/{object}": { + "delete": { + "tags": [ + "links" + ], + "summary": "Delete all links that refer to an item or thing.", + "operationId": "removeAllLinksForObject", + "parameters": [ + { + "name": "object", + "in": "path", + "description": "item name or thing UID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/persistence/{serviceId}": { + "get": { + "tags": [ + "persistence" + ], + "summary": "Gets a persistence service configuration.", + "operationId": "getPersistenceServiceConfiguration", + "parameters": [ + { + "name": "serviceId", + "in": "path", + "description": "Id of the persistence service.", + "required": true, + "schema": { + "pattern": "[a-zA-Z0-9]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersistenceServiceConfigurationDTO" + } + } + } + }, + "404": { + "description": "Service configuration not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "persistence" + ], + "summary": "Sets a persistence service configuration.", + "operationId": "putPersistenceServiceConfiguration", + "parameters": [ + { + "name": "serviceId", + "in": "path", + "description": "Id of the persistence service.", + "required": true, + "schema": { + "pattern": "[a-zA-Z0-9]+", + "type": "string" + } + } + ], + "requestBody": { + "description": "service configuration", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersistenceServiceConfigurationDTO" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersistenceServiceConfigurationDTO" + } + } + } + }, + "201": { + "description": "PersistenceServiceConfiguration created." + }, + "400": { + "description": "Payload invalid." + }, + "405": { + "description": "PersistenceServiceConfiguration not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "persistence" + ], + "summary": "Deletes a persistence service configuration.", + "operationId": "deletePersistenceServiceConfiguration", + "parameters": [ + { + "name": "serviceId", + "in": "path", + "description": "Id of the persistence service.", + "required": true, + "schema": { + "pattern": "[a-zA-Z0-9]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Persistence service configuration not found." + }, + "405": { + "description": "Persistence service configuration not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/persistence/items/{itemname}": { + "get": { + "tags": [ + "persistence" + ], + "summary": "Gets item persistence data from the persistence service.", + "operationId": "getItemDataFromPersistenceService", + "parameters": [ + { + "name": "serviceId", + "in": "query", + "description": "Id of the persistence service. If not provided the default service will be used", + "schema": { + "type": "string" + } + }, + { + "name": "itemname", + "in": "path", + "description": "The item name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "starttime", + "in": "query", + "description": "Start time of the data to return. Will default to 1 day before endtime. [yyyy-MM-dd\u0027T\u0027HH:mm:ss.SSSZ]", + "schema": { + "type": "string" + } + }, + { + "name": "endtime", + "in": "query", + "description": "End time of the data to return. Will default to current time. [yyyy-MM-dd\u0027T\u0027HH:mm:ss.SSSZ]", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "Page number of data to return. This parameter will enable paging.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "pagelength", + "in": "query", + "description": "The length of each page.", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "boundary", + "in": "query", + "description": "Gets one value before and after the requested period.", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ItemHistoryDTO" + } + } + } + }, + "404": { + "description": "Unknown Item or persistence service" + } + } + }, + "put": { + "tags": [ + "persistence" + ], + "summary": "Stores item persistence data into the persistence service.", + "operationId": "storeItemDataInPersistenceService", + "parameters": [ + { + "name": "serviceId", + "in": "query", + "description": "Id of the persistence service. If not provided the default service will be used", + "schema": { + "type": "string" + } + }, + { + "name": "itemname", + "in": "path", + "description": "The item name.", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "Time of the data to be stored. Will default to current time. [yyyy-MM-dd\u0027T\u0027HH:mm:ss.SSSZ]", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "state", + "in": "query", + "description": "The state to store.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Unknown Item or persistence service" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "persistence" + ], + "summary": "Deletes item persistence data from a specific persistence service in a given time range.", + "operationId": "deleteItemFromPersistenceService", + "parameters": [ + { + "name": "serviceId", + "in": "query", + "description": "Id of the persistence service.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "itemname", + "in": "path", + "description": "The item name.", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "starttime", + "in": "query", + "description": "Start of the time range to be deleted. [yyyy-MM-dd\u0027T\u0027HH:mm:ss.SSSZ]", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "endtime", + "in": "query", + "description": "End of the time range to be deleted. [yyyy-MM-dd\u0027T\u0027HH:mm:ss.SSSZ]", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "400": { + "description": "Invalid filter parameters" + }, + "404": { + "description": "Unknown persistence service" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/persistence/items": { + "get": { + "tags": [ + "persistence" + ], + "summary": "Gets a list of items available via a specific persistence service.", + "operationId": "getItemsForPersistenceService", + "parameters": [ + { + "name": "serviceId", + "in": "query", + "description": "Id of the persistence service. If not provided the default service will be used", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistenceItemInfo" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/persistence": { + "get": { + "tags": [ + "persistence" + ], + "summary": "Gets a list of persistence services.", + "operationId": "getPersistenceServices", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistenceServiceDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/profile-types": { + "get": { + "tags": [ + "profile-types" + ], + "summary": "Gets all available profile types.", + "operationId": "getProfileTypes", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "channelTypeUID", + "in": "query", + "description": "channel type filter", + "schema": { + "type": "string" + } + }, + { + "name": "itemType", + "in": "query", + "description": "item type filter", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/ProfileTypeDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/services/{serviceId}/config": { + "get": { + "tags": [ + "services" + ], + "summary": "Get service configuration for given service ID.", + "operationId": "getServiceConfig", + "parameters": [ + { + "name": "serviceId", + "in": "path", + "description": "service ID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "500": { + "description": "Configuration can not be read due to internal error" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "services" + ], + "summary": "Updates a service configuration for given service ID and returns the old configuration.", + "operationId": "updateServiceConfig", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "serviceId", + "in": "path", + "description": "service ID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "204": { + "description": "No old configuration" + }, + "500": { + "description": "Configuration can not be updated due to internal error" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "services" + ], + "summary": "Deletes a service configuration for given service ID and returns the old configuration.", + "operationId": "deleteServiceConfig", + "parameters": [ + { + "name": "serviceId", + "in": "path", + "description": "service ID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "204": { + "description": "No old configuration" + }, + "500": { + "description": "Configuration can not be deleted due to internal error" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/services": { + "get": { + "tags": [ + "services" + ], + "summary": "Get all configurable services.", + "operationId": "getServices", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigurableServiceDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/services/{serviceId}": { + "get": { + "tags": [ + "services" + ], + "summary": "Get configurable service for given service ID.", + "operationId": "getServicesById", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "serviceId", + "in": "path", + "description": "service ID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConfigurableServiceDTO" + } + } + } + }, + "404": { + "description": "Not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/services/{serviceId}/contexts": { + "get": { + "tags": [ + "services" + ], + "summary": "Get existing multiple context service configurations for the given factory PID.", + "operationId": "getServiceContext", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "serviceId", + "in": "path", + "description": "service ID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigurableServiceDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/tags": { + "get": { + "tags": [ + "tags" + ], + "summary": "Get all available semantic tags.", + "operationId": "getSemanticTags", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EnrichedSemanticTagDTO" + } + } + } + } + } + } + }, + "post": { + "tags": [ + "tags" + ], + "summary": "Creates a new semantic tag and adds it to the registry.", + "operationId": "createSemanticTag", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "tag data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnrichedSemanticTagDTO" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/EnrichedSemanticTagDTO" + } + } + } + }, + "400": { + "description": "The tag identifier is invalid or the tag label is missing." + }, + "409": { + "description": "A tag with the same identifier already exists." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/tags/{tagId}": { + "get": { + "tags": [ + "tags" + ], + "summary": "Gets a semantic tag and its sub tags.", + "operationId": "getSemanticTagAndSubTags", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "tagId", + "in": "path", + "description": "tag id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EnrichedSemanticTagDTO" + } + } + } + } + }, + "404": { + "description": "Semantic tag not found." + } + } + }, + "put": { + "tags": [ + "tags" + ], + "summary": "Updates a semantic tag.", + "operationId": "updateSemanticTag", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "tagId", + "in": "path", + "description": "tag id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "tag data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnrichedSemanticTagDTO" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/EnrichedSemanticTagDTO" + } + } + } + }, + "404": { + "description": "Semantic tag not found." + }, + "405": { + "description": "Semantic tag not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "tags" + ], + "summary": "Removes a semantic tag and its sub tags from the registry.", + "operationId": "removeSemanticTag", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "tagId", + "in": "path", + "description": "tag id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK, was deleted." + }, + "404": { + "description": "Semantic tag not found." + }, + "405": { + "description": "Semantic tag not removable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/things": { + "get": { + "tags": [ + "things" + ], + "summary": "Get all available things.", + "operationId": "getThings", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "summary", + "in": "query", + "description": "summary fields only", + "schema": { + "type": "boolean" + } + }, + { + "name": "staticDataOnly", + "in": "query", + "description": "provides a cacheable list of values not expected to change regularly and checks the If-Modified-Since header", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/EnrichedThingDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "post": { + "tags": [ + "things" + ], + "summary": "Creates a new thing and adds it to the registry.", + "operationId": "createThingInRegistry", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "thing data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThingDTO" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/EnrichedThingDTO" + } + } + } + }, + "400": { + "description": "A uid must be provided, if no binding can create a thing of this type." + }, + "409": { + "description": "A thing with the same uid already exists." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/things/{thingUID}": { + "get": { + "tags": [ + "things" + ], + "summary": "Gets thing by UID.", + "operationId": "getThingById", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnrichedThingDTO" + } + } + } + }, + "404": { + "description": "Thing not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "things" + ], + "summary": "Updates a thing.", + "operationId": "updateThing", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "thing", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThingDTO" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/EnrichedThingDTO" + } + } + } + }, + "404": { + "description": "Thing not found." + }, + "409": { + "description": "Thing could not be updated as it is not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "things" + ], + "summary": "Removes a thing from the registry. Set \u0027force\u0027 to __true__ if you want the thing to be removed immediately.", + "operationId": "removeThingById", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "force", + "in": "query", + "description": "force", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "OK, was deleted." + }, + "202": { + "description": "ACCEPTED for asynchronous deletion." + }, + "404": { + "description": "Thing not found." + }, + "409": { + "description": "Thing could not be deleted because it\u0027s not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/things/{thingUID}/config/status": { + "get": { + "tags": [ + "things" + ], + "summary": "Gets thing config status.", + "operationId": "getThingConfigStatus", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thing", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigStatusMessage" + } + } + } + } + }, + "404": { + "description": "Thing not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/things/{thingUID}/firmware/status": { + "get": { + "tags": [ + "things" + ], + "summary": "Gets thing\u0027s firmware status.", + "operationId": "getThingFirmwareStatus", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thing", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/FirmwareStatusDTO" + } + } + } + }, + "204": { + "description": "No firmware status provided by this Thing." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/things/{thingUID}/firmwares": { + "get": { + "tags": [ + "things" + ], + "summary": "Get all available firmwares for provided thing UID", + "operationId": "getAvailableFirmwaresForThing", + "parameters": [ + { + "name": "thingUID", + "in": "path", + "description": "thingUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/FirmwareDTO" + } + } + } + } + }, + "204": { + "description": "No firmwares found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/things/{thingUID}/status": { + "get": { + "tags": [ + "things" + ], + "summary": "Gets thing status.", + "operationId": "getThingStatus", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thing", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThingStatusInfo" + } + } + } + }, + "404": { + "description": "Thing not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/things/{thingUID}/enable": { + "put": { + "tags": [ + "things" + ], + "summary": "Sets the thing enabled status.", + "operationId": "enableThing", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thing", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "enabled", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/EnrichedThingDTO" + } + } + } + }, + "404": { + "description": "Thing not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/things/{thingUID}/config": { + "put": { + "tags": [ + "things" + ], + "summary": "Updates thing\u0027s configuration.", + "operationId": "updateThingConfig", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thing", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "configuration parameters", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/EnrichedThingDTO" + } + } + } + }, + "400": { + "description": "Configuration of the thing is not valid." + }, + "404": { + "description": "Thing not found" + }, + "409": { + "description": "Thing could not be updated as it is not editable." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/things/{thingUID}/firmware/{firmwareVersion}": { + "put": { + "tags": [ + "things" + ], + "summary": "Update thing firmware.", + "operationId": "updateThingFirmware", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "thingUID", + "in": "path", + "description": "thing", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "firmwareVersion", + "in": "path", + "description": "version", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Firmware update preconditions not satisfied." + }, + "404": { + "description": "Thing not found." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/thing-types": { + "get": { + "tags": [ + "thing-types" + ], + "summary": "Gets all available thing types without config description, channels and properties.", + "operationId": "getThingTypes", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "bindingId", + "in": "query", + "description": "filter by binding Id", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/StrippedThingTypeDTO" + } + } + } + } + } + } + } + }, + "/thing-types/{thingTypeUID}": { + "get": { + "tags": [ + "thing-types" + ], + "summary": "Gets thing type by UID.", + "operationId": "getThingTypeById", + "parameters": [ + { + "name": "thingTypeUID", + "in": "path", + "description": "thingTypeUID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Thing type with provided thingTypeUID does not exist.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThingTypeDTO" + } + } + } + }, + "404": { + "description": "No content" + } + } + } + }, + "/": { + "get": { + "tags": [ + "root" + ], + "summary": "Gets information about the runtime, the API version and links to resources.", + "operationId": "getRoot", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootBean" + } + } + } + } + } + } + }, + "/systeminfo": { + "get": { + "tags": [ + "systeminfo" + ], + "summary": "Gets information about the system.", + "operationId": "getSystemInformation", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SystemInfoBean" + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/systeminfo/uom": { + "get": { + "tags": [ + "systeminfo" + ], + "summary": "Get all supported dimensions and their system units.", + "operationId": "getUoMInformation", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UoMInfoBean" + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/sitemaps/events/subscribe": { + "post": { + "tags": [ + "sitemaps" + ], + "summary": "Creates a sitemap event subscription.", + "operationId": "createSitemapEventSubscription", + "responses": { + "201": { + "description": "Subscription created." + }, + "503": { + "description": "Subscriptions limit reached." + } + } + } + }, + "/sitemaps/{sitemapname}/{pageid}": { + "get": { + "tags": [ + "sitemaps" + ], + "summary": "Polls the data for one page of a sitemap.", + "operationId": "pollDataForPage", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "sitemapname", + "in": "path", + "description": "sitemap name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "pageid", + "in": "path", + "description": "page id", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "subscriptionid", + "in": "query", + "description": "subscriptionid", + "schema": { + "type": "string" + } + }, + { + "name": "includeHidden", + "in": "query", + "description": "include hidden widgets", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageDTO" + } + } + } + }, + "404": { + "description": "Sitemap with requested name does not exist or page does not exist, or page refers to a non-linkable widget" + }, + "400": { + "description": "Invalid subscription id has been provided." + } + } + } + }, + "/sitemaps/{sitemapname}/*": { + "get": { + "tags": [ + "sitemaps" + ], + "summary": "Polls the data for a whole sitemap. Not recommended due to potentially high traffic.", + "operationId": "pollDataForSitemap", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "sitemapname", + "in": "path", + "description": "sitemap name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "subscriptionid", + "in": "query", + "description": "subscriptionid", + "schema": { + "type": "string" + } + }, + { + "name": "includeHidden", + "in": "query", + "description": "include hidden widgets", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SitemapDTO" + } + } + } + }, + "404": { + "description": "Sitemap with requested name does not exist" + }, + "400": { + "description": "Invalid subscription id has been provided." + } + } + } + }, + "/sitemaps/{sitemapname}": { + "get": { + "tags": [ + "sitemaps" + ], + "summary": "Get sitemap by name.", + "operationId": "getSitemapByName", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "sitemapname", + "in": "path", + "description": "sitemap name", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + }, + { + "name": "type", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "jsoncallback", + "in": "query", + "schema": { + "type": "string", + "default": "callback" + } + }, + { + "name": "includeHidden", + "in": "query", + "description": "include hidden widgets", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SitemapDTO" + } + } + } + } + } + } + }, + "/sitemaps/events/{subscriptionid}/*": { + "get": { + "tags": [ + "sitemaps" + ], + "summary": "Get sitemap events for a whole sitemap. Not recommended due to potentially high traffic.", + "operationId": "getSitemapEvents", + "parameters": [ + { + "name": "subscriptionid", + "in": "path", + "description": "subscription id", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9-]+", + "type": "string" + } + }, + { + "name": "sitemap", + "in": "query", + "description": "sitemap name", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Missing sitemap parameter, or sitemap not linked successfully to the subscription." + }, + "404": { + "description": "Subscription not found." + } + } + } + }, + "/sitemaps/events/{subscriptionid}": { + "get": { + "tags": [ + "sitemaps" + ], + "summary": "Get sitemap events.", + "operationId": "getSitemapEvents_1", + "parameters": [ + { + "name": "subscriptionid", + "in": "path", + "description": "subscription id", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9-]+", + "type": "string" + } + }, + { + "name": "sitemap", + "in": "query", + "description": "sitemap name", + "schema": { + "type": "string" + } + }, + { + "name": "pageid", + "in": "query", + "description": "page id", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Missing sitemap or page parameter, or page not linked successfully to the subscription." + }, + "404": { + "description": "Subscription not found." + } + } + } + }, + "/sitemaps": { + "get": { + "tags": [ + "sitemaps" + ], + "summary": "Get all available sitemaps.", + "operationId": "getSitemaps", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SitemapDTO" + } + } + } + } + } + } + } + }, + "/events/states": { + "get": { + "tags": [ + "events" + ], + "summary": "Initiates a new item state tracker connection", + "operationId": "initNewStateTacker", + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/events": { + "get": { + "tags": [ + "events" + ], + "summary": "Get all events.", + "operationId": "getEvents", + "parameters": [ + { + "name": "topics", + "in": "query", + "description": "topics", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Topic is empty or contains invalid characters" + } + } + } + }, + "/events/states/{connectionId}": { + "post": { + "tags": [ + "events" + ], + "summary": "Changes the list of items a SSE connection will receive state updates to.", + "operationId": "updateItemListForStateUpdates", + "parameters": [ + { + "name": "connectionId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "items", + "content": { + "*/*": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Unknown connectionId" + } + } + } + }, + "/transformations/{uid}": { + "get": { + "tags": [ + "transformations" + ], + "summary": "Get a single transformation", + "operationId": "getTransformation", + "parameters": [ + { + "name": "uid", + "in": "path", + "description": "Transformation UID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Transformation" + } + } + } + }, + "404": { + "description": "Not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "transformations" + ], + "summary": "Put a single transformation", + "operationId": "putTransformation", + "parameters": [ + { + "name": "uid", + "in": "path", + "description": "Transformation UID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "transformation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TransformationDTO" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request (content missing or invalid)" + }, + "405": { + "description": "Transformation not editable" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "transformations" + ], + "summary": "Get a single transformation", + "operationId": "deleteTransformation", + "parameters": [ + { + "name": "uid", + "in": "path", + "description": "Transformation UID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "UID not found" + }, + "405": { + "description": "Transformation not editable" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/transformations/services": { + "get": { + "tags": [ + "transformations" + ], + "summary": "Get all transformation services", + "operationId": "getTransformationServices", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/transformations": { + "get": { + "tags": [ + "transformations" + ], + "summary": "Get a list of all transformations", + "operationId": "getTransformations", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TransformationDTO" + } + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/ui/components/{namespace}": { + "get": { + "tags": [ + "ui" + ], + "summary": "Get all registered UI components in the specified namespace.", + "operationId": "getRegisteredUIComponentsInNamespace", + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "summary", + "in": "query", + "description": "summary fields only", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RootUIComponent" + } + } + } + } + } + } + }, + "post": { + "tags": [ + "ui" + ], + "summary": "Add a UI component in the specified namespace.", + "operationId": "addUIComponentToNamespace", + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootUIComponent" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootUIComponent" + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/ui/components/{namespace}/{componentUID}": { + "get": { + "tags": [ + "ui" + ], + "summary": "Get a specific UI component in the specified namespace.", + "operationId": "getUIComponentInNamespace", + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "componentUID", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootUIComponent" + } + } + } + }, + "404": { + "description": "Component not found" + } + } + }, + "put": { + "tags": [ + "ui" + ], + "summary": "Update a specific UI component in the specified namespace.", + "operationId": "updateUIComponentInNamespace", + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "componentUID", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootUIComponent" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootUIComponent" + } + } + } + }, + "404": { + "description": "Component not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "ui" + ], + "summary": "Remove a specific UI component in the specified namespace.", + "operationId": "removeUIComponentFromNamespace", + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "componentUID", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Component not found" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/ui/tiles": { + "get": { + "tags": [ + "ui" + ], + "summary": "Get all registered UI tiles.", + "operationId": "getUITiles", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TileDTO" + } + } + } + } + } + } + } + }, + "/voice/defaultvoice": { + "get": { + "tags": [ + "voice" + ], + "summary": "Gets the default voice.", + "operationId": "getDefaultVoice", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VoiceDTO" + } + } + } + }, + "404": { + "description": "No default voice was found." + } + } + } + }, + "/voice/interpreters/{id}": { + "get": { + "tags": [ + "voice" + ], + "summary": "Gets a single interpreter.", + "operationId": "getVoiceInterpreterByUID", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "path", + "description": "interpreter id", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HumanLanguageInterpreterDTO" + } + } + } + } + }, + "404": { + "description": "Interpreter not found" + } + } + } + }, + "/voice/interpreters": { + "get": { + "tags": [ + "voice" + ], + "summary": "Get the list of all interpreters.", + "operationId": "getVoiceInterpreters", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HumanLanguageInterpreterDTO" + } + } + } + } + } + } + }, + "post": { + "tags": [ + "voice" + ], + "summary": "Sends a text to the default human language interpreter.", + "operationId": "interpretTextByDefaultInterpreter", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "text to interpret", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "No human language interpreter was found." + }, + "400": { + "description": "interpretation exception occurs" + } + } + } + }, + "/voice/voices": { + "get": { + "tags": [ + "voice" + ], + "summary": "Get the list of all voices.", + "operationId": "getVoices", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/VoiceDTO" + } + } + } + } + } + } + } + }, + "/voice/interpreters/{ids}": { + "post": { + "tags": [ + "voice" + ], + "summary": "Sends a text to a given human language interpreter(s).", + "operationId": "interpretText", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "ids", + "in": "path", + "description": "comma separated list of interpreter ids", + "required": true, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "requestBody": { + "description": "text to interpret", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "No human language interpreter was found." + }, + "400": { + "description": "interpretation exception occurs" + } + } + } + }, + "/voice/listenandanswer": { + "post": { + "tags": [ + "voice" + ], + "summary": "Executes a simple dialog sequence without keyword spotting for a given audio source.", + "operationId": "listenAndAnswer", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "sourceId", + "in": "query", + "description": "source ID", + "schema": { + "type": "string" + } + }, + { + "name": "sttId", + "in": "query", + "description": "Speech-to-Text ID", + "schema": { + "type": "string" + } + }, + { + "name": "ttsId", + "in": "query", + "description": "Text-to-Speech ID", + "schema": { + "type": "string" + } + }, + { + "name": "voiceId", + "in": "query", + "description": "voice ID", + "schema": { + "type": "string" + } + }, + { + "name": "hliIds", + "in": "query", + "description": "interpreter IDs", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "sinkId", + "in": "query", + "description": "audio sink ID", + "schema": { + "type": "string" + } + }, + { + "name": "listeningItem", + "in": "query", + "description": "listening item", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "One of the given ids is wrong." + }, + "400": { + "description": "Services are missing or language is not supported by services or dialog processing is already started for the audio source." + } + } + } + }, + "/voice/say": { + "post": { + "tags": [ + "voice" + ], + "summary": "Speaks a given text with a given voice through the given audio sink.", + "operationId": "textToSpeech", + "parameters": [ + { + "name": "voiceid", + "in": "query", + "description": "voice id", + "schema": { + "type": "string" + } + }, + { + "name": "sinkid", + "in": "query", + "description": "audio sink id", + "schema": { + "type": "string" + } + }, + { + "name": "volume", + "in": "query", + "description": "volume level", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "text to speak", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/voice/dialog/start": { + "post": { + "tags": [ + "voice" + ], + "summary": "Start dialog processing for a given audio source.", + "operationId": "startDialog", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "name": "sourceId", + "in": "query", + "description": "source ID", + "schema": { + "type": "string" + } + }, + { + "name": "ksId", + "in": "query", + "description": "keywork spotter ID", + "schema": { + "type": "string" + } + }, + { + "name": "sttId", + "in": "query", + "description": "Speech-to-Text ID", + "schema": { + "type": "string" + } + }, + { + "name": "ttsId", + "in": "query", + "description": "Text-to-Speech ID", + "schema": { + "type": "string" + } + }, + { + "name": "voiceId", + "in": "query", + "description": "voice ID", + "schema": { + "type": "string" + } + }, + { + "name": "hliIds", + "in": "query", + "description": "comma separated list of interpreter IDs", + "schema": { + "type": "string" + } + }, + { + "name": "sinkId", + "in": "query", + "description": "audio sink ID", + "schema": { + "type": "string" + } + }, + { + "name": "keyword", + "in": "query", + "description": "keyword", + "schema": { + "type": "string" + } + }, + { + "name": "listeningItem", + "in": "query", + "description": "listening item", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "One of the given ids is wrong." + }, + "400": { + "description": "Services are missing or language is not supported by services or dialog processing is already started for the audio source." + } + } + } + }, + "/voice/dialog/stop": { + "post": { + "tags": [ + "voice" + ], + "summary": "Stop dialog processing for a given audio source.", + "operationId": "stopDialog", + "parameters": [ + { + "name": "sourceId", + "in": "query", + "description": "source ID", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "No audio source was found." + }, + "400": { + "description": "No dialog processing is started for the audio source." + } + } + } + }, + "/logging/{loggerName}": { + "get": { + "tags": [ + "logging" + ], + "summary": "Get a single logger.", + "operationId": "getLogger", + "parameters": [ + { + "name": "loggerName", + "in": "path", + "description": "logger name", + "required": true, + "schema": { + "pattern": "[a-zA-Z0-9.]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LoggerInfo" + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "put": { + "tags": [ + "logging" + ], + "summary": "Modify or add logger", + "operationId": "putLogger", + "parameters": [ + { + "name": "loggerName", + "in": "path", + "description": "logger name", + "required": true, + "schema": { + "pattern": "[a-zA-Z0-9.]+", + "type": "string" + } + } + ], + "requestBody": { + "description": "logger", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LoggerInfo" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Payload is invalid." + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + }, + "delete": { + "tags": [ + "logging" + ], + "summary": "Remove a single logger.", + "operationId": "removeLogger", + "parameters": [ + { + "name": "loggerName", + "in": "path", + "description": "logger name", + "required": true, + "schema": { + "pattern": "[a-zA-Z0-9.]+", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/logging": { + "get": { + "tags": [ + "logging" + ], + "summary": "Get all loggers", + "operationId": "getLogger_1", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LoggerBean" + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "admin" + ] + } + ] + } + }, + "/iconsets": { + "get": { + "tags": [ + "iconsets" + ], + "summary": "Gets all icon sets.", + "operationId": "getIconSets", + "parameters": [ + { + "name": "Accept-Language", + "in": "header", + "description": "language", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IconSet" + } + } + } + } + } + } + } + }, + "/habpanel/gallery/{galleryName}/widgets": { + "get": { + "tags": [ + "habpanel" + ], + "summary": "Gets the list of widget gallery items.", + "operationId": "getGalleryWidgetList", + "parameters": [ + { + "name": "galleryName", + "in": "path", + "description": "gallery name e.g. \u0027community\u0027", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]*", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GalleryWidgetsListItem" + } + } + } + } + }, + "404": { + "description": "Unknown gallery" + } + } + } + }, + "/habpanel/gallery/{galleryName}/widgets/{id}": { + "get": { + "tags": [ + "habpanel" + ], + "summary": "Gets the details about a widget gallery item.", + "operationId": "getGalleryWidgetsItem", + "parameters": [ + { + "name": "galleryName", + "in": "path", + "description": "gallery name e.g. \u0027community\u0027", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]*", + "type": "string" + } + }, + { + "name": "id", + "in": "path", + "description": "id within the gallery", + "required": true, + "schema": { + "pattern": "[a-zA-Z_0-9]*", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GalleryItem" + } + } + } + }, + "404": { + "description": "Unknown gallery or gallery item not found" + } + } + } + } + }, + "components": { + "schemas": { + "ConfigDescriptionParameterDTO": { + "type": "object", + "properties": { + "context": { + "type": "string" + }, + "defaultValue": { + "type": "string" + }, + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "required": { + "type": "boolean" + }, + "type": { + "type": "string", + "enum": [ + "TEXT", + "INTEGER", + "DECIMAL", + "BOOLEAN" + ] + }, + "min": { + "type": "number" + }, + "max": { + "type": "number" + }, + "stepsize": { + "type": "number" + }, + "pattern": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + }, + "multiple": { + "type": "boolean" + }, + "multipleLimit": { + "type": "integer", + "format": "int32" + }, + "groupName": { + "type": "string" + }, + "advanced": { + "type": "boolean" + }, + "verify": { + "type": "boolean" + }, + "limitToOptions": { + "type": "boolean" + }, + "unit": { + "type": "string" + }, + "unitLabel": { + "type": "string" + }, + "options": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ParameterOptionDTO" + } + }, + "filterCriteria": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FilterCriteriaDTO" + } + } + } + }, + "FilterCriteriaDTO": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "ModuleTypeDTO": { + "type": "object", + "properties": { + "uid": { + "type": "string" + }, + "visibility": { + "type": "string", + "enum": [ + "VISIBLE", + "HIDDEN", + "EXPERT" + ] + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "configDescriptions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameterDTO" + } + } + } + }, + "ParameterOptionDTO": { + "type": "object", + "properties": { + "label": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "ActionDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "type": { + "type": "string" + }, + "inputs": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "ConditionDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "type": { + "type": "string" + }, + "inputs": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "RuleDTO": { + "type": "object", + "properties": { + "triggers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TriggerDTO" + } + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConditionDTO" + } + }, + "actions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ActionDTO" + } + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "configDescriptions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameterDTO" + } + }, + "templateUID": { + "type": "string" + }, + "uid": { + "type": "string" + }, + "name": { + "type": "string" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "visibility": { + "type": "string", + "enum": [ + "VISIBLE", + "HIDDEN", + "EXPERT" + ] + }, + "description": { + "type": "string" + } + } + }, + "TriggerDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "type": { + "type": "string" + } + } + }, + "EnrichedRuleDTO": { + "type": "object", + "properties": { + "triggers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TriggerDTO" + } + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConditionDTO" + } + }, + "actions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ActionDTO" + } + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "configDescriptions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameterDTO" + } + }, + "templateUID": { + "type": "string" + }, + "uid": { + "type": "string" + }, + "name": { + "type": "string" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "visibility": { + "type": "string", + "enum": [ + "VISIBLE", + "HIDDEN", + "EXPERT" + ] + }, + "description": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/RuleStatusInfo" + }, + "editable": { + "type": "boolean" + } + } + }, + "RuleStatusInfo": { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "UNINITIALIZED", + "INITIALIZING", + "IDLE", + "RUNNING" + ] + }, + "statusDetail": { + "type": "string", + "enum": [ + "NONE", + "HANDLER_MISSING_ERROR", + "HANDLER_INITIALIZING_ERROR", + "CONFIGURATION_ERROR", + "TEMPLATE_MISSING_ERROR", + "INVALID_RULE", + "DISABLED" + ] + }, + "description": { + "type": "string" + } + } + }, + "ModuleDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "type": { + "type": "string" + } + } + }, + "Action": { + "type": "object", + "properties": { + "inputs": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "typeUID": { + "type": "string" + }, + "configuration": { + "$ref": "#/components/schemas/Configuration" + }, + "id": { + "type": "string" + } + } + }, + "Condition": { + "type": "object", + "properties": { + "inputs": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "typeUID": { + "type": "string" + }, + "configuration": { + "$ref": "#/components/schemas/Configuration" + }, + "id": { + "type": "string" + } + } + }, + "ConfigDescriptionParameter": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "TEXT", + "INTEGER", + "DECIMAL", + "BOOLEAN" + ] + }, + "groupName": { + "type": "string" + }, + "pattern": { + "type": "string" + }, + "required": { + "type": "boolean" + }, + "readOnly": { + "type": "boolean" + }, + "multiple": { + "type": "boolean" + }, + "multipleLimit": { + "type": "integer", + "format": "int32" + }, + "unit": { + "type": "string" + }, + "unitLabel": { + "type": "string" + }, + "context": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "options": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ParameterOption" + } + }, + "filterCriteria": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FilterCriteria" + } + }, + "limitToOptions": { + "type": "boolean" + }, + "advanced": { + "type": "boolean" + }, + "minimum": { + "type": "number" + }, + "maximum": { + "type": "number" + }, + "stepSize": { + "type": "number" + }, + "verifyable": { + "type": "boolean" + }, + "default": { + "type": "string" + } + } + }, + "Configuration": { + "type": "object", + "properties": { + "properties": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + }, + "FilterCriteria": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "Module": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "typeUID": { + "type": "string" + }, + "configuration": { + "$ref": "#/components/schemas/Configuration" + }, + "id": { + "type": "string" + } + } + }, + "ParameterOption": { + "type": "object", + "properties": { + "label": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "Rule": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "visibility": { + "type": "string", + "enum": [ + "VISIBLE", + "HIDDEN", + "EXPERT" + ] + }, + "configurationDescriptions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameter" + } + }, + "templateUID": { + "type": "string" + }, + "triggers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Trigger" + } + }, + "uid": { + "type": "string" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "configuration": { + "$ref": "#/components/schemas/Configuration" + }, + "modules": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Module" + } + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Condition" + } + }, + "name": { + "type": "string" + }, + "actions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Action" + } + } + } + }, + "RuleExecution": { + "type": "object", + "properties": { + "date": { + "type": "string", + "format": "date-time" + }, + "rule": { + "$ref": "#/components/schemas/Rule" + } + } + }, + "Trigger": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "typeUID": { + "type": "string" + }, + "configuration": { + "$ref": "#/components/schemas/Configuration" + }, + "id": { + "type": "string" + } + } + }, + "Template": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "visibility": { + "type": "string", + "enum": [ + "VISIBLE", + "HIDDEN", + "EXPERT" + ] + }, + "uid": { + "type": "string" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "Input": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "required": { + "type": "boolean" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "reference": { + "type": "string" + }, + "defaultValue": { + "type": "string" + } + } + }, + "Output": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "reference": { + "type": "string" + }, + "defaultValue": { + "type": "string" + } + } + }, + "ThingActionDTO": { + "type": "object", + "properties": { + "actionUid": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "inputs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Input" + } + }, + "outputs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Output" + } + } + } + }, + "AudioSinkDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + } + } + }, + "AudioSourceDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + } + } + }, + "UserApiTokenDTO": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "createdTime": { + "type": "string", + "format": "date-time" + }, + "scope": { + "type": "string" + } + } + }, + "UserSessionDTO": { + "type": "object", + "properties": { + "sessionId": { + "type": "string" + }, + "createdTime": { + "type": "string", + "format": "date-time" + }, + "lastRefreshTime": { + "type": "string", + "format": "date-time" + }, + "clientId": { + "type": "string" + }, + "scope": { + "type": "string" + } + } + }, + "TokenResponseDTO": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "expires_in": { + "type": "integer", + "format": "int32" + }, + "refresh_token": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "user": { + "$ref": "#/components/schemas/UserDTO" + } + } + }, + "UserDTO": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "Addon": { + "type": "object", + "properties": { + "uid": { + "type": "string" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "version": { + "type": "string" + }, + "maturity": { + "type": "string" + }, + "compatible": { + "type": "boolean" + }, + "contentType": { + "type": "string" + }, + "link": { + "type": "string" + }, + "author": { + "type": "string" + }, + "verifiedAuthor": { + "type": "boolean" + }, + "installed": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "description": { + "type": "string" + }, + "detailedDescription": { + "type": "string" + }, + "configDescriptionURI": { + "type": "string" + }, + "keywords": { + "type": "string" + }, + "countries": { + "type": "array", + "items": { + "type": "string" + } + }, + "license": { + "type": "string" + }, + "connection": { + "type": "string" + }, + "backgroundColor": { + "type": "string" + }, + "imageLink": { + "type": "string" + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "loggerPackages": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "AddonType": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + } + } + }, + "ChannelTypeDTO": { + "type": "object", + "properties": { + "parameters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameterDTO" + } + }, + "parameterGroups": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameterGroupDTO" + } + }, + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "category": { + "type": "string" + }, + "itemType": { + "type": "string" + }, + "unitHint": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "stateDescription": { + "$ref": "#/components/schemas/StateDescription" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "UID": { + "type": "string" + }, + "advanced": { + "type": "boolean" + }, + "commandDescription": { + "$ref": "#/components/schemas/CommandDescription" + } + } + }, + "CommandDescription": { + "type": "object", + "properties": { + "commandOptions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CommandOption" + } + } + } + }, + "CommandOption": { + "type": "object", + "properties": { + "command": { + "type": "string" + }, + "label": { + "type": "string" + } + } + }, + "ConfigDescriptionParameterGroupDTO": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "context": { + "type": "string" + }, + "advanced": { + "type": "boolean" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + } + } + }, + "StateDescription": { + "type": "object", + "properties": { + "minimum": { + "type": "number" + }, + "maximum": { + "type": "number" + }, + "step": { + "type": "number" + }, + "pattern": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + }, + "options": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StateOption" + } + } + } + }, + "StateOption": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + } + }, + "ConfigDescriptionDTO": { + "type": "object", + "properties": { + "uri": { + "type": "string" + }, + "parameters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameterDTO" + } + }, + "parameterGroups": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameterGroupDTO" + } + } + } + }, + "DiscoveryResultDTO": { + "type": "object", + "properties": { + "bridgeUID": { + "type": "string" + }, + "flag": { + "type": "string", + "enum": [ + "NEW", + "IGNORED" + ] + }, + "label": { + "type": "string" + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "representationProperty": { + "type": "string" + }, + "thingUID": { + "type": "string" + }, + "thingTypeUID": { + "type": "string" + } + } + }, + "MetadataDTO": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "config": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + }, + "EnrichedItemDTO": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "label": { + "type": "string" + }, + "category": { + "type": "string" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "groupNames": { + "type": "array", + "items": { + "type": "string" + } + }, + "link": { + "type": "string" + }, + "state": { + "type": "string" + }, + "transformedState": { + "type": "string" + }, + "stateDescription": { + "$ref": "#/components/schemas/StateDescription" + }, + "unitSymbol": { + "type": "string" + }, + "commandDescription": { + "$ref": "#/components/schemas/CommandDescription" + }, + "metadata": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "editable": { + "type": "boolean" + } + } + }, + "GroupFunctionDTO": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "params": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "GroupItemDTO": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "label": { + "type": "string" + }, + "category": { + "type": "string" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "groupNames": { + "type": "array", + "items": { + "type": "string" + } + }, + "groupType": { + "type": "string" + }, + "function": { + "$ref": "#/components/schemas/GroupFunctionDTO" + } + } + }, + "EnrichedItemChannelLinkDTO": { + "type": "object", + "properties": { + "itemName": { + "type": "string" + }, + "channelUID": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "editable": { + "type": "boolean" + } + } + }, + "ItemChannelLinkDTO": { + "type": "object", + "properties": { + "itemName": { + "type": "string" + }, + "channelUID": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + }, + "HistoryDataBean": { + "type": "object", + "properties": { + "time": { + "type": "integer", + "format": "int64" + }, + "state": { + "type": "string" + } + } + }, + "ItemHistoryDTO": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "totalrecords": { + "type": "string" + }, + "datapoints": { + "type": "string" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HistoryDataBean" + } + } + } + }, + "PersistenceCronStrategyDTO": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "cronExpression": { + "type": "string" + } + } + }, + "PersistenceFilterDTO": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "number" + }, + "relative": { + "type": "boolean" + }, + "unit": { + "type": "string" + }, + "lower": { + "type": "number" + }, + "upper": { + "type": "number" + }, + "values": { + "type": "array", + "items": { + "type": "string" + } + }, + "inverted": { + "type": "boolean" + } + } + }, + "PersistenceItemConfigurationDTO": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "string" + } + }, + "strategies": { + "type": "array", + "items": { + "type": "string" + } + }, + "filters": { + "type": "array", + "items": { + "type": "string" + } + }, + "alias": { + "type": "string" + } + } + }, + "PersistenceServiceConfigurationDTO": { + "type": "object", + "properties": { + "serviceId": { + "type": "string" + }, + "configs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistenceItemConfigurationDTO" + } + }, + "defaults": { + "type": "array", + "items": { + "type": "string" + } + }, + "cronStrategies": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistenceCronStrategyDTO" + } + }, + "thresholdFilters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistenceFilterDTO" + } + }, + "timeFilters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistenceFilterDTO" + } + }, + "equalsFilters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistenceFilterDTO" + } + }, + "includeFilters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersistenceFilterDTO" + } + }, + "editable": { + "type": "boolean" + } + } + }, + "PersistenceItemInfo": { + "type": "object", + "properties": { + "earliest": { + "type": "string", + "format": "date-time" + }, + "latest": { + "type": "string", + "format": "date-time" + }, + "name": { + "type": "string" + }, + "count": { + "type": "integer", + "format": "int32" + } + } + }, + "PersistenceServiceDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "ProfileTypeDTO": { + "type": "object", + "properties": { + "uid": { + "type": "string" + }, + "label": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "supportedItemTypes": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "ConfigurableServiceDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "category": { + "type": "string" + }, + "configDescriptionURI": { + "type": "string" + }, + "multiple": { + "type": "boolean" + } + } + }, + "EnrichedSemanticTagDTO": { + "type": "object" + }, + "EnrichedChannelDTO": { + "type": "object", + "properties": { + "uid": { + "type": "string" + }, + "id": { + "type": "string" + }, + "channelTypeUID": { + "type": "string" + }, + "itemType": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "defaultTags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "autoUpdatePolicy": { + "type": "string" + }, + "linkedItems": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "EnrichedThingDTO": { + "type": "object", + "properties": { + "label": { + "type": "string" + }, + "bridgeUID": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "UID": { + "type": "string" + }, + "thingTypeUID": { + "type": "string" + }, + "location": { + "type": "string" + }, + "channels": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EnrichedChannelDTO" + } + }, + "statusInfo": { + "$ref": "#/components/schemas/ThingStatusInfo" + }, + "firmwareStatus": { + "$ref": "#/components/schemas/FirmwareStatusDTO" + }, + "editable": { + "type": "boolean" + } + } + }, + "FirmwareStatusDTO": { + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "updatableVersion": { + "type": "string" + } + } + }, + "ThingStatusInfo": { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "UNINITIALIZED", + "INITIALIZING", + "UNKNOWN", + "ONLINE", + "OFFLINE", + "REMOVING", + "REMOVED" + ] + }, + "statusDetail": { + "type": "string", + "enum": [ + "NONE", + "NOT_YET_READY", + "HANDLER_MISSING_ERROR", + "HANDLER_REGISTERING_ERROR", + "HANDLER_INITIALIZING_ERROR", + "HANDLER_CONFIGURATION_PENDING", + "CONFIGURATION_PENDING", + "COMMUNICATION_ERROR", + "CONFIGURATION_ERROR", + "BRIDGE_OFFLINE", + "FIRMWARE_UPDATING", + "DUTY_CYCLE", + "BRIDGE_UNINITIALIZED", + "GONE", + "DISABLED" + ] + }, + "description": { + "type": "string" + } + } + }, + "ChannelDTO": { + "type": "object", + "properties": { + "uid": { + "type": "string" + }, + "id": { + "type": "string" + }, + "channelTypeUID": { + "type": "string" + }, + "itemType": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "defaultTags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "autoUpdatePolicy": { + "type": "string" + } + } + }, + "ThingDTO": { + "type": "object", + "properties": { + "label": { + "type": "string" + }, + "bridgeUID": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "UID": { + "type": "string" + }, + "thingTypeUID": { + "type": "string" + }, + "location": { + "type": "string" + }, + "channels": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ChannelDTO" + } + } + } + }, + "ConfigStatusMessage": { + "type": "object", + "properties": { + "parameterName": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "INFORMATION", + "WARNING", + "ERROR", + "PENDING" + ] + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "integer", + "format": "int32" + } + } + }, + "FirmwareDTO": { + "type": "object", + "properties": { + "thingTypeUID": { + "type": "string" + }, + "vendor": { + "type": "string" + }, + "model": { + "type": "string" + }, + "modelRestricted": { + "type": "boolean" + }, + "description": { + "type": "string" + }, + "version": { + "type": "string" + }, + "changelog": { + "type": "string" + }, + "prerequisiteVersion": { + "type": "string" + } + } + }, + "StrippedThingTypeDTO": { + "type": "object", + "properties": { + "UID": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "category": { + "type": "string" + }, + "listed": { + "type": "boolean" + }, + "supportedBridgeTypeUIDs": { + "type": "array", + "items": { + "type": "string" + } + }, + "bridge": { + "type": "boolean" + } + } + }, + "ChannelDefinitionDTO": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "category": { + "type": "string" + }, + "stateDescription": { + "$ref": "#/components/schemas/StateDescription" + }, + "advanced": { + "type": "boolean" + }, + "typeUID": { + "type": "string" + } + } + }, + "ChannelGroupDefinitionDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "channels": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ChannelDefinitionDTO" + } + } + } + }, + "ThingTypeDTO": { + "type": "object", + "properties": { + "UID": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "category": { + "type": "string" + }, + "listed": { + "type": "boolean" + }, + "supportedBridgeTypeUIDs": { + "type": "array", + "items": { + "type": "string" + } + }, + "bridge": { + "type": "boolean" + }, + "channels": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ChannelDefinitionDTO" + } + }, + "channelGroups": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ChannelGroupDefinitionDTO" + } + }, + "configParameters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameterDTO" + } + }, + "parameterGroups": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigDescriptionParameterGroupDTO" + } + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "extensibleChannelTypeIds": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "Links": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, + "RootBean": { + "type": "object", + "properties": { + "version": { + "type": "string" + }, + "locale": { + "type": "string" + }, + "measurementSystem": { + "type": "string" + }, + "runtimeInfo": { + "$ref": "#/components/schemas/RuntimeInfo" + }, + "links": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Links" + } + } + } + }, + "RuntimeInfo": { + "type": "object", + "properties": { + "version": { + "type": "string" + }, + "buildString": { + "type": "string" + } + } + }, + "SystemInfo": { + "type": "object", + "properties": { + "configFolder": { + "type": "string" + }, + "userdataFolder": { + "type": "string" + }, + "logFolder": { + "type": "string" + }, + "javaVersion": { + "type": "string" + }, + "javaVendor": { + "type": "string" + }, + "javaVendorVersion": { + "type": "string" + }, + "osName": { + "type": "string" + }, + "osVersion": { + "type": "string" + }, + "osArchitecture": { + "type": "string" + }, + "availableProcessors": { + "type": "integer", + "format": "int32" + }, + "freeMemory": { + "type": "integer", + "format": "int64" + }, + "totalMemory": { + "type": "integer", + "format": "int64" + }, + "uptime": { + "type": "integer", + "format": "int64" + }, + "startLevel": { + "type": "integer", + "format": "int32" + } + } + }, + "SystemInfoBean": { + "type": "object", + "properties": { + "systemInfo": { + "$ref": "#/components/schemas/SystemInfo" + } + } + }, + "DimensionInfo": { + "type": "object", + "properties": { + "dimension": { + "type": "string" + }, + "systemUnit": { + "type": "string" + } + } + }, + "UoMInfo": { + "type": "object", + "properties": { + "dimensions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DimensionInfo" + } + } + } + }, + "UoMInfoBean": { + "type": "object", + "properties": { + "uomInfo": { + "$ref": "#/components/schemas/UoMInfo" + } + } + }, + "MappingDTO": { + "type": "object", + "properties": { + "row": { + "type": "integer", + "format": "int32" + }, + "column": { + "type": "integer", + "format": "int32" + }, + "command": { + "type": "string" + }, + "releaseCommand": { + "type": "string" + }, + "label": { + "type": "string" + }, + "icon": { + "type": "string" + } + } + }, + "PageDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "link": { + "type": "string" + }, + "parent": { + "$ref": "#/components/schemas/PageDTO" + }, + "leaf": { + "type": "boolean" + }, + "timeout": { + "type": "boolean" + }, + "widgets": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WidgetDTO" + } + } + } + }, + "WidgetDTO": { + "type": "object", + "properties": { + "widgetId": { + "type": "string" + }, + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "visibility": { + "type": "boolean" + }, + "label": { + "type": "string" + }, + "labelSource": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "staticIcon": { + "type": "boolean" + }, + "labelcolor": { + "type": "string" + }, + "valuecolor": { + "type": "string" + }, + "iconcolor": { + "type": "string" + }, + "pattern": { + "type": "string" + }, + "unit": { + "type": "string" + }, + "mappings": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MappingDTO" + } + }, + "switchSupport": { + "type": "boolean" + }, + "releaseOnly": { + "type": "boolean" + }, + "sendFrequency": { + "type": "integer", + "format": "int32" + }, + "refresh": { + "type": "integer", + "format": "int32" + }, + "height": { + "type": "integer", + "format": "int32" + }, + "minValue": { + "type": "number" + }, + "maxValue": { + "type": "number" + }, + "step": { + "type": "number" + }, + "inputHint": { + "type": "string" + }, + "url": { + "type": "string" + }, + "encoding": { + "type": "string" + }, + "service": { + "type": "string" + }, + "period": { + "type": "string" + }, + "yAxisDecimalPattern": { + "type": "string" + }, + "legend": { + "type": "boolean" + }, + "forceAsItem": { + "type": "boolean" + }, + "row": { + "type": "integer", + "format": "int32" + }, + "column": { + "type": "integer", + "format": "int32" + }, + "command": { + "type": "string" + }, + "releaseCommand": { + "type": "string" + }, + "stateless": { + "type": "boolean" + }, + "state": { + "type": "string" + }, + "item": { + "$ref": "#/components/schemas/EnrichedItemDTO" + }, + "linkedPage": { + "$ref": "#/components/schemas/PageDTO" + } + } + }, + "SitemapDTO": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "label": { + "type": "string" + }, + "link": { + "type": "string" + }, + "homepage": { + "$ref": "#/components/schemas/PageDTO" + } + } + }, + "Transformation": { + "type": "object", + "properties": { + "uid": { + "type": "string" + }, + "label": { + "type": "string" + }, + "type": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "TransformationDTO": { + "type": "object", + "properties": { + "uid": { + "type": "string" + }, + "label": { + "type": "string" + }, + "type": { + "type": "string" + }, + "configuration": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "editable": { + "type": "boolean" + } + } + }, + "RootUIComponent": { + "type": "object", + "properties": { + "component": { + "type": "string" + }, + "config": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "slots": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UIComponent" + } + } + }, + "uid": { + "type": "string" + }, + "tags": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + }, + "props": { + "$ref": "#/components/schemas/ConfigDescriptionDTO" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "type": { + "type": "string" + } + } + }, + "UIComponent": { + "type": "object", + "properties": { + "component": { + "type": "string" + }, + "config": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "type": { + "type": "string" + } + } + }, + "TileDTO": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "url": { + "type": "string" + }, + "overlay": { + "type": "string" + }, + "imageUrl": { + "type": "string" + } + } + }, + "VoiceDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "locale": { + "type": "string" + } + } + }, + "HumanLanguageInterpreterDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "locales": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "LoggerInfo": { + "type": "object", + "properties": { + "loggerName": { + "type": "string" + }, + "level": { + "type": "string" + } + } + }, + "LoggerBean": { + "type": "object", + "properties": { + "loggers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/LoggerInfo" + } + } + } + }, + "IconSet": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "formats": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string", + "enum": [ + "PNG", + "SVG" + ] + } + } + } + }, + "GalleryWidgetsListItem": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "likes": { + "type": "integer", + "format": "int32" + }, + "views": { + "type": "integer", + "format": "int32" + }, + "posts": { + "type": "integer", + "format": "int32" + }, + "imageUrl": { + "type": "string" + }, + "createdDate": { + "type": "string", + "format": "date-time" + } + } + }, + "GalleryItem": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "likes": { + "type": "integer", + "format": "int32" + }, + "views": { + "type": "integer", + "format": "int32" + }, + "posts": { + "type": "integer", + "format": "int32" + }, + "imageUrl": { + "type": "string" + }, + "author": { + "type": "string" + }, + "authorName": { + "type": "string" + }, + "authorAvatarUrl": { + "type": "string" + }, + "createdDate": { + "type": "string", + "format": "date-time" + }, + "updatedDate": { + "type": "string", + "format": "date-time" + }, + "readme": { + "type": "string" + } + } + } + }, + "securitySchemes": { + "oauth2": { + "type": "oauth2", + "flows": { + "authorizationCode": { + "authorizationUrl": "/auth/authorize", + "tokenUrl": "/rest/auth/token", + "scopes": { + "admin": "Administration operations" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift index 9241caa9..744e885e 100644 --- a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift +++ b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift @@ -66,7 +66,7 @@ class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableO var legend: Bool? var encoding = "" @Published var item: OpenHABItem? - var linkedPage: OpenHABSitemapPage? + var linkedPage: OpenHABPage? var mappings: [OpenHABWidgetMapping] = [] var image: UIImage? var widgets: [ObservableOpenHABWidget] = [] @@ -212,7 +212,7 @@ class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableO extension ObservableOpenHABWidget { // This is an ugly initializer - convenience init(widgetId: String, label: String, icon: String, type: String, url: String?, period: String?, minValue: Double?, maxValue: Double?, step: Double?, refresh: Int?, height: Double?, isLeaf: Bool?, iconColor: String?, labelColor: String?, valueColor: String?, service: String?, state: String?, text: String?, legend: Bool?, encoding: String?, item: OpenHABItem?, linkedPage: OpenHABSitemapPage?, mappings: [OpenHABWidgetMapping], widgets: [ObservableOpenHABWidget], forceAsItem: Bool?) { + convenience init(widgetId: String, label: String, icon: String, type: String, url: String?, period: String?, minValue: Double?, maxValue: Double?, step: Double?, refresh: Int?, height: Double?, isLeaf: Bool?, iconColor: String?, labelColor: String?, valueColor: String?, service: String?, state: String?, text: String?, legend: Bool?, encoding: String?, item: OpenHABItem?, linkedPage: OpenHABPage?, mappings: [OpenHABWidgetMapping], widgets: [ObservableOpenHABWidget], forceAsItem: Bool?) { self.init() id = widgetId @@ -281,7 +281,7 @@ extension ObservableOpenHABWidget { let encoding: String? let groupType: String? let item: OpenHABItem.CodingData? - let linkedPage: OpenHABSitemapPage.CodingData? + let linkedPage: OpenHABPage.CodingData? let mappings: [OpenHABWidgetMapping] let widgets: [ObservableOpenHABWidget.CodingData] let forceAsItem: Bool? diff --git a/openHABWatch Extension/openHABWatch Extension/UserData.swift b/openHABWatch Extension/openHABWatch Extension/UserData.swift index adb06236..6923ab3a 100644 --- a/openHABWatch Extension/openHABWatch Extension/UserData.swift +++ b/openHABWatch Extension/openHABWatch Extension/UserData.swift @@ -16,15 +16,6 @@ import OpenHABCore import os.log import SwiftUI -// swiftlint:disable:next file_types_order -extension OpenHABCore.Future where Value == ObservableOpenHABSitemapPage.CodingData { - func trafo() -> OpenHABCore.Future { - transformed { data in - data.openHABSitemapPage - } - } -} - final class UserData: ObservableObject { @Published var widgets: [ObservableOpenHABWidget] = [] @Published var showAlert = false @@ -99,44 +90,6 @@ final class UserData: ObservableObject { refreshUrl() } - func request(_ endpoint: Endpoint) -> OpenHABCore.Future { - // Start by constructing a Promise, that will later be - // returned as a Future - let promise = Promise() - - // Immediately reject the promise in case the passed - // endpoint can't be converted into a valid URL - guard let url = endpoint.url else { - promise.reject(with: NetworkingError.invalidURL) - return promise - } - - if currentPageOperation != nil { - currentPageOperation?.cancel() - currentPageOperation = nil - } - - currentPageOperation = NetworkConnection.page( - url: url, - longPolling: true - ) { [weak self] response in - guard self != nil else { return } - - switch response.result { - case let .success(data): - os_log("openHAB 2", log: OSLog.remoteAccess, type: .info) - promise.resolve(with: data) - - case let .failure(error): - os_log("On LoadPage %{PUBLIC}@ code: %d ", log: .remoteAccess, type: .error, error.localizedDescription, response.response?.statusCode ?? 0) - promise.reject(with: error) - } - } - currentPageOperation?.resume() - - return promise - } - func loadPage(url: URL?, longPolling: Bool, refresh: Bool) { @@ -205,20 +158,6 @@ final class UserData: ObservableObject { tracker?.selectUrl() } } - - func loadPage(_ endpoint: Endpoint) { - request(endpoint) - .decoded(as: ObservableOpenHABSitemapPage.CodingData.self) - .trafo() - .observe { result in - switch result { - case let .failure(error): - os_log("On LoadPage %{PUBLIC}@", log: .remoteAccess, type: .error, error.localizedDescription) - case let .success(page): - self.openHABSitemapPage = page - } - } - } } extension UserData: OpenHABWatchTrackerDelegate { From c96ec85238722a097a96833d59465dbbeb9a9ec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=BCller-Seydlitz?= Date: Fri, 16 Aug 2024 21:15:05 +0200 Subject: [PATCH 03/13] Manually modifying openapi - JerseyResponseBuilderDTO for response to create event subscription, Allowing for X-Atmosphere-Transport for long-polling, SitemapWidgetEvent for server side events Experimenting with SSE consumption Include Client and Types to make it compile on github Shifted logging to dedicated ClientMiddleware Created class OpenHABSitemapWidgetEvent Modified openapi to include sitemapName and pageId in SitemapWidgetEvent Getting server sent events working - establishing a subscription and receiving events , not yet consuming / Commented out in OpenHABSitemapViewController --- .gitignore | 3 +- .../GeneratedSources/openapi/Client.swift | 1967 +++++ .../GeneratedSources/openapi/Types.swift | 7295 +++++++++++++++++ .../Sources/OpenHABCore/Model/APIActor.swift | 169 +- .../OpenHABCore/Model/LoggingMiddleware.swift | 115 + .../OpenHABCore/Model/OpenHABItem.swift | 2 +- .../Sources/OpenHABCore/openapi/openapi.json | 107 +- .../OpenHABDrawerTableViewController.swift | 25 +- openHAB/OpenHABSitemapViewController.swift | 25 +- openHAB/OpenHABWebViewController.swift | 1 - 10 files changed, 9647 insertions(+), 62 deletions(-) create mode 100644 OpenHABCore/Sources/OpenHABCore/GeneratedSources/openapi/Client.swift create mode 100644 OpenHABCore/Sources/OpenHABCore/GeneratedSources/openapi/Types.swift create mode 100644 OpenHABCore/Sources/OpenHABCore/Model/LoggingMiddleware.swift diff --git a/.gitignore b/.gitignore index 92c6fa79..5999bc48 100644 --- a/.gitignore +++ b/.gitignore @@ -18,5 +18,6 @@ build/ BuildTools/.build OpenHABCore/Package.resolved -OpenHABCore/Sources/OpenHABCore/GeneratedSources + +#OpenHABCore/Sources/OpenHABCore/GeneratedSources OpenHABCore/swift-openapi-generator diff --git a/OpenHABCore/Sources/OpenHABCore/GeneratedSources/openapi/Client.swift b/OpenHABCore/Sources/OpenHABCore/GeneratedSources/openapi/Client.swift new file mode 100644 index 00000000..9f0f22bf --- /dev/null +++ b/OpenHABCore/Sources/OpenHABCore/GeneratedSources/openapi/Client.swift @@ -0,0 +1,1967 @@ +// Copyright (c) 2010-2024 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +// Generated by swift-openapi-generator, do not modify. +@_spi(Generated) import OpenAPIRuntime +#if os(Linux) +@preconcurrency import struct Foundation.Data +@preconcurrency import struct Foundation.Date +@preconcurrency import struct Foundation.URL +#else +import struct Foundation.Data +import struct Foundation.Date +import struct Foundation.URL +#endif +import HTTPTypes + +struct Client: APIProtocol { + /// The underlying HTTP client. + private let client: UniversalClient + /// Creates a new client. + /// - Parameters: + /// - serverURL: The server URL that the client connects to. Any server + /// URLs defined in the OpenAPI document are available as static methods + /// on the ``Servers`` type. + /// - configuration: A set of configuration values for the client. + /// - transport: A transport that performs HTTP operations. + /// - middlewares: A list of middlewares to call before the transport. + init(serverURL: Foundation.URL, + configuration: Configuration = .init(), + transport: any ClientTransport, + middlewares: [any ClientMiddleware] = []) { + client = .init( + serverURL: serverURL, + configuration: configuration, + transport: transport, + middlewares: middlewares + ) + } + + private var converter: Converter { + client.converter + } + + /// Adds a new member to a group item. + /// + /// - Remark: HTTP `PUT /items/{itemName}/members/{memberItemName}`. + /// - Remark: Generated from `#/paths//items/{itemName}/members/{memberItemName}/put(addMemberToGroupItem)`. + func addMemberToGroupItem(_ input: Operations.addMemberToGroupItem.Input) async throws -> Operations.addMemberToGroupItem.Output { + try await client.send( + input: input, + forOperation: Operations.addMemberToGroupItem.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/items/{}/members/{}", + parameters: [ + input.path.itemName, + input.path.memberItemName + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .put + ) + suppressMutabilityWarning(&request) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + .ok(.init()) + case 404: + .notFound(.init()) + case 405: + .methodNotAllowed(.init()) + default: + .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Removes an existing member from a group item. + /// + /// - Remark: HTTP `DELETE /items/{itemName}/members/{memberItemName}`. + /// - Remark: Generated from `#/paths//items/{itemName}/members/{memberItemName}/delete(removeMemberFromGroupItem)`. + func removeMemberFromGroupItem(_ input: Operations.removeMemberFromGroupItem.Input) async throws -> Operations.removeMemberFromGroupItem.Output { + try await client.send( + input: input, + forOperation: Operations.removeMemberFromGroupItem.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/items/{}/members/{}", + parameters: [ + input.path.itemName, + input.path.memberItemName + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .delete + ) + suppressMutabilityWarning(&request) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + .ok(.init()) + case 404: + .notFound(.init()) + case 405: + .methodNotAllowed(.init()) + default: + .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Adds metadata to an item. + /// + /// - Remark: HTTP `PUT /items/{itemname}/metadata/{namespace}`. + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/put(addMetadataToItem)`. + func addMetadataToItem(_ input: Operations.addMetadataToItem.Input) async throws -> Operations.addMetadataToItem.Output { + try await client.send( + input: input, + forOperation: Operations.addMetadataToItem.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/items/{}/metadata/{}", + parameters: [ + input.path.itemname, + input.path.namespace + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .put + ) + suppressMutabilityWarning(&request) + let body: OpenAPIRuntime.HTTPBody? = switch input.body { + case let .json(value): + try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + .ok(.init()) + case 201: + .created(.init()) + case 400: + .badRequest(.init()) + case 404: + .notFound(.init()) + case 405: + .methodNotAllowed(.init()) + default: + .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Removes metadata from an item. + /// + /// - Remark: HTTP `DELETE /items/{itemname}/metadata/{namespace}`. + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/delete(removeMetadataFromItem)`. + func removeMetadataFromItem(_ input: Operations.removeMetadataFromItem.Input) async throws -> Operations.removeMetadataFromItem.Output { + try await client.send( + input: input, + forOperation: Operations.removeMetadataFromItem.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/items/{}/metadata/{}", + parameters: [ + input.path.itemname, + input.path.namespace + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .delete + ) + suppressMutabilityWarning(&request) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + .ok(.init()) + case 404: + .notFound(.init()) + case 405: + .methodNotAllowed(.init()) + default: + .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Adds a tag to an item. + /// + /// - Remark: HTTP `PUT /items/{itemname}/tags/{tag}`. + /// - Remark: Generated from `#/paths//items/{itemname}/tags/{tag}/put(addTagToItem)`. + func addTagToItem(_ input: Operations.addTagToItem.Input) async throws -> Operations.addTagToItem.Output { + try await client.send( + input: input, + forOperation: Operations.addTagToItem.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/items/{}/tags/{}", + parameters: [ + input.path.itemname, + input.path.tag + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .put + ) + suppressMutabilityWarning(&request) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + .ok(.init()) + case 404: + .notFound(.init()) + case 405: + .methodNotAllowed(.init()) + default: + .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Removes a tag from an item. + /// + /// - Remark: HTTP `DELETE /items/{itemname}/tags/{tag}`. + /// - Remark: Generated from `#/paths//items/{itemname}/tags/{tag}/delete(removeTagFromItem)`. + func removeTagFromItem(_ input: Operations.removeTagFromItem.Input) async throws -> Operations.removeTagFromItem.Output { + try await client.send( + input: input, + forOperation: Operations.removeTagFromItem.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/items/{}/tags/{}", + parameters: [ + input.path.itemname, + input.path.tag + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .delete + ) + suppressMutabilityWarning(&request) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + .ok(.init()) + case 404: + .notFound(.init()) + case 405: + .methodNotAllowed(.init()) + default: + .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Gets a single item. + /// + /// - Remark: HTTP `GET /items/{itemname}`. + /// - Remark: Generated from `#/paths//items/{itemname}/get(getItemByName)`. + func getItemByName(_ input: Operations.getItemByName.Input) async throws -> Operations.getItemByName.Output { + try await client.send( + input: input, + forOperation: Operations.getItemByName.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/items/{}", + parameters: [ + input.path.itemname + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Accept-Language", + value: input.headers.Accept_hyphen_Language + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "metadata", + value: input.query.metadata + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "recursive", + value: input.query.recursive + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.getItemByName.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.EnrichedItemDTO.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 404: + return .notFound(.init()) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Sends a command to an item. + /// + /// - Remark: HTTP `POST /items/{itemname}`. + /// - Remark: Generated from `#/paths//items/{itemname}/post(sendItemCommand)`. + func sendItemCommand(_ input: Operations.sendItemCommand.Input) async throws -> Operations.sendItemCommand.Output { + try await client.send( + input: input, + forOperation: Operations.sendItemCommand.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/items/{}", + parameters: [ + input.path.itemname + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + let body: OpenAPIRuntime.HTTPBody? = switch input.body { + case let .plainText(value): + try converter.setRequiredRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "text/plain" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + .ok(.init()) + case 400: + .badRequest(.init()) + case 404: + .notFound(.init()) + default: + .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Adds a new item to the registry or updates the existing item. + /// + /// - Remark: HTTP `PUT /items/{itemname}`. + /// - Remark: Generated from `#/paths//items/{itemname}/put(addOrUpdateItemInRegistry)`. + func addOrUpdateItemInRegistry(_ input: Operations.addOrUpdateItemInRegistry.Input) async throws -> Operations.addOrUpdateItemInRegistry.Output { + try await client.send( + input: input, + forOperation: Operations.addOrUpdateItemInRegistry.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/items/{}", + parameters: [ + input.path.itemname + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .put + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Accept-Language", + value: input.headers.Accept_hyphen_Language + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? = switch input.body { + case let .json(value): + try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.addOrUpdateItemInRegistry.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "*/*" + ] + ) + switch chosenContentType { + case "*/*": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .any(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 201: + return .created(.init()) + case 400: + return .badRequest(.init()) + case 404: + return .notFound(.init()) + case 405: + return .methodNotAllowed(.init()) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Removes an item from the registry. + /// + /// - Remark: HTTP `DELETE /items/{itemname}`. + /// - Remark: Generated from `#/paths//items/{itemname}/delete(removeItemFromRegistry)`. + func removeItemFromRegistry(_ input: Operations.removeItemFromRegistry.Input) async throws -> Operations.removeItemFromRegistry.Output { + try await client.send( + input: input, + forOperation: Operations.removeItemFromRegistry.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/items/{}", + parameters: [ + input.path.itemname + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .delete + ) + suppressMutabilityWarning(&request) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + .ok(.init()) + case 404: + .notFound(.init()) + default: + .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Get all available items. + /// + /// - Remark: HTTP `GET /items`. + /// - Remark: Generated from `#/paths//items/get(getItems)`. + func getItems(_ input: Operations.getItems.Input) async throws -> Operations.getItems.Output { + try await client.send( + input: input, + forOperation: Operations.getItems.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/items", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Accept-Language", + value: input.headers.Accept_hyphen_Language + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "type", + value: input.query._type + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "tags", + value: input.query.tags + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "metadata", + value: input.query.metadata + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "recursive", + value: input.query.recursive + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "fields", + value: input.query.fields + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "staticDataOnly", + value: input.query.staticDataOnly + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.getItems.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + [Components.Schemas.EnrichedItemDTO].self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Adds a list of items to the registry or updates the existing items. + /// + /// - Remark: HTTP `PUT /items`. + /// - Remark: Generated from `#/paths//items/put(addOrUpdateItemsInRegistry)`. + func addOrUpdateItemsInRegistry(_ input: Operations.addOrUpdateItemsInRegistry.Input) async throws -> Operations.addOrUpdateItemsInRegistry.Output { + try await client.send( + input: input, + forOperation: Operations.addOrUpdateItemsInRegistry.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/items", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .put + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? = switch input.body { + case let .json(value): + try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.addOrUpdateItemsInRegistry.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "*/*" + ] + ) + switch chosenContentType { + case "*/*": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .any(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 400: + return .badRequest(.init()) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Gets the state of an item. + /// + /// - Remark: HTTP `GET /items/{itemname}/state`. + /// - Remark: Generated from `#/paths//items/{itemname}/state/get(getItemState_1)`. + func getItemState_1(_ input: Operations.getItemState_1.Input) async throws -> Operations.getItemState_1.Output { + try await client.send( + input: input, + forOperation: Operations.getItemState_1.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/items/{}/state", + parameters: [ + input.path.itemname + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.getItemState_1.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "text/plain" + ] + ) + switch chosenContentType { + case "text/plain": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .plainText(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 404: + return .notFound(.init()) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Updates the state of an item. + /// + /// - Remark: HTTP `PUT /items/{itemname}/state`. + /// - Remark: Generated from `#/paths//items/{itemname}/state/put(updateItemState)`. + func updateItemState(_ input: Operations.updateItemState.Input) async throws -> Operations.updateItemState.Output { + try await client.send( + input: input, + forOperation: Operations.updateItemState.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/items/{}/state", + parameters: [ + input.path.itemname + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .put + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Accept-Language", + value: input.headers.Accept_hyphen_Language + ) + let body: OpenAPIRuntime.HTTPBody? = switch input.body { + case let .plainText(value): + try converter.setRequiredRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "text/plain" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 202: + .accepted(.init()) + case 400: + .badRequest(.init()) + case 404: + .notFound(.init()) + default: + .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Gets the namespace of an item. + /// + /// - Remark: HTTP `GET /items/{itemname}/metadata/namespaces`. + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/namespaces/get(getItemNamespaces)`. + func getItemNamespaces(_ input: Operations.getItemNamespaces.Input) async throws -> Operations.getItemNamespaces.Output { + try await client.send( + input: input, + forOperation: Operations.getItemNamespaces.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/items/{}/metadata/namespaces", + parameters: [ + input.path.itemname + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Accept-Language", + value: input.headers.Accept_hyphen_Language + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.getItemNamespaces.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Swift.String.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 404: + return .notFound(.init()) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Gets the item which defines the requested semantics of an item. + /// + /// - Remark: HTTP `GET /items/{itemName}/semantic/{semanticClass}`. + /// - Remark: Generated from `#/paths//items/{itemName}/semantic/{semanticClass}/get(getSemanticItem)`. + func getSemanticItem(_ input: Operations.getSemanticItem.Input) async throws -> Operations.getSemanticItem.Output { + try await client.send( + input: input, + forOperation: Operations.getSemanticItem.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/items/{}/semantic/{}", + parameters: [ + input.path.itemName, + input.path.semanticClass + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Accept-Language", + value: input.headers.Accept_hyphen_Language + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + .ok(.init()) + case 404: + .notFound(.init()) + default: + .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Remove unused/orphaned metadata. + /// + /// - Remark: HTTP `POST /items/metadata/purge`. + /// - Remark: Generated from `#/paths//items/metadata/purge/post(purgeDatabase)`. + func purgeDatabase(_ input: Operations.purgeDatabase.Input) async throws -> Operations.purgeDatabase.Output { + try await client.send( + input: input, + forOperation: Operations.purgeDatabase.id, + serializer: { _ in + let path = try converter.renderedPath( + template: "/items/metadata/purge", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + .ok(.init()) + default: + .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Creates a sitemap event subscription. + /// + /// - Remark: HTTP `POST /sitemaps/events/subscribe`. + /// - Remark: Generated from `#/paths//sitemaps/events/subscribe/post(createSitemapEventSubscription)`. + func createSitemapEventSubscription(_ input: Operations.createSitemapEventSubscription.Input) async throws -> Operations.createSitemapEventSubscription.Output { + try await client.send( + input: input, + forOperation: Operations.createSitemapEventSubscription.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/sitemaps/events/subscribe", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 201: + return .created(.init()) + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.createSitemapEventSubscription.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.JerseyResponseBuilderDTO.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 503: + return .serviceUnavailable(.init()) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Polls the data for one page of a sitemap. + /// + /// - Remark: HTTP `GET /sitemaps/{sitemapname}/{pageid}`. + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/{pageid}/get(pollDataForPage)`. + func pollDataForPage(_ input: Operations.pollDataForPage.Input) async throws -> Operations.pollDataForPage.Output { + try await client.send( + input: input, + forOperation: Operations.pollDataForPage.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/sitemaps/{}/{}", + parameters: [ + input.path.sitemapname, + input.path.pageid + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Accept-Language", + value: input.headers.Accept_hyphen_Language + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "X-Atmosphere-Transport", + value: input.headers.X_hyphen_Atmosphere_hyphen_Transport + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "subscriptionid", + value: input.query.subscriptionid + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "includeHidden", + value: input.query.includeHidden + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.pollDataForPage.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.PageDTO.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 400: + return .badRequest(.init()) + case 404: + return .notFound(.init()) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Polls the data for a whole sitemap. Not recommended due to potentially high traffic. + /// + /// - Remark: HTTP `GET /sitemaps/{sitemapname}/*`. + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/*/get(pollDataForSitemap)`. + func pollDataForSitemap(_ input: Operations.pollDataForSitemap.Input) async throws -> Operations.pollDataForSitemap.Output { + try await client.send( + input: input, + forOperation: Operations.pollDataForSitemap.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/sitemaps/{}/*", + parameters: [ + input.path.sitemapname + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Accept-Language", + value: input.headers.Accept_hyphen_Language + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "X-Atmosphere-Transport", + value: input.headers.X_hyphen_Atmosphere_hyphen_Transport + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "subscriptionid", + value: input.query.subscriptionid + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "includeHidden", + value: input.query.includeHidden + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.pollDataForSitemap.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.SitemapDTO.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 400: + return .badRequest(.init()) + case 404: + return .notFound(.init()) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Get sitemap by name. + /// + /// - Remark: HTTP `GET /sitemaps/{sitemapname}`. + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/get(getSitemapByName)`. + func getSitemapByName(_ input: Operations.getSitemapByName.Input) async throws -> Operations.getSitemapByName.Output { + try await client.send( + input: input, + forOperation: Operations.getSitemapByName.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/sitemaps/{}", + parameters: [ + input.path.sitemapname + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Accept-Language", + value: input.headers.Accept_hyphen_Language + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "type", + value: input.query._type + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "jsoncallback", + value: input.query.jsoncallback + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "includeHidden", + value: input.query.includeHidden + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.getSitemapByName.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.SitemapDTO.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Get sitemap events for a whole sitemap. Not recommended due to potentially high traffic. + /// + /// - Remark: HTTP `GET /sitemaps/events/{subscriptionid}/*`. + /// - Remark: Generated from `#/paths//sitemaps/events/{subscriptionid}/*/get(getSitemapEvents)`. + func getSitemapEvents(_ input: Operations.getSitemapEvents.Input) async throws -> Operations.getSitemapEvents.Output { + try await client.send( + input: input, + forOperation: Operations.getSitemapEvents.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/sitemaps/events/{}/*", + parameters: [ + input.path.subscriptionid + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "sitemap", + value: input.query.sitemap + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + .ok(.init()) + case 400: + .badRequest(.init()) + case 404: + .notFound(.init()) + default: + .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Get sitemap events. + /// + /// - Remark: HTTP `GET /sitemaps/events/{subscriptionid}`. + /// - Remark: Generated from `#/paths//sitemaps/events/{subscriptionid}/get(getSitemapEvents_1)`. + func getSitemapEvents_1(_ input: Operations.getSitemapEvents_1.Input) async throws -> Operations.getSitemapEvents_1.Output { + try await client.send( + input: input, + forOperation: Operations.getSitemapEvents_1.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/sitemaps/events/{}", + parameters: [ + input.path.subscriptionid + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "sitemap", + value: input.query.sitemap + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "pageid", + value: input.query.pageid + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.getSitemapEvents_1.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "text/event-stream", + "application/json" + ] + ) + switch chosenContentType { + case "text/event-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .text_event_hyphen_stream(value) + } + ) + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.SitemapWidgetEvent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 400: + return .badRequest(.init()) + case 404: + return .notFound(.init()) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Get all available sitemaps. + /// + /// - Remark: HTTP `GET /sitemaps`. + /// - Remark: Generated from `#/paths//sitemaps/get(getSitemaps)`. + func getSitemaps(_ input: Operations.getSitemaps.Input) async throws -> Operations.getSitemaps.Output { + try await client.send( + input: input, + forOperation: Operations.getSitemaps.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/sitemaps", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.getSitemaps.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + [Components.Schemas.SitemapDTO].self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Get all registered UI components in the specified namespace. + /// + /// - Remark: HTTP `GET /ui/components/{namespace}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/get(getRegisteredUIComponentsInNamespace)`. + func getRegisteredUIComponentsInNamespace(_ input: Operations.getRegisteredUIComponentsInNamespace.Input) async throws -> Operations.getRegisteredUIComponentsInNamespace.Output { + try await client.send( + input: input, + forOperation: Operations.getRegisteredUIComponentsInNamespace.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/ui/components/{}", + parameters: [ + input.path.namespace + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "summary", + value: input.query.summary + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.getRegisteredUIComponentsInNamespace.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + [Components.Schemas.RootUIComponent].self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Add a UI component in the specified namespace. + /// + /// - Remark: HTTP `POST /ui/components/{namespace}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/post(addUIComponentToNamespace)`. + func addUIComponentToNamespace(_ input: Operations.addUIComponentToNamespace.Input) async throws -> Operations.addUIComponentToNamespace.Output { + try await client.send( + input: input, + forOperation: Operations.addUIComponentToNamespace.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/ui/components/{}", + parameters: [ + input.path.namespace + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? = switch input.body { + case .none: + nil + case let .json(value): + try converter.setOptionalRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.addUIComponentToNamespace.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.RootUIComponent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Get a specific UI component in the specified namespace. + /// + /// - Remark: HTTP `GET /ui/components/{namespace}/{componentUID}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/get(getUIComponentInNamespace)`. + func getUIComponentInNamespace(_ input: Operations.getUIComponentInNamespace.Input) async throws -> Operations.getUIComponentInNamespace.Output { + try await client.send( + input: input, + forOperation: Operations.getUIComponentInNamespace.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/ui/components/{}/{}", + parameters: [ + input.path.namespace, + input.path.componentUID + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.getUIComponentInNamespace.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.RootUIComponent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 404: + return .notFound(.init()) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Update a specific UI component in the specified namespace. + /// + /// - Remark: HTTP `PUT /ui/components/{namespace}/{componentUID}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/put(updateUIComponentInNamespace)`. + func updateUIComponentInNamespace(_ input: Operations.updateUIComponentInNamespace.Input) async throws -> Operations.updateUIComponentInNamespace.Output { + try await client.send( + input: input, + forOperation: Operations.updateUIComponentInNamespace.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/ui/components/{}/{}", + parameters: [ + input.path.namespace, + input.path.componentUID + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .put + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? = switch input.body { + case .none: + nil + case let .json(value): + try converter.setOptionalRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.updateUIComponentInNamespace.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.RootUIComponent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 404: + return .notFound(.init()) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Remove a specific UI component in the specified namespace. + /// + /// - Remark: HTTP `DELETE /ui/components/{namespace}/{componentUID}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/delete(removeUIComponentFromNamespace)`. + func removeUIComponentFromNamespace(_ input: Operations.removeUIComponentFromNamespace.Input) async throws -> Operations.removeUIComponentFromNamespace.Output { + try await client.send( + input: input, + forOperation: Operations.removeUIComponentFromNamespace.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/ui/components/{}/{}", + parameters: [ + input.path.namespace, + input.path.componentUID + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .delete + ) + suppressMutabilityWarning(&request) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + .ok(.init()) + case 404: + .notFound(.init()) + default: + .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + + /// Get all registered UI tiles. + /// + /// - Remark: HTTP `GET /ui/tiles`. + /// - Remark: Generated from `#/paths//ui/tiles/get(getUITiles)`. + func getUITiles(_ input: Operations.getUITiles.Input) async throws -> Operations.getUITiles.Output { + try await client.send( + input: input, + forOperation: Operations.getUITiles.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/ui/tiles", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.getUITiles.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + [Components.Schemas.TileDTO].self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } +} diff --git a/OpenHABCore/Sources/OpenHABCore/GeneratedSources/openapi/Types.swift b/OpenHABCore/Sources/OpenHABCore/GeneratedSources/openapi/Types.swift new file mode 100644 index 00000000..23afee90 --- /dev/null +++ b/OpenHABCore/Sources/OpenHABCore/GeneratedSources/openapi/Types.swift @@ -0,0 +1,7295 @@ +// Copyright (c) 2010-2024 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +// Generated by swift-openapi-generator, do not modify. +@_spi(Generated) import OpenAPIRuntime +#if os(Linux) +@preconcurrency import struct Foundation.Data +@preconcurrency import struct Foundation.Date +@preconcurrency import struct Foundation.URL +#else +import struct Foundation.Data +import struct Foundation.Date +import struct Foundation.URL +#endif +/// A type that performs HTTP operations defined by the OpenAPI document. +protocol APIProtocol: Sendable { + /// Adds a new member to a group item. + /// + /// - Remark: HTTP `PUT /items/{itemName}/members/{memberItemName}`. + /// - Remark: Generated from `#/paths//items/{itemName}/members/{memberItemName}/put(addMemberToGroupItem)`. + func addMemberToGroupItem(_ input: Operations.addMemberToGroupItem.Input) async throws -> Operations.addMemberToGroupItem.Output + /// Removes an existing member from a group item. + /// + /// - Remark: HTTP `DELETE /items/{itemName}/members/{memberItemName}`. + /// - Remark: Generated from `#/paths//items/{itemName}/members/{memberItemName}/delete(removeMemberFromGroupItem)`. + func removeMemberFromGroupItem(_ input: Operations.removeMemberFromGroupItem.Input) async throws -> Operations.removeMemberFromGroupItem.Output + /// Adds metadata to an item. + /// + /// - Remark: HTTP `PUT /items/{itemname}/metadata/{namespace}`. + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/put(addMetadataToItem)`. + func addMetadataToItem(_ input: Operations.addMetadataToItem.Input) async throws -> Operations.addMetadataToItem.Output + /// Removes metadata from an item. + /// + /// - Remark: HTTP `DELETE /items/{itemname}/metadata/{namespace}`. + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/delete(removeMetadataFromItem)`. + func removeMetadataFromItem(_ input: Operations.removeMetadataFromItem.Input) async throws -> Operations.removeMetadataFromItem.Output + /// Adds a tag to an item. + /// + /// - Remark: HTTP `PUT /items/{itemname}/tags/{tag}`. + /// - Remark: Generated from `#/paths//items/{itemname}/tags/{tag}/put(addTagToItem)`. + func addTagToItem(_ input: Operations.addTagToItem.Input) async throws -> Operations.addTagToItem.Output + /// Removes a tag from an item. + /// + /// - Remark: HTTP `DELETE /items/{itemname}/tags/{tag}`. + /// - Remark: Generated from `#/paths//items/{itemname}/tags/{tag}/delete(removeTagFromItem)`. + func removeTagFromItem(_ input: Operations.removeTagFromItem.Input) async throws -> Operations.removeTagFromItem.Output + /// Gets a single item. + /// + /// - Remark: HTTP `GET /items/{itemname}`. + /// - Remark: Generated from `#/paths//items/{itemname}/get(getItemByName)`. + func getItemByName(_ input: Operations.getItemByName.Input) async throws -> Operations.getItemByName.Output + /// Sends a command to an item. + /// + /// - Remark: HTTP `POST /items/{itemname}`. + /// - Remark: Generated from `#/paths//items/{itemname}/post(sendItemCommand)`. + func sendItemCommand(_ input: Operations.sendItemCommand.Input) async throws -> Operations.sendItemCommand.Output + /// Adds a new item to the registry or updates the existing item. + /// + /// - Remark: HTTP `PUT /items/{itemname}`. + /// - Remark: Generated from `#/paths//items/{itemname}/put(addOrUpdateItemInRegistry)`. + func addOrUpdateItemInRegistry(_ input: Operations.addOrUpdateItemInRegistry.Input) async throws -> Operations.addOrUpdateItemInRegistry.Output + /// Removes an item from the registry. + /// + /// - Remark: HTTP `DELETE /items/{itemname}`. + /// - Remark: Generated from `#/paths//items/{itemname}/delete(removeItemFromRegistry)`. + func removeItemFromRegistry(_ input: Operations.removeItemFromRegistry.Input) async throws -> Operations.removeItemFromRegistry.Output + /// Get all available items. + /// + /// - Remark: HTTP `GET /items`. + /// - Remark: Generated from `#/paths//items/get(getItems)`. + func getItems(_ input: Operations.getItems.Input) async throws -> Operations.getItems.Output + /// Adds a list of items to the registry or updates the existing items. + /// + /// - Remark: HTTP `PUT /items`. + /// - Remark: Generated from `#/paths//items/put(addOrUpdateItemsInRegistry)`. + func addOrUpdateItemsInRegistry(_ input: Operations.addOrUpdateItemsInRegistry.Input) async throws -> Operations.addOrUpdateItemsInRegistry.Output + /// Gets the state of an item. + /// + /// - Remark: HTTP `GET /items/{itemname}/state`. + /// - Remark: Generated from `#/paths//items/{itemname}/state/get(getItemState_1)`. + func getItemState_1(_ input: Operations.getItemState_1.Input) async throws -> Operations.getItemState_1.Output + /// Updates the state of an item. + /// + /// - Remark: HTTP `PUT /items/{itemname}/state`. + /// - Remark: Generated from `#/paths//items/{itemname}/state/put(updateItemState)`. + func updateItemState(_ input: Operations.updateItemState.Input) async throws -> Operations.updateItemState.Output + /// Gets the namespace of an item. + /// + /// - Remark: HTTP `GET /items/{itemname}/metadata/namespaces`. + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/namespaces/get(getItemNamespaces)`. + func getItemNamespaces(_ input: Operations.getItemNamespaces.Input) async throws -> Operations.getItemNamespaces.Output + /// Gets the item which defines the requested semantics of an item. + /// + /// - Remark: HTTP `GET /items/{itemName}/semantic/{semanticClass}`. + /// - Remark: Generated from `#/paths//items/{itemName}/semantic/{semanticClass}/get(getSemanticItem)`. + func getSemanticItem(_ input: Operations.getSemanticItem.Input) async throws -> Operations.getSemanticItem.Output + /// Remove unused/orphaned metadata. + /// + /// - Remark: HTTP `POST /items/metadata/purge`. + /// - Remark: Generated from `#/paths//items/metadata/purge/post(purgeDatabase)`. + func purgeDatabase(_ input: Operations.purgeDatabase.Input) async throws -> Operations.purgeDatabase.Output + /// Creates a sitemap event subscription. + /// + /// - Remark: HTTP `POST /sitemaps/events/subscribe`. + /// - Remark: Generated from `#/paths//sitemaps/events/subscribe/post(createSitemapEventSubscription)`. + func createSitemapEventSubscription(_ input: Operations.createSitemapEventSubscription.Input) async throws -> Operations.createSitemapEventSubscription.Output + /// Polls the data for one page of a sitemap. + /// + /// - Remark: HTTP `GET /sitemaps/{sitemapname}/{pageid}`. + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/{pageid}/get(pollDataForPage)`. + func pollDataForPage(_ input: Operations.pollDataForPage.Input) async throws -> Operations.pollDataForPage.Output + /// Polls the data for a whole sitemap. Not recommended due to potentially high traffic. + /// + /// - Remark: HTTP `GET /sitemaps/{sitemapname}/*`. + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/*/get(pollDataForSitemap)`. + func pollDataForSitemap(_ input: Operations.pollDataForSitemap.Input) async throws -> Operations.pollDataForSitemap.Output + /// Get sitemap by name. + /// + /// - Remark: HTTP `GET /sitemaps/{sitemapname}`. + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/get(getSitemapByName)`. + func getSitemapByName(_ input: Operations.getSitemapByName.Input) async throws -> Operations.getSitemapByName.Output + /// Get sitemap events for a whole sitemap. Not recommended due to potentially high traffic. + /// + /// - Remark: HTTP `GET /sitemaps/events/{subscriptionid}/*`. + /// - Remark: Generated from `#/paths//sitemaps/events/{subscriptionid}/*/get(getSitemapEvents)`. + func getSitemapEvents(_ input: Operations.getSitemapEvents.Input) async throws -> Operations.getSitemapEvents.Output + /// Get sitemap events. + /// + /// - Remark: HTTP `GET /sitemaps/events/{subscriptionid}`. + /// - Remark: Generated from `#/paths//sitemaps/events/{subscriptionid}/get(getSitemapEvents_1)`. + func getSitemapEvents_1(_ input: Operations.getSitemapEvents_1.Input) async throws -> Operations.getSitemapEvents_1.Output + /// Get all available sitemaps. + /// + /// - Remark: HTTP `GET /sitemaps`. + /// - Remark: Generated from `#/paths//sitemaps/get(getSitemaps)`. + func getSitemaps(_ input: Operations.getSitemaps.Input) async throws -> Operations.getSitemaps.Output + /// Get all registered UI components in the specified namespace. + /// + /// - Remark: HTTP `GET /ui/components/{namespace}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/get(getRegisteredUIComponentsInNamespace)`. + func getRegisteredUIComponentsInNamespace(_ input: Operations.getRegisteredUIComponentsInNamespace.Input) async throws -> Operations.getRegisteredUIComponentsInNamespace.Output + /// Add a UI component in the specified namespace. + /// + /// - Remark: HTTP `POST /ui/components/{namespace}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/post(addUIComponentToNamespace)`. + func addUIComponentToNamespace(_ input: Operations.addUIComponentToNamespace.Input) async throws -> Operations.addUIComponentToNamespace.Output + /// Get a specific UI component in the specified namespace. + /// + /// - Remark: HTTP `GET /ui/components/{namespace}/{componentUID}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/get(getUIComponentInNamespace)`. + func getUIComponentInNamespace(_ input: Operations.getUIComponentInNamespace.Input) async throws -> Operations.getUIComponentInNamespace.Output + /// Update a specific UI component in the specified namespace. + /// + /// - Remark: HTTP `PUT /ui/components/{namespace}/{componentUID}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/put(updateUIComponentInNamespace)`. + func updateUIComponentInNamespace(_ input: Operations.updateUIComponentInNamespace.Input) async throws -> Operations.updateUIComponentInNamespace.Output + /// Remove a specific UI component in the specified namespace. + /// + /// - Remark: HTTP `DELETE /ui/components/{namespace}/{componentUID}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/delete(removeUIComponentFromNamespace)`. + func removeUIComponentFromNamespace(_ input: Operations.removeUIComponentFromNamespace.Input) async throws -> Operations.removeUIComponentFromNamespace.Output + /// Get all registered UI tiles. + /// + /// - Remark: HTTP `GET /ui/tiles`. + /// - Remark: Generated from `#/paths//ui/tiles/get(getUITiles)`. + func getUITiles(_ input: Operations.getUITiles.Input) async throws -> Operations.getUITiles.Output +} + +/// Convenience overloads for operation inputs. +extension APIProtocol { + /// Adds a new member to a group item. + /// + /// - Remark: HTTP `PUT /items/{itemName}/members/{memberItemName}`. + /// - Remark: Generated from `#/paths//items/{itemName}/members/{memberItemName}/put(addMemberToGroupItem)`. + func addMemberToGroupItem(path: Operations.addMemberToGroupItem.Input.Path) async throws -> Operations.addMemberToGroupItem.Output { + try await addMemberToGroupItem(Operations.addMemberToGroupItem.Input(path: path)) + } + + /// Removes an existing member from a group item. + /// + /// - Remark: HTTP `DELETE /items/{itemName}/members/{memberItemName}`. + /// - Remark: Generated from `#/paths//items/{itemName}/members/{memberItemName}/delete(removeMemberFromGroupItem)`. + func removeMemberFromGroupItem(path: Operations.removeMemberFromGroupItem.Input.Path) async throws -> Operations.removeMemberFromGroupItem.Output { + try await removeMemberFromGroupItem(Operations.removeMemberFromGroupItem.Input(path: path)) + } + + /// Adds metadata to an item. + /// + /// - Remark: HTTP `PUT /items/{itemname}/metadata/{namespace}`. + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/put(addMetadataToItem)`. + func addMetadataToItem(path: Operations.addMetadataToItem.Input.Path, + body: Operations.addMetadataToItem.Input.Body) async throws -> Operations.addMetadataToItem.Output { + try await addMetadataToItem(Operations.addMetadataToItem.Input( + path: path, + body: body + )) + } + + /// Removes metadata from an item. + /// + /// - Remark: HTTP `DELETE /items/{itemname}/metadata/{namespace}`. + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/delete(removeMetadataFromItem)`. + func removeMetadataFromItem(path: Operations.removeMetadataFromItem.Input.Path) async throws -> Operations.removeMetadataFromItem.Output { + try await removeMetadataFromItem(Operations.removeMetadataFromItem.Input(path: path)) + } + + /// Adds a tag to an item. + /// + /// - Remark: HTTP `PUT /items/{itemname}/tags/{tag}`. + /// - Remark: Generated from `#/paths//items/{itemname}/tags/{tag}/put(addTagToItem)`. + func addTagToItem(path: Operations.addTagToItem.Input.Path) async throws -> Operations.addTagToItem.Output { + try await addTagToItem(Operations.addTagToItem.Input(path: path)) + } + + /// Removes a tag from an item. + /// + /// - Remark: HTTP `DELETE /items/{itemname}/tags/{tag}`. + /// - Remark: Generated from `#/paths//items/{itemname}/tags/{tag}/delete(removeTagFromItem)`. + func removeTagFromItem(path: Operations.removeTagFromItem.Input.Path) async throws -> Operations.removeTagFromItem.Output { + try await removeTagFromItem(Operations.removeTagFromItem.Input(path: path)) + } + + /// Gets a single item. + /// + /// - Remark: HTTP `GET /items/{itemname}`. + /// - Remark: Generated from `#/paths//items/{itemname}/get(getItemByName)`. + func getItemByName(path: Operations.getItemByName.Input.Path, + query: Operations.getItemByName.Input.Query = .init(), + headers: Operations.getItemByName.Input.Headers = .init()) async throws -> Operations.getItemByName.Output { + try await getItemByName(Operations.getItemByName.Input( + path: path, + query: query, + headers: headers + )) + } + + /// Sends a command to an item. + /// + /// - Remark: HTTP `POST /items/{itemname}`. + /// - Remark: Generated from `#/paths//items/{itemname}/post(sendItemCommand)`. + func sendItemCommand(path: Operations.sendItemCommand.Input.Path, + body: Operations.sendItemCommand.Input.Body) async throws -> Operations.sendItemCommand.Output { + try await sendItemCommand(Operations.sendItemCommand.Input( + path: path, + body: body + )) + } + + /// Adds a new item to the registry or updates the existing item. + /// + /// - Remark: HTTP `PUT /items/{itemname}`. + /// - Remark: Generated from `#/paths//items/{itemname}/put(addOrUpdateItemInRegistry)`. + func addOrUpdateItemInRegistry(path: Operations.addOrUpdateItemInRegistry.Input.Path, + headers: Operations.addOrUpdateItemInRegistry.Input.Headers = .init(), + body: Operations.addOrUpdateItemInRegistry.Input.Body) async throws -> Operations.addOrUpdateItemInRegistry.Output { + try await addOrUpdateItemInRegistry(Operations.addOrUpdateItemInRegistry.Input( + path: path, + headers: headers, + body: body + )) + } + + /// Removes an item from the registry. + /// + /// - Remark: HTTP `DELETE /items/{itemname}`. + /// - Remark: Generated from `#/paths//items/{itemname}/delete(removeItemFromRegistry)`. + func removeItemFromRegistry(path: Operations.removeItemFromRegistry.Input.Path) async throws -> Operations.removeItemFromRegistry.Output { + try await removeItemFromRegistry(Operations.removeItemFromRegistry.Input(path: path)) + } + + /// Get all available items. + /// + /// - Remark: HTTP `GET /items`. + /// - Remark: Generated from `#/paths//items/get(getItems)`. + func getItems(query: Operations.getItems.Input.Query = .init(), + headers: Operations.getItems.Input.Headers = .init()) async throws -> Operations.getItems.Output { + try await getItems(Operations.getItems.Input( + query: query, + headers: headers + )) + } + + /// Adds a list of items to the registry or updates the existing items. + /// + /// - Remark: HTTP `PUT /items`. + /// - Remark: Generated from `#/paths//items/put(addOrUpdateItemsInRegistry)`. + func addOrUpdateItemsInRegistry(headers: Operations.addOrUpdateItemsInRegistry.Input.Headers = .init(), + body: Operations.addOrUpdateItemsInRegistry.Input.Body) async throws -> Operations.addOrUpdateItemsInRegistry.Output { + try await addOrUpdateItemsInRegistry(Operations.addOrUpdateItemsInRegistry.Input( + headers: headers, + body: body + )) + } + + /// Gets the state of an item. + /// + /// - Remark: HTTP `GET /items/{itemname}/state`. + /// - Remark: Generated from `#/paths//items/{itemname}/state/get(getItemState_1)`. + func getItemState_1(path: Operations.getItemState_1.Input.Path, + headers: Operations.getItemState_1.Input.Headers = .init()) async throws -> Operations.getItemState_1.Output { + try await getItemState_1(Operations.getItemState_1.Input( + path: path, + headers: headers + )) + } + + /// Updates the state of an item. + /// + /// - Remark: HTTP `PUT /items/{itemname}/state`. + /// - Remark: Generated from `#/paths//items/{itemname}/state/put(updateItemState)`. + func updateItemState(path: Operations.updateItemState.Input.Path, + headers: Operations.updateItemState.Input.Headers = .init(), + body: Operations.updateItemState.Input.Body) async throws -> Operations.updateItemState.Output { + try await updateItemState(Operations.updateItemState.Input( + path: path, + headers: headers, + body: body + )) + } + + /// Gets the namespace of an item. + /// + /// - Remark: HTTP `GET /items/{itemname}/metadata/namespaces`. + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/namespaces/get(getItemNamespaces)`. + func getItemNamespaces(path: Operations.getItemNamespaces.Input.Path, + headers: Operations.getItemNamespaces.Input.Headers = .init()) async throws -> Operations.getItemNamespaces.Output { + try await getItemNamespaces(Operations.getItemNamespaces.Input( + path: path, + headers: headers + )) + } + + /// Gets the item which defines the requested semantics of an item. + /// + /// - Remark: HTTP `GET /items/{itemName}/semantic/{semanticClass}`. + /// - Remark: Generated from `#/paths//items/{itemName}/semantic/{semanticClass}/get(getSemanticItem)`. + func getSemanticItem(path: Operations.getSemanticItem.Input.Path, + headers: Operations.getSemanticItem.Input.Headers = .init()) async throws -> Operations.getSemanticItem.Output { + try await getSemanticItem(Operations.getSemanticItem.Input( + path: path, + headers: headers + )) + } + + /// Remove unused/orphaned metadata. + /// + /// - Remark: HTTP `POST /items/metadata/purge`. + /// - Remark: Generated from `#/paths//items/metadata/purge/post(purgeDatabase)`. + func purgeDatabase() async throws -> Operations.purgeDatabase.Output { + try await purgeDatabase(Operations.purgeDatabase.Input()) + } + + /// Creates a sitemap event subscription. + /// + /// - Remark: HTTP `POST /sitemaps/events/subscribe`. + /// - Remark: Generated from `#/paths//sitemaps/events/subscribe/post(createSitemapEventSubscription)`. + func createSitemapEventSubscription(headers: Operations.createSitemapEventSubscription.Input.Headers = .init()) async throws -> Operations.createSitemapEventSubscription.Output { + try await createSitemapEventSubscription(Operations.createSitemapEventSubscription.Input(headers: headers)) + } + + /// Polls the data for one page of a sitemap. + /// + /// - Remark: HTTP `GET /sitemaps/{sitemapname}/{pageid}`. + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/{pageid}/get(pollDataForPage)`. + func pollDataForPage(path: Operations.pollDataForPage.Input.Path, + query: Operations.pollDataForPage.Input.Query = .init(), + headers: Operations.pollDataForPage.Input.Headers = .init()) async throws -> Operations.pollDataForPage.Output { + try await pollDataForPage(Operations.pollDataForPage.Input( + path: path, + query: query, + headers: headers + )) + } + + /// Polls the data for a whole sitemap. Not recommended due to potentially high traffic. + /// + /// - Remark: HTTP `GET /sitemaps/{sitemapname}/*`. + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/*/get(pollDataForSitemap)`. + func pollDataForSitemap(path: Operations.pollDataForSitemap.Input.Path, + query: Operations.pollDataForSitemap.Input.Query = .init(), + headers: Operations.pollDataForSitemap.Input.Headers = .init()) async throws -> Operations.pollDataForSitemap.Output { + try await pollDataForSitemap(Operations.pollDataForSitemap.Input( + path: path, + query: query, + headers: headers + )) + } + + /// Get sitemap by name. + /// + /// - Remark: HTTP `GET /sitemaps/{sitemapname}`. + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/get(getSitemapByName)`. + func getSitemapByName(path: Operations.getSitemapByName.Input.Path, + query: Operations.getSitemapByName.Input.Query = .init(), + headers: Operations.getSitemapByName.Input.Headers = .init()) async throws -> Operations.getSitemapByName.Output { + try await getSitemapByName(Operations.getSitemapByName.Input( + path: path, + query: query, + headers: headers + )) + } + + /// Get sitemap events for a whole sitemap. Not recommended due to potentially high traffic. + /// + /// - Remark: HTTP `GET /sitemaps/events/{subscriptionid}/*`. + /// - Remark: Generated from `#/paths//sitemaps/events/{subscriptionid}/*/get(getSitemapEvents)`. + func getSitemapEvents(path: Operations.getSitemapEvents.Input.Path, + query: Operations.getSitemapEvents.Input.Query = .init()) async throws -> Operations.getSitemapEvents.Output { + try await getSitemapEvents(Operations.getSitemapEvents.Input( + path: path, + query: query + )) + } + + /// Get sitemap events. + /// + /// - Remark: HTTP `GET /sitemaps/events/{subscriptionid}`. + /// - Remark: Generated from `#/paths//sitemaps/events/{subscriptionid}/get(getSitemapEvents_1)`. + func getSitemapEvents_1(path: Operations.getSitemapEvents_1.Input.Path, + query: Operations.getSitemapEvents_1.Input.Query = .init(), + headers: Operations.getSitemapEvents_1.Input.Headers = .init()) async throws -> Operations.getSitemapEvents_1.Output { + try await getSitemapEvents_1(Operations.getSitemapEvents_1.Input( + path: path, + query: query, + headers: headers + )) + } + + /// Get all available sitemaps. + /// + /// - Remark: HTTP `GET /sitemaps`. + /// - Remark: Generated from `#/paths//sitemaps/get(getSitemaps)`. + func getSitemaps(headers: Operations.getSitemaps.Input.Headers = .init()) async throws -> Operations.getSitemaps.Output { + try await getSitemaps(Operations.getSitemaps.Input(headers: headers)) + } + + /// Get all registered UI components in the specified namespace. + /// + /// - Remark: HTTP `GET /ui/components/{namespace}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/get(getRegisteredUIComponentsInNamespace)`. + func getRegisteredUIComponentsInNamespace(path: Operations.getRegisteredUIComponentsInNamespace.Input.Path, + query: Operations.getRegisteredUIComponentsInNamespace.Input.Query = .init(), + headers: Operations.getRegisteredUIComponentsInNamespace.Input.Headers = .init()) async throws -> Operations.getRegisteredUIComponentsInNamespace.Output { + try await getRegisteredUIComponentsInNamespace(Operations.getRegisteredUIComponentsInNamespace.Input( + path: path, + query: query, + headers: headers + )) + } + + /// Add a UI component in the specified namespace. + /// + /// - Remark: HTTP `POST /ui/components/{namespace}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/post(addUIComponentToNamespace)`. + func addUIComponentToNamespace(path: Operations.addUIComponentToNamespace.Input.Path, + headers: Operations.addUIComponentToNamespace.Input.Headers = .init(), + body: Operations.addUIComponentToNamespace.Input.Body? = nil) async throws -> Operations.addUIComponentToNamespace.Output { + try await addUIComponentToNamespace(Operations.addUIComponentToNamespace.Input( + path: path, + headers: headers, + body: body + )) + } + + /// Get a specific UI component in the specified namespace. + /// + /// - Remark: HTTP `GET /ui/components/{namespace}/{componentUID}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/get(getUIComponentInNamespace)`. + func getUIComponentInNamespace(path: Operations.getUIComponentInNamespace.Input.Path, + headers: Operations.getUIComponentInNamespace.Input.Headers = .init()) async throws -> Operations.getUIComponentInNamespace.Output { + try await getUIComponentInNamespace(Operations.getUIComponentInNamespace.Input( + path: path, + headers: headers + )) + } + + /// Update a specific UI component in the specified namespace. + /// + /// - Remark: HTTP `PUT /ui/components/{namespace}/{componentUID}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/put(updateUIComponentInNamespace)`. + func updateUIComponentInNamespace(path: Operations.updateUIComponentInNamespace.Input.Path, + headers: Operations.updateUIComponentInNamespace.Input.Headers = .init(), + body: Operations.updateUIComponentInNamespace.Input.Body? = nil) async throws -> Operations.updateUIComponentInNamespace.Output { + try await updateUIComponentInNamespace(Operations.updateUIComponentInNamespace.Input( + path: path, + headers: headers, + body: body + )) + } + + /// Remove a specific UI component in the specified namespace. + /// + /// - Remark: HTTP `DELETE /ui/components/{namespace}/{componentUID}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/delete(removeUIComponentFromNamespace)`. + func removeUIComponentFromNamespace(path: Operations.removeUIComponentFromNamespace.Input.Path) async throws -> Operations.removeUIComponentFromNamespace.Output { + try await removeUIComponentFromNamespace(Operations.removeUIComponentFromNamespace.Input(path: path)) + } + + /// Get all registered UI tiles. + /// + /// - Remark: HTTP `GET /ui/tiles`. + /// - Remark: Generated from `#/paths//ui/tiles/get(getUITiles)`. + func getUITiles(headers: Operations.getUITiles.Input.Headers = .init()) async throws -> Operations.getUITiles.Output { + try await getUITiles(Operations.getUITiles.Input(headers: headers)) + } +} + +/// Server URLs defined in the OpenAPI document. +enum Servers { + static func server1() throws -> Foundation.URL { + try Foundation.URL( + validatingOpenAPIServerURL: "/rest", + variables: [] + ) + } +} + +/// Types generated from the components section of the OpenAPI document. +enum Components { + /// Types generated from the `#/components/schemas` section of the OpenAPI document. + enum Schemas { + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO`. + struct ConfigDescriptionParameterDTO: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/context`. + var context: Swift.String? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/defaultValue`. + var defaultValue: Swift.String? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/description`. + var description: Swift.String? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/label`. + var label: Swift.String? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/name`. + var name: Swift.String? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/required`. + var required: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/type`. + enum _typePayload: String, Codable, Hashable, Sendable, CaseIterable { + case TEXT + case INTEGER + case DECIMAL + case BOOLEAN + } + + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/type`. + var _type: Components.Schemas.ConfigDescriptionParameterDTO._typePayload? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/min`. + var min: Swift.Double? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/max`. + var max: Swift.Double? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/stepsize`. + var stepsize: Swift.Double? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/pattern`. + var pattern: Swift.String? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/readOnly`. + var readOnly: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/multiple`. + var multiple: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/multipleLimit`. + var multipleLimit: Swift.Int32? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/groupName`. + var groupName: Swift.String? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/advanced`. + var advanced: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/verify`. + var verify: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/limitToOptions`. + var limitToOptions: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/unit`. + var unit: Swift.String? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/unitLabel`. + var unitLabel: Swift.String? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/options`. + var options: [Components.Schemas.ParameterOptionDTO]? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/filterCriteria`. + var filterCriteria: [Components.Schemas.FilterCriteriaDTO]? + /// Creates a new `ConfigDescriptionParameterDTO`. + /// + /// - Parameters: + /// - context: + /// - defaultValue: + /// - description: + /// - label: + /// - name: + /// - required: + /// - _type: + /// - min: + /// - max: + /// - stepsize: + /// - pattern: + /// - readOnly: + /// - multiple: + /// - multipleLimit: + /// - groupName: + /// - advanced: + /// - verify: + /// - limitToOptions: + /// - unit: + /// - unitLabel: + /// - options: + /// - filterCriteria: + init(context: Swift.String? = nil, + defaultValue: Swift.String? = nil, + description: Swift.String? = nil, + label: Swift.String? = nil, + name: Swift.String? = nil, + required: Swift.Bool? = nil, + _type: Components.Schemas.ConfigDescriptionParameterDTO._typePayload? = nil, + min: Swift.Double? = nil, + max: Swift.Double? = nil, + stepsize: Swift.Double? = nil, + pattern: Swift.String? = nil, + readOnly: Swift.Bool? = nil, + multiple: Swift.Bool? = nil, + multipleLimit: Swift.Int32? = nil, + groupName: Swift.String? = nil, + advanced: Swift.Bool? = nil, + verify: Swift.Bool? = nil, + limitToOptions: Swift.Bool? = nil, + unit: Swift.String? = nil, + unitLabel: Swift.String? = nil, + options: [Components.Schemas.ParameterOptionDTO]? = nil, + filterCriteria: [Components.Schemas.FilterCriteriaDTO]? = nil) { + self.context = context + self.defaultValue = defaultValue + self.description = description + self.label = label + self.name = name + self.required = required + self._type = _type + self.min = min + self.max = max + self.stepsize = stepsize + self.pattern = pattern + self.readOnly = readOnly + self.multiple = multiple + self.multipleLimit = multipleLimit + self.groupName = groupName + self.advanced = advanced + self.verify = verify + self.limitToOptions = limitToOptions + self.unit = unit + self.unitLabel = unitLabel + self.options = options + self.filterCriteria = filterCriteria + } + + enum CodingKeys: String, CodingKey { + case context + case defaultValue + case description + case label + case name + case required + case _type = "type" + case min + case max + case stepsize + case pattern + case readOnly + case multiple + case multipleLimit + case groupName + case advanced + case verify + case limitToOptions + case unit + case unitLabel + case options + case filterCriteria + } + } + + /// - Remark: Generated from `#/components/schemas/FilterCriteriaDTO`. + struct FilterCriteriaDTO: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/FilterCriteriaDTO/value`. + var value: Swift.String? + /// - Remark: Generated from `#/components/schemas/FilterCriteriaDTO/name`. + var name: Swift.String? + /// Creates a new `FilterCriteriaDTO`. + /// + /// - Parameters: + /// - value: + /// - name: + init(value: Swift.String? = nil, + name: Swift.String? = nil) { + self.value = value + self.name = name + } + + enum CodingKeys: String, CodingKey { + case value + case name + } + } + + /// - Remark: Generated from `#/components/schemas/ParameterOptionDTO`. + struct ParameterOptionDTO: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/ParameterOptionDTO/label`. + var label: Swift.String? + /// - Remark: Generated from `#/components/schemas/ParameterOptionDTO/value`. + var value: Swift.String? + /// Creates a new `ParameterOptionDTO`. + /// + /// - Parameters: + /// - label: + /// - value: + init(label: Swift.String? = nil, + value: Swift.String? = nil) { + self.label = label + self.value = value + } + + enum CodingKeys: String, CodingKey { + case label + case value + } + } + + /// - Remark: Generated from `#/components/schemas/CommandDescription`. + struct CommandDescription: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/CommandDescription/commandOptions`. + var commandOptions: [Components.Schemas.CommandOption]? + /// Creates a new `CommandDescription`. + /// + /// - Parameters: + /// - commandOptions: + init(commandOptions: [Components.Schemas.CommandOption]? = nil) { + self.commandOptions = commandOptions + } + + enum CodingKeys: String, CodingKey { + case commandOptions + } + } + + /// - Remark: Generated from `#/components/schemas/CommandOption`. + struct CommandOption: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/CommandOption/command`. + var command: Swift.String? + /// - Remark: Generated from `#/components/schemas/CommandOption/label`. + var label: Swift.String? + /// Creates a new `CommandOption`. + /// + /// - Parameters: + /// - command: + /// - label: + init(command: Swift.String? = nil, + label: Swift.String? = nil) { + self.command = command + self.label = label + } + + enum CodingKeys: String, CodingKey { + case command + case label + } + } + + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterGroupDTO`. + struct ConfigDescriptionParameterGroupDTO: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterGroupDTO/name`. + var name: Swift.String? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterGroupDTO/context`. + var context: Swift.String? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterGroupDTO/advanced`. + var advanced: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterGroupDTO/label`. + var label: Swift.String? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterGroupDTO/description`. + var description: Swift.String? + /// Creates a new `ConfigDescriptionParameterGroupDTO`. + /// + /// - Parameters: + /// - name: + /// - context: + /// - advanced: + /// - label: + /// - description: + init(name: Swift.String? = nil, + context: Swift.String? = nil, + advanced: Swift.Bool? = nil, + label: Swift.String? = nil, + description: Swift.String? = nil) { + self.name = name + self.context = context + self.advanced = advanced + self.label = label + self.description = description + } + + enum CodingKeys: String, CodingKey { + case name + case context + case advanced + case label + case description + } + } + + /// - Remark: Generated from `#/components/schemas/StateDescription`. + struct StateDescription: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/StateDescription/minimum`. + var minimum: Swift.Double? + /// - Remark: Generated from `#/components/schemas/StateDescription/maximum`. + var maximum: Swift.Double? + /// - Remark: Generated from `#/components/schemas/StateDescription/step`. + var step: Swift.Double? + /// - Remark: Generated from `#/components/schemas/StateDescription/pattern`. + var pattern: Swift.String? + /// - Remark: Generated from `#/components/schemas/StateDescription/readOnly`. + var readOnly: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/StateDescription/options`. + var options: [Components.Schemas.StateOption]? + /// Creates a new `StateDescription`. + /// + /// - Parameters: + /// - minimum: + /// - maximum: + /// - step: + /// - pattern: + /// - readOnly: + /// - options: + init(minimum: Swift.Double? = nil, + maximum: Swift.Double? = nil, + step: Swift.Double? = nil, + pattern: Swift.String? = nil, + readOnly: Swift.Bool? = nil, + options: [Components.Schemas.StateOption]? = nil) { + self.minimum = minimum + self.maximum = maximum + self.step = step + self.pattern = pattern + self.readOnly = readOnly + self.options = options + } + + enum CodingKeys: String, CodingKey { + case minimum + case maximum + case step + case pattern + case readOnly + case options + } + } + + /// - Remark: Generated from `#/components/schemas/StateOption`. + struct StateOption: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/StateOption/value`. + var value: Swift.String? + /// - Remark: Generated from `#/components/schemas/StateOption/label`. + var label: Swift.String? + /// Creates a new `StateOption`. + /// + /// - Parameters: + /// - value: + /// - label: + init(value: Swift.String? = nil, + label: Swift.String? = nil) { + self.value = value + self.label = label + } + + enum CodingKeys: String, CodingKey { + case value + case label + } + } + + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionDTO`. + struct ConfigDescriptionDTO: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionDTO/uri`. + var uri: Swift.String? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionDTO/parameters`. + var parameters: [Components.Schemas.ConfigDescriptionParameterDTO]? + /// - Remark: Generated from `#/components/schemas/ConfigDescriptionDTO/parameterGroups`. + var parameterGroups: [Components.Schemas.ConfigDescriptionParameterGroupDTO]? + /// Creates a new `ConfigDescriptionDTO`. + /// + /// - Parameters: + /// - uri: + /// - parameters: + /// - parameterGroups: + init(uri: Swift.String? = nil, + parameters: [Components.Schemas.ConfigDescriptionParameterDTO]? = nil, + parameterGroups: [Components.Schemas.ConfigDescriptionParameterGroupDTO]? = nil) { + self.uri = uri + self.parameters = parameters + self.parameterGroups = parameterGroups + } + + enum CodingKeys: String, CodingKey { + case uri + case parameters + case parameterGroups + } + } + + /// - Remark: Generated from `#/components/schemas/MetadataDTO`. + struct MetadataDTO: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/MetadataDTO/value`. + var value: Swift.String? + /// - Remark: Generated from `#/components/schemas/MetadataDTO/config`. + struct configPayload: Codable, Hashable, Sendable { + /// A container of undocumented properties. + var additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] + /// Creates a new `configPayload`. + /// + /// - Parameters: + /// - additionalProperties: A container of undocumented properties. + init(additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] = .init()) { + self.additionalProperties = additionalProperties + } + + init(from decoder: any Decoder) throws { + additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) + } + + func encode(to encoder: any Encoder) throws { + try encoder.encodeAdditionalProperties(additionalProperties) + } + } + + /// - Remark: Generated from `#/components/schemas/MetadataDTO/config`. + var config: Components.Schemas.MetadataDTO.configPayload? + /// Creates a new `MetadataDTO`. + /// + /// - Parameters: + /// - value: + /// - config: + init(value: Swift.String? = nil, + config: Components.Schemas.MetadataDTO.configPayload? = nil) { + self.value = value + self.config = config + } + + enum CodingKeys: String, CodingKey { + case value + case config + } + } + + /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO`. + struct EnrichedItemDTO: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/type`. + var _type: Swift.String? + /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/name`. + var name: Swift.String? + /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/label`. + var label: Swift.String? + /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/category`. + var category: Swift.String? + /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/tags`. + var tags: [Swift.String]? + /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/groupNames`. + var groupNames: [Swift.String]? + /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/link`. + var link: Swift.String? + /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/state`. + var state: Swift.String? + /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/transformedState`. + var transformedState: Swift.String? + /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/stateDescription`. + var stateDescription: Components.Schemas.StateDescription? + /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/unitSymbol`. + var unitSymbol: Swift.String? + /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/commandDescription`. + var commandDescription: Components.Schemas.CommandDescription? + /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/metadata`. + struct metadataPayload: Codable, Hashable, Sendable { + /// A container of undocumented properties. + var additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] + /// Creates a new `metadataPayload`. + /// + /// - Parameters: + /// - additionalProperties: A container of undocumented properties. + init(additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] = .init()) { + self.additionalProperties = additionalProperties + } + + init(from decoder: any Decoder) throws { + additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) + } + + func encode(to encoder: any Encoder) throws { + try encoder.encodeAdditionalProperties(additionalProperties) + } + } + + /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/metadata`. + var metadata: Components.Schemas.EnrichedItemDTO.metadataPayload? + /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/editable`. + var editable: Swift.Bool? + /// Creates a new `EnrichedItemDTO`. + /// + /// - Parameters: + /// - _type: + /// - name: + /// - label: + /// - category: + /// - tags: + /// - groupNames: + /// - link: + /// - state: + /// - transformedState: + /// - stateDescription: + /// - unitSymbol: + /// - commandDescription: + /// - metadata: + /// - editable: + init(_type: Swift.String? = nil, + name: Swift.String? = nil, + label: Swift.String? = nil, + category: Swift.String? = nil, + tags: [Swift.String]? = nil, + groupNames: [Swift.String]? = nil, + link: Swift.String? = nil, + state: Swift.String? = nil, + transformedState: Swift.String? = nil, + stateDescription: Components.Schemas.StateDescription? = nil, + unitSymbol: Swift.String? = nil, + commandDescription: Components.Schemas.CommandDescription? = nil, + metadata: Components.Schemas.EnrichedItemDTO.metadataPayload? = nil, + editable: Swift.Bool? = nil) { + self._type = _type + self.name = name + self.label = label + self.category = category + self.tags = tags + self.groupNames = groupNames + self.link = link + self.state = state + self.transformedState = transformedState + self.stateDescription = stateDescription + self.unitSymbol = unitSymbol + self.commandDescription = commandDescription + self.metadata = metadata + self.editable = editable + } + + enum CodingKeys: String, CodingKey { + case _type = "type" + case name + case label + case category + case tags + case groupNames + case link + case state + case transformedState + case stateDescription + case unitSymbol + case commandDescription + case metadata + case editable + } + } + + /// - Remark: Generated from `#/components/schemas/GroupFunctionDTO`. + struct GroupFunctionDTO: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/GroupFunctionDTO/name`. + var name: Swift.String? + /// - Remark: Generated from `#/components/schemas/GroupFunctionDTO/params`. + var params: [Swift.String]? + /// Creates a new `GroupFunctionDTO`. + /// + /// - Parameters: + /// - name: + /// - params: + init(name: Swift.String? = nil, + params: [Swift.String]? = nil) { + self.name = name + self.params = params + } + + enum CodingKeys: String, CodingKey { + case name + case params + } + } + + /// - Remark: Generated from `#/components/schemas/GroupItemDTO`. + struct GroupItemDTO: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/GroupItemDTO/type`. + var _type: Swift.String? + /// - Remark: Generated from `#/components/schemas/GroupItemDTO/name`. + var name: Swift.String? + /// - Remark: Generated from `#/components/schemas/GroupItemDTO/label`. + var label: Swift.String? + /// - Remark: Generated from `#/components/schemas/GroupItemDTO/category`. + var category: Swift.String? + /// - Remark: Generated from `#/components/schemas/GroupItemDTO/tags`. + var tags: [Swift.String]? + /// - Remark: Generated from `#/components/schemas/GroupItemDTO/groupNames`. + var groupNames: [Swift.String]? + /// - Remark: Generated from `#/components/schemas/GroupItemDTO/groupType`. + var groupType: Swift.String? + /// - Remark: Generated from `#/components/schemas/GroupItemDTO/function`. + var function: Components.Schemas.GroupFunctionDTO? + /// Creates a new `GroupItemDTO`. + /// + /// - Parameters: + /// - _type: + /// - name: + /// - label: + /// - category: + /// - tags: + /// - groupNames: + /// - groupType: + /// - function: + init(_type: Swift.String? = nil, + name: Swift.String? = nil, + label: Swift.String? = nil, + category: Swift.String? = nil, + tags: [Swift.String]? = nil, + groupNames: [Swift.String]? = nil, + groupType: Swift.String? = nil, + function: Components.Schemas.GroupFunctionDTO? = nil) { + self._type = _type + self.name = name + self.label = label + self.category = category + self.tags = tags + self.groupNames = groupNames + self.groupType = groupType + self.function = function + } + + enum CodingKeys: String, CodingKey { + case _type = "type" + case name + case label + case category + case tags + case groupNames + case groupType + case function + } + } + + /// - Remark: Generated from `#/components/schemas/JerseyResponseBuilderDTO`. + struct JerseyResponseBuilderDTO: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/JerseyResponseBuilderDTO/status`. + var status: Swift.String? + /// - Remark: Generated from `#/components/schemas/JerseyResponseBuilderDTO/context`. + var context: Components.Schemas.ContextDTO? + /// Creates a new `JerseyResponseBuilderDTO`. + /// + /// - Parameters: + /// - status: + /// - context: + init(status: Swift.String? = nil, + context: Components.Schemas.ContextDTO? = nil) { + self.status = status + self.context = context + } + + enum CodingKeys: String, CodingKey { + case status + case context + } + } + + /// - Remark: Generated from `#/components/schemas/ContextDTO`. + struct ContextDTO: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/ContextDTO/headers`. + var headers: Components.Schemas.HeadersDTO? + /// Creates a new `ContextDTO`. + /// + /// - Parameters: + /// - headers: + init(headers: Components.Schemas.HeadersDTO? = nil) { + self.headers = headers + } + + enum CodingKeys: String, CodingKey { + case headers + } + } + + /// - Remark: Generated from `#/components/schemas/HeadersDTO`. + struct HeadersDTO: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/HeadersDTO/Location`. + var Location: [Swift.String]? + /// Creates a new `HeadersDTO`. + /// + /// - Parameters: + /// - Location: + init(Location: [Swift.String]? = nil) { + self.Location = Location + } + + enum CodingKeys: String, CodingKey { + case Location + } + } + + /// - Remark: Generated from `#/components/schemas/MappingDTO`. + struct MappingDTO: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/MappingDTO/row`. + var row: Swift.Int32? + /// - Remark: Generated from `#/components/schemas/MappingDTO/column`. + var column: Swift.Int32? + /// - Remark: Generated from `#/components/schemas/MappingDTO/command`. + var command: Swift.String? + /// - Remark: Generated from `#/components/schemas/MappingDTO/releaseCommand`. + var releaseCommand: Swift.String? + /// - Remark: Generated from `#/components/schemas/MappingDTO/label`. + var label: Swift.String? + /// - Remark: Generated from `#/components/schemas/MappingDTO/icon`. + var icon: Swift.String? + /// Creates a new `MappingDTO`. + /// + /// - Parameters: + /// - row: + /// - column: + /// - command: + /// - releaseCommand: + /// - label: + /// - icon: + init(row: Swift.Int32? = nil, + column: Swift.Int32? = nil, + command: Swift.String? = nil, + releaseCommand: Swift.String? = nil, + label: Swift.String? = nil, + icon: Swift.String? = nil) { + self.row = row + self.column = column + self.command = command + self.releaseCommand = releaseCommand + self.label = label + self.icon = icon + } + + enum CodingKeys: String, CodingKey { + case row + case column + case command + case releaseCommand + case label + case icon + } + } + + /// - Remark: Generated from `#/components/schemas/PageDTO`. + struct PageDTO: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/PageDTO/id`. + var id: Swift.String? { + get { + storage.value.id + } + _modify { + yield &storage.value.id + } + } + + /// - Remark: Generated from `#/components/schemas/PageDTO/title`. + var title: Swift.String? { + get { + storage.value.title + } + _modify { + yield &storage.value.title + } + } + + /// - Remark: Generated from `#/components/schemas/PageDTO/icon`. + var icon: Swift.String? { + get { + storage.value.icon + } + _modify { + yield &storage.value.icon + } + } + + /// - Remark: Generated from `#/components/schemas/PageDTO/link`. + var link: Swift.String? { + get { + storage.value.link + } + _modify { + yield &storage.value.link + } + } + + /// - Remark: Generated from `#/components/schemas/PageDTO/parent`. + var parent: Components.Schemas.PageDTO? { + get { + storage.value.parent + } + _modify { + yield &storage.value.parent + } + } + + /// - Remark: Generated from `#/components/schemas/PageDTO/leaf`. + var leaf: Swift.Bool? { + get { + storage.value.leaf + } + _modify { + yield &storage.value.leaf + } + } + + /// - Remark: Generated from `#/components/schemas/PageDTO/timeout`. + var timeout: Swift.Bool? { + get { + storage.value.timeout + } + _modify { + yield &storage.value.timeout + } + } + + /// - Remark: Generated from `#/components/schemas/PageDTO/widgets`. + var widgets: [Components.Schemas.WidgetDTO]? { + get { + storage.value.widgets + } + _modify { + yield &storage.value.widgets + } + } + + /// Creates a new `PageDTO`. + /// + /// - Parameters: + /// - id: + /// - title: + /// - icon: + /// - link: + /// - parent: + /// - leaf: + /// - timeout: + /// - widgets: + init(id: Swift.String? = nil, + title: Swift.String? = nil, + icon: Swift.String? = nil, + link: Swift.String? = nil, + parent: Components.Schemas.PageDTO? = nil, + leaf: Swift.Bool? = nil, + timeout: Swift.Bool? = nil, + widgets: [Components.Schemas.WidgetDTO]? = nil) { + storage = .init(value: .init( + id: id, + title: title, + icon: icon, + link: link, + parent: parent, + leaf: leaf, + timeout: timeout, + widgets: widgets + )) + } + + enum CodingKeys: String, CodingKey { + case id + case title + case icon + case link + case parent + case leaf + case timeout + case widgets + } + + init(from decoder: any Decoder) throws { + storage = try .init(from: decoder) + } + + func encode(to encoder: any Encoder) throws { + try storage.encode(to: encoder) + } + + /// Internal reference storage to allow type recursion. + private var storage: OpenAPIRuntime.CopyOnWriteBox + private struct Storage: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/PageDTO/id`. + var id: Swift.String? + /// - Remark: Generated from `#/components/schemas/PageDTO/title`. + var title: Swift.String? + /// - Remark: Generated from `#/components/schemas/PageDTO/icon`. + var icon: Swift.String? + /// - Remark: Generated from `#/components/schemas/PageDTO/link`. + var link: Swift.String? + /// - Remark: Generated from `#/components/schemas/PageDTO/parent`. + var parent: Components.Schemas.PageDTO? + /// - Remark: Generated from `#/components/schemas/PageDTO/leaf`. + var leaf: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/PageDTO/timeout`. + var timeout: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/PageDTO/widgets`. + var widgets: [Components.Schemas.WidgetDTO]? + init(id: Swift.String? = nil, + title: Swift.String? = nil, + icon: Swift.String? = nil, + link: Swift.String? = nil, + parent: Components.Schemas.PageDTO? = nil, + leaf: Swift.Bool? = nil, + timeout: Swift.Bool? = nil, + widgets: [Components.Schemas.WidgetDTO]? = nil) { + self.id = id + self.title = title + self.icon = icon + self.link = link + self.parent = parent + self.leaf = leaf + self.timeout = timeout + self.widgets = widgets + } + + typealias CodingKeys = Components.Schemas.PageDTO.CodingKeys + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO`. + struct WidgetDTO: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/WidgetDTO/widgetId`. + var widgetId: Swift.String? { + get { + storage.value.widgetId + } + _modify { + yield &storage.value.widgetId + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/type`. + var _type: Swift.String? { + get { + storage.value._type + } + _modify { + yield &storage.value._type + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/name`. + var name: Swift.String? { + get { + storage.value.name + } + _modify { + yield &storage.value.name + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/visibility`. + var visibility: Swift.Bool? { + get { + storage.value.visibility + } + _modify { + yield &storage.value.visibility + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/label`. + var label: Swift.String? { + get { + storage.value.label + } + _modify { + yield &storage.value.label + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/labelSource`. + var labelSource: Swift.String? { + get { + storage.value.labelSource + } + _modify { + yield &storage.value.labelSource + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/icon`. + var icon: Swift.String? { + get { + storage.value.icon + } + _modify { + yield &storage.value.icon + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/staticIcon`. + var staticIcon: Swift.Bool? { + get { + storage.value.staticIcon + } + _modify { + yield &storage.value.staticIcon + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/labelcolor`. + var labelcolor: Swift.String? { + get { + storage.value.labelcolor + } + _modify { + yield &storage.value.labelcolor + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/valuecolor`. + var valuecolor: Swift.String? { + get { + storage.value.valuecolor + } + _modify { + yield &storage.value.valuecolor + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/iconcolor`. + var iconcolor: Swift.String? { + get { + storage.value.iconcolor + } + _modify { + yield &storage.value.iconcolor + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/pattern`. + var pattern: Swift.String? { + get { + storage.value.pattern + } + _modify { + yield &storage.value.pattern + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/unit`. + var unit: Swift.String? { + get { + storage.value.unit + } + _modify { + yield &storage.value.unit + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/mappings`. + var mappings: [Components.Schemas.MappingDTO]? { + get { + storage.value.mappings + } + _modify { + yield &storage.value.mappings + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/switchSupport`. + var switchSupport: Swift.Bool? { + get { + storage.value.switchSupport + } + _modify { + yield &storage.value.switchSupport + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/releaseOnly`. + var releaseOnly: Swift.Bool? { + get { + storage.value.releaseOnly + } + _modify { + yield &storage.value.releaseOnly + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/sendFrequency`. + var sendFrequency: Swift.Int32? { + get { + storage.value.sendFrequency + } + _modify { + yield &storage.value.sendFrequency + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/refresh`. + var refresh: Swift.Int32? { + get { + storage.value.refresh + } + _modify { + yield &storage.value.refresh + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/height`. + var height: Swift.Int32? { + get { + storage.value.height + } + _modify { + yield &storage.value.height + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/minValue`. + var minValue: Swift.Double? { + get { + storage.value.minValue + } + _modify { + yield &storage.value.minValue + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/maxValue`. + var maxValue: Swift.Double? { + get { + storage.value.maxValue + } + _modify { + yield &storage.value.maxValue + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/step`. + var step: Swift.Double? { + get { + storage.value.step + } + _modify { + yield &storage.value.step + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/inputHint`. + var inputHint: Swift.String? { + get { + storage.value.inputHint + } + _modify { + yield &storage.value.inputHint + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/url`. + var url: Swift.String? { + get { + storage.value.url + } + _modify { + yield &storage.value.url + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/encoding`. + var encoding: Swift.String? { + get { + storage.value.encoding + } + _modify { + yield &storage.value.encoding + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/service`. + var service: Swift.String? { + get { + storage.value.service + } + _modify { + yield &storage.value.service + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/period`. + var period: Swift.String? { + get { + storage.value.period + } + _modify { + yield &storage.value.period + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/yAxisDecimalPattern`. + var yAxisDecimalPattern: Swift.String? { + get { + storage.value.yAxisDecimalPattern + } + _modify { + yield &storage.value.yAxisDecimalPattern + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/legend`. + var legend: Swift.Bool? { + get { + storage.value.legend + } + _modify { + yield &storage.value.legend + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/forceAsItem`. + var forceAsItem: Swift.Bool? { + get { + storage.value.forceAsItem + } + _modify { + yield &storage.value.forceAsItem + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/row`. + var row: Swift.Int32? { + get { + storage.value.row + } + _modify { + yield &storage.value.row + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/column`. + var column: Swift.Int32? { + get { + storage.value.column + } + _modify { + yield &storage.value.column + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/command`. + var command: Swift.String? { + get { + storage.value.command + } + _modify { + yield &storage.value.command + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/releaseCommand`. + var releaseCommand: Swift.String? { + get { + storage.value.releaseCommand + } + _modify { + yield &storage.value.releaseCommand + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/stateless`. + var stateless: Swift.Bool? { + get { + storage.value.stateless + } + _modify { + yield &storage.value.stateless + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/state`. + var state: Swift.String? { + get { + storage.value.state + } + _modify { + yield &storage.value.state + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/item`. + var item: Components.Schemas.EnrichedItemDTO? { + get { + storage.value.item + } + _modify { + yield &storage.value.item + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/linkedPage`. + var linkedPage: Components.Schemas.PageDTO? { + get { + storage.value.linkedPage + } + _modify { + yield &storage.value.linkedPage + } + } + + /// - Remark: Generated from `#/components/schemas/WidgetDTO/widgets`. + var widgets: [Components.Schemas.WidgetDTO]? { + get { + storage.value.widgets + } + _modify { + yield &storage.value.widgets + } + } + + /// Creates a new `WidgetDTO`. + /// + /// - Parameters: + /// - widgetId: + /// - _type: + /// - name: + /// - visibility: + /// - label: + /// - labelSource: + /// - icon: + /// - staticIcon: + /// - labelcolor: + /// - valuecolor: + /// - iconcolor: + /// - pattern: + /// - unit: + /// - mappings: + /// - switchSupport: + /// - releaseOnly: + /// - sendFrequency: + /// - refresh: + /// - height: + /// - minValue: + /// - maxValue: + /// - step: + /// - inputHint: + /// - url: + /// - encoding: + /// - service: + /// - period: + /// - yAxisDecimalPattern: + /// - legend: + /// - forceAsItem: + /// - row: + /// - column: + /// - command: + /// - releaseCommand: + /// - stateless: + /// - state: + /// - item: + /// - linkedPage: + /// - widgets: + init(widgetId: Swift.String? = nil, + _type: Swift.String? = nil, + name: Swift.String? = nil, + visibility: Swift.Bool? = nil, + label: Swift.String? = nil, + labelSource: Swift.String? = nil, + icon: Swift.String? = nil, + staticIcon: Swift.Bool? = nil, + labelcolor: Swift.String? = nil, + valuecolor: Swift.String? = nil, + iconcolor: Swift.String? = nil, + pattern: Swift.String? = nil, + unit: Swift.String? = nil, + mappings: [Components.Schemas.MappingDTO]? = nil, + switchSupport: Swift.Bool? = nil, + releaseOnly: Swift.Bool? = nil, + sendFrequency: Swift.Int32? = nil, + refresh: Swift.Int32? = nil, + height: Swift.Int32? = nil, + minValue: Swift.Double? = nil, + maxValue: Swift.Double? = nil, + step: Swift.Double? = nil, + inputHint: Swift.String? = nil, + url: Swift.String? = nil, + encoding: Swift.String? = nil, + service: Swift.String? = nil, + period: Swift.String? = nil, + yAxisDecimalPattern: Swift.String? = nil, + legend: Swift.Bool? = nil, + forceAsItem: Swift.Bool? = nil, + row: Swift.Int32? = nil, + column: Swift.Int32? = nil, + command: Swift.String? = nil, + releaseCommand: Swift.String? = nil, + stateless: Swift.Bool? = nil, + state: Swift.String? = nil, + item: Components.Schemas.EnrichedItemDTO? = nil, + linkedPage: Components.Schemas.PageDTO? = nil, + widgets: [Components.Schemas.WidgetDTO]? = nil) { + storage = .init(value: .init( + widgetId: widgetId, + _type: _type, + name: name, + visibility: visibility, + label: label, + labelSource: labelSource, + icon: icon, + staticIcon: staticIcon, + labelcolor: labelcolor, + valuecolor: valuecolor, + iconcolor: iconcolor, + pattern: pattern, + unit: unit, + mappings: mappings, + switchSupport: switchSupport, + releaseOnly: releaseOnly, + sendFrequency: sendFrequency, + refresh: refresh, + height: height, + minValue: minValue, + maxValue: maxValue, + step: step, + inputHint: inputHint, + url: url, + encoding: encoding, + service: service, + period: period, + yAxisDecimalPattern: yAxisDecimalPattern, + legend: legend, + forceAsItem: forceAsItem, + row: row, + column: column, + command: command, + releaseCommand: releaseCommand, + stateless: stateless, + state: state, + item: item, + linkedPage: linkedPage, + widgets: widgets + )) + } + + enum CodingKeys: String, CodingKey { + case widgetId + case _type = "type" + case name + case visibility + case label + case labelSource + case icon + case staticIcon + case labelcolor + case valuecolor + case iconcolor + case pattern + case unit + case mappings + case switchSupport + case releaseOnly + case sendFrequency + case refresh + case height + case minValue + case maxValue + case step + case inputHint + case url + case encoding + case service + case period + case yAxisDecimalPattern + case legend + case forceAsItem + case row + case column + case command + case releaseCommand + case stateless + case state + case item + case linkedPage + case widgets + } + + init(from decoder: any Decoder) throws { + storage = try .init(from: decoder) + } + + func encode(to encoder: any Encoder) throws { + try storage.encode(to: encoder) + } + + /// Internal reference storage to allow type recursion. + private var storage: OpenAPIRuntime.CopyOnWriteBox + private struct Storage: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/WidgetDTO/widgetId`. + var widgetId: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/type`. + var _type: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/name`. + var name: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/visibility`. + var visibility: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/label`. + var label: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/labelSource`. + var labelSource: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/icon`. + var icon: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/staticIcon`. + var staticIcon: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/labelcolor`. + var labelcolor: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/valuecolor`. + var valuecolor: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/iconcolor`. + var iconcolor: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/pattern`. + var pattern: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/unit`. + var unit: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/mappings`. + var mappings: [Components.Schemas.MappingDTO]? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/switchSupport`. + var switchSupport: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/releaseOnly`. + var releaseOnly: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/sendFrequency`. + var sendFrequency: Swift.Int32? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/refresh`. + var refresh: Swift.Int32? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/height`. + var height: Swift.Int32? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/minValue`. + var minValue: Swift.Double? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/maxValue`. + var maxValue: Swift.Double? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/step`. + var step: Swift.Double? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/inputHint`. + var inputHint: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/url`. + var url: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/encoding`. + var encoding: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/service`. + var service: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/period`. + var period: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/yAxisDecimalPattern`. + var yAxisDecimalPattern: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/legend`. + var legend: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/forceAsItem`. + var forceAsItem: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/row`. + var row: Swift.Int32? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/column`. + var column: Swift.Int32? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/command`. + var command: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/releaseCommand`. + var releaseCommand: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/stateless`. + var stateless: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/state`. + var state: Swift.String? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/item`. + var item: Components.Schemas.EnrichedItemDTO? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/linkedPage`. + var linkedPage: Components.Schemas.PageDTO? + /// - Remark: Generated from `#/components/schemas/WidgetDTO/widgets`. + var widgets: [Components.Schemas.WidgetDTO]? + init(widgetId: Swift.String? = nil, + _type: Swift.String? = nil, + name: Swift.String? = nil, + visibility: Swift.Bool? = nil, + label: Swift.String? = nil, + labelSource: Swift.String? = nil, + icon: Swift.String? = nil, + staticIcon: Swift.Bool? = nil, + labelcolor: Swift.String? = nil, + valuecolor: Swift.String? = nil, + iconcolor: Swift.String? = nil, + pattern: Swift.String? = nil, + unit: Swift.String? = nil, + mappings: [Components.Schemas.MappingDTO]? = nil, + switchSupport: Swift.Bool? = nil, + releaseOnly: Swift.Bool? = nil, + sendFrequency: Swift.Int32? = nil, + refresh: Swift.Int32? = nil, + height: Swift.Int32? = nil, + minValue: Swift.Double? = nil, + maxValue: Swift.Double? = nil, + step: Swift.Double? = nil, + inputHint: Swift.String? = nil, + url: Swift.String? = nil, + encoding: Swift.String? = nil, + service: Swift.String? = nil, + period: Swift.String? = nil, + yAxisDecimalPattern: Swift.String? = nil, + legend: Swift.Bool? = nil, + forceAsItem: Swift.Bool? = nil, + row: Swift.Int32? = nil, + column: Swift.Int32? = nil, + command: Swift.String? = nil, + releaseCommand: Swift.String? = nil, + stateless: Swift.Bool? = nil, + state: Swift.String? = nil, + item: Components.Schemas.EnrichedItemDTO? = nil, + linkedPage: Components.Schemas.PageDTO? = nil, + widgets: [Components.Schemas.WidgetDTO]? = nil) { + self.widgetId = widgetId + self._type = _type + self.name = name + self.visibility = visibility + self.label = label + self.labelSource = labelSource + self.icon = icon + self.staticIcon = staticIcon + self.labelcolor = labelcolor + self.valuecolor = valuecolor + self.iconcolor = iconcolor + self.pattern = pattern + self.unit = unit + self.mappings = mappings + self.switchSupport = switchSupport + self.releaseOnly = releaseOnly + self.sendFrequency = sendFrequency + self.refresh = refresh + self.height = height + self.minValue = minValue + self.maxValue = maxValue + self.step = step + self.inputHint = inputHint + self.url = url + self.encoding = encoding + self.service = service + self.period = period + self.yAxisDecimalPattern = yAxisDecimalPattern + self.legend = legend + self.forceAsItem = forceAsItem + self.row = row + self.column = column + self.command = command + self.releaseCommand = releaseCommand + self.stateless = stateless + self.state = state + self.item = item + self.linkedPage = linkedPage + self.widgets = widgets + } + + typealias CodingKeys = Components.Schemas.WidgetDTO.CodingKeys + } + } + + /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent`. + struct SitemapWidgetEvent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/widgetId`. + var widgetId: Swift.String? + /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/label`. + var label: Swift.String? + /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/labelSource`. + var labelSource: Swift.String? + /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/icon`. + var icon: Swift.String? + /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/labelcolor`. + var labelcolor: Swift.String? + /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/valuecolor`. + var valuecolor: Swift.String? + /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/iconcolor`. + var iconcolor: Swift.String? + /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/state`. + var state: Swift.String? + /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/reloadIcon`. + var reloadIcon: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/visibility`. + var visibility: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/descriptionChanged`. + var descriptionChanged: Swift.Bool? + /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/item`. + var item: Components.Schemas.EnrichedItemDTO? + /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/sitemapName`. + var sitemapName: Swift.String? + /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/pageId`. + var pageId: Swift.String? + /// Creates a new `SitemapWidgetEvent`. + /// + /// - Parameters: + /// - widgetId: + /// - label: + /// - labelSource: + /// - icon: + /// - labelcolor: + /// - valuecolor: + /// - iconcolor: + /// - state: + /// - reloadIcon: + /// - visibility: + /// - descriptionChanged: + /// - item: + /// - sitemapName: + /// - pageId: + init(widgetId: Swift.String? = nil, + label: Swift.String? = nil, + labelSource: Swift.String? = nil, + icon: Swift.String? = nil, + labelcolor: Swift.String? = nil, + valuecolor: Swift.String? = nil, + iconcolor: Swift.String? = nil, + state: Swift.String? = nil, + reloadIcon: Swift.Bool? = nil, + visibility: Swift.Bool? = nil, + descriptionChanged: Swift.Bool? = nil, + item: Components.Schemas.EnrichedItemDTO? = nil, + sitemapName: Swift.String? = nil, + pageId: Swift.String? = nil) { + self.widgetId = widgetId + self.label = label + self.labelSource = labelSource + self.icon = icon + self.labelcolor = labelcolor + self.valuecolor = valuecolor + self.iconcolor = iconcolor + self.state = state + self.reloadIcon = reloadIcon + self.visibility = visibility + self.descriptionChanged = descriptionChanged + self.item = item + self.sitemapName = sitemapName + self.pageId = pageId + } + + enum CodingKeys: String, CodingKey { + case widgetId + case label + case labelSource + case icon + case labelcolor + case valuecolor + case iconcolor + case state + case reloadIcon + case visibility + case descriptionChanged + case item + case sitemapName + case pageId + } + } + + /// - Remark: Generated from `#/components/schemas/SitemapDTO`. + struct SitemapDTO: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/SitemapDTO/name`. + var name: Swift.String? + /// - Remark: Generated from `#/components/schemas/SitemapDTO/icon`. + var icon: Swift.String? + /// - Remark: Generated from `#/components/schemas/SitemapDTO/label`. + var label: Swift.String? + /// - Remark: Generated from `#/components/schemas/SitemapDTO/link`. + var link: Swift.String? + /// - Remark: Generated from `#/components/schemas/SitemapDTO/homepage`. + var homepage: Components.Schemas.PageDTO? + /// Creates a new `SitemapDTO`. + /// + /// - Parameters: + /// - name: + /// - icon: + /// - label: + /// - link: + /// - homepage: + init(name: Swift.String? = nil, + icon: Swift.String? = nil, + label: Swift.String? = nil, + link: Swift.String? = nil, + homepage: Components.Schemas.PageDTO? = nil) { + self.name = name + self.icon = icon + self.label = label + self.link = link + self.homepage = homepage + } + + enum CodingKeys: String, CodingKey { + case name + case icon + case label + case link + case homepage + } + } + + /// - Remark: Generated from `#/components/schemas/RootUIComponent`. + struct RootUIComponent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/RootUIComponent/component`. + var component: Swift.String? + /// - Remark: Generated from `#/components/schemas/RootUIComponent/config`. + struct configPayload: Codable, Hashable, Sendable { + /// A container of undocumented properties. + var additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] + /// Creates a new `configPayload`. + /// + /// - Parameters: + /// - additionalProperties: A container of undocumented properties. + init(additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] = .init()) { + self.additionalProperties = additionalProperties + } + + init(from decoder: any Decoder) throws { + additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) + } + + func encode(to encoder: any Encoder) throws { + try encoder.encodeAdditionalProperties(additionalProperties) + } + } + + /// - Remark: Generated from `#/components/schemas/RootUIComponent/config`. + var config: Components.Schemas.RootUIComponent.configPayload? + /// - Remark: Generated from `#/components/schemas/RootUIComponent/slots`. + struct slotsPayload: Codable, Hashable, Sendable { + /// A container of undocumented properties. + var additionalProperties: [String: [Components.Schemas.UIComponent]] + /// Creates a new `slotsPayload`. + /// + /// - Parameters: + /// - additionalProperties: A container of undocumented properties. + init(additionalProperties: [String: [Components.Schemas.UIComponent]] = .init()) { + self.additionalProperties = additionalProperties + } + + init(from decoder: any Decoder) throws { + additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) + } + + func encode(to encoder: any Encoder) throws { + try encoder.encodeAdditionalProperties(additionalProperties) + } + } + + /// - Remark: Generated from `#/components/schemas/RootUIComponent/slots`. + var slots: Components.Schemas.RootUIComponent.slotsPayload? + /// - Remark: Generated from `#/components/schemas/RootUIComponent/uid`. + var uid: Swift.String? + /// - Remark: Generated from `#/components/schemas/RootUIComponent/tags`. + var tags: [Swift.String]? + /// - Remark: Generated from `#/components/schemas/RootUIComponent/props`. + var props: Components.Schemas.ConfigDescriptionDTO? + /// - Remark: Generated from `#/components/schemas/RootUIComponent/timestamp`. + var timestamp: Foundation.Date? + /// - Remark: Generated from `#/components/schemas/RootUIComponent/type`. + var _type: Swift.String? + /// Creates a new `RootUIComponent`. + /// + /// - Parameters: + /// - component: + /// - config: + /// - slots: + /// - uid: + /// - tags: + /// - props: + /// - timestamp: + /// - _type: + init(component: Swift.String? = nil, + config: Components.Schemas.RootUIComponent.configPayload? = nil, + slots: Components.Schemas.RootUIComponent.slotsPayload? = nil, + uid: Swift.String? = nil, + tags: [Swift.String]? = nil, + props: Components.Schemas.ConfigDescriptionDTO? = nil, + timestamp: Foundation.Date? = nil, + _type: Swift.String? = nil) { + self.component = component + self.config = config + self.slots = slots + self.uid = uid + self.tags = tags + self.props = props + self.timestamp = timestamp + self._type = _type + } + + enum CodingKeys: String, CodingKey { + case component + case config + case slots + case uid + case tags + case props + case timestamp + case _type = "type" + } + } + + /// - Remark: Generated from `#/components/schemas/UIComponent`. + struct UIComponent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/UIComponent/component`. + var component: Swift.String? + /// - Remark: Generated from `#/components/schemas/UIComponent/config`. + struct configPayload: Codable, Hashable, Sendable { + /// A container of undocumented properties. + var additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] + /// Creates a new `configPayload`. + /// + /// - Parameters: + /// - additionalProperties: A container of undocumented properties. + init(additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] = .init()) { + self.additionalProperties = additionalProperties + } + + init(from decoder: any Decoder) throws { + additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) + } + + func encode(to encoder: any Encoder) throws { + try encoder.encodeAdditionalProperties(additionalProperties) + } + } + + /// - Remark: Generated from `#/components/schemas/UIComponent/config`. + var config: Components.Schemas.UIComponent.configPayload? + /// - Remark: Generated from `#/components/schemas/UIComponent/type`. + var _type: Swift.String? + /// Creates a new `UIComponent`. + /// + /// - Parameters: + /// - component: + /// - config: + /// - _type: + init(component: Swift.String? = nil, + config: Components.Schemas.UIComponent.configPayload? = nil, + _type: Swift.String? = nil) { + self.component = component + self.config = config + self._type = _type + } + + enum CodingKeys: String, CodingKey { + case component + case config + case _type = "type" + } + } + + /// - Remark: Generated from `#/components/schemas/TileDTO`. + struct TileDTO: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/TileDTO/name`. + var name: Swift.String? + /// - Remark: Generated from `#/components/schemas/TileDTO/url`. + var url: Swift.String? + /// - Remark: Generated from `#/components/schemas/TileDTO/overlay`. + var overlay: Swift.String? + /// - Remark: Generated from `#/components/schemas/TileDTO/imageUrl`. + var imageUrl: Swift.String? + /// Creates a new `TileDTO`. + /// + /// - Parameters: + /// - name: + /// - url: + /// - overlay: + /// - imageUrl: + init(name: Swift.String? = nil, + url: Swift.String? = nil, + overlay: Swift.String? = nil, + imageUrl: Swift.String? = nil) { + self.name = name + self.url = url + self.overlay = overlay + self.imageUrl = imageUrl + } + + enum CodingKeys: String, CodingKey { + case name + case url + case overlay + case imageUrl + } + } + } + + /// Types generated from the `#/components/parameters` section of the OpenAPI document. + enum Parameters {} + /// Types generated from the `#/components/requestBodies` section of the OpenAPI document. + enum RequestBodies {} + /// Types generated from the `#/components/responses` section of the OpenAPI document. + enum Responses {} + /// Types generated from the `#/components/headers` section of the OpenAPI document. + enum Headers {} +} + +/// API operations, with input and output types, generated from `#/paths` in the OpenAPI document. +enum Operations { + /// Adds a new member to a group item. + /// + /// - Remark: HTTP `PUT /items/{itemName}/members/{memberItemName}`. + /// - Remark: Generated from `#/paths//items/{itemName}/members/{memberItemName}/put(addMemberToGroupItem)`. + enum addMemberToGroupItem { + static let id: Swift.String = "addMemberToGroupItem" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemName}/members/{memberItemName}/PUT/path`. + struct Path: Sendable, Hashable { + /// item name + /// + /// - Remark: Generated from `#/paths/items/{itemName}/members/{memberItemName}/PUT/path/itemName`. + var itemName: Swift.String + /// member item name + /// + /// - Remark: Generated from `#/paths/items/{itemName}/members/{memberItemName}/PUT/path/memberItemName`. + var memberItemName: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - itemName: item name + /// - memberItemName: member item name + init(itemName: Swift.String, + memberItemName: Swift.String) { + self.itemName = itemName + self.memberItemName = memberItemName + } + } + + var path: Operations.addMemberToGroupItem.Input.Path + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + init(path: Operations.addMemberToGroupItem.Input.Path) { + self.path = path + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// Creates a new `Ok`. + init() {} + } + + /// OK + /// + /// - Remark: Generated from `#/paths//items/{itemName}/members/{memberItemName}/put(addMemberToGroupItem)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.addMemberToGroupItem.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.addMemberToGroupItem.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Item or member item not found or item is not of type group item. + /// + /// - Remark: Generated from `#/paths//items/{itemName}/members/{memberItemName}/put(addMemberToGroupItem)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.addMemberToGroupItem.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.addMemberToGroupItem.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + struct MethodNotAllowed: Sendable, Hashable { + /// Creates a new `MethodNotAllowed`. + init() {} + } + + /// Member item is not editable. + /// + /// - Remark: Generated from `#/paths//items/{itemName}/members/{memberItemName}/put(addMemberToGroupItem)/responses/405`. + /// + /// HTTP response code: `405 methodNotAllowed`. + case methodNotAllowed(Operations.addMemberToGroupItem.Output.MethodNotAllowed) + /// The associated value of the enum case if `self` is `.methodNotAllowed`. + /// + /// - Throws: An error if `self` is not `.methodNotAllowed`. + /// - SeeAlso: `.methodNotAllowed`. + var methodNotAllowed: Operations.addMemberToGroupItem.Output.MethodNotAllowed { + get throws { + switch self { + case let .methodNotAllowed(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "methodNotAllowed", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + } + + /// Removes an existing member from a group item. + /// + /// - Remark: HTTP `DELETE /items/{itemName}/members/{memberItemName}`. + /// - Remark: Generated from `#/paths//items/{itemName}/members/{memberItemName}/delete(removeMemberFromGroupItem)`. + enum removeMemberFromGroupItem { + static let id: Swift.String = "removeMemberFromGroupItem" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemName}/members/{memberItemName}/DELETE/path`. + struct Path: Sendable, Hashable { + /// item name + /// + /// - Remark: Generated from `#/paths/items/{itemName}/members/{memberItemName}/DELETE/path/itemName`. + var itemName: Swift.String + /// member item name + /// + /// - Remark: Generated from `#/paths/items/{itemName}/members/{memberItemName}/DELETE/path/memberItemName`. + var memberItemName: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - itemName: item name + /// - memberItemName: member item name + init(itemName: Swift.String, + memberItemName: Swift.String) { + self.itemName = itemName + self.memberItemName = memberItemName + } + } + + var path: Operations.removeMemberFromGroupItem.Input.Path + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + init(path: Operations.removeMemberFromGroupItem.Input.Path) { + self.path = path + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// Creates a new `Ok`. + init() {} + } + + /// OK + /// + /// - Remark: Generated from `#/paths//items/{itemName}/members/{memberItemName}/delete(removeMemberFromGroupItem)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.removeMemberFromGroupItem.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.removeMemberFromGroupItem.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Item or member item not found or item is not of type group item. + /// + /// - Remark: Generated from `#/paths//items/{itemName}/members/{memberItemName}/delete(removeMemberFromGroupItem)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.removeMemberFromGroupItem.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.removeMemberFromGroupItem.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + struct MethodNotAllowed: Sendable, Hashable { + /// Creates a new `MethodNotAllowed`. + init() {} + } + + /// Member item is not editable. + /// + /// - Remark: Generated from `#/paths//items/{itemName}/members/{memberItemName}/delete(removeMemberFromGroupItem)/responses/405`. + /// + /// HTTP response code: `405 methodNotAllowed`. + case methodNotAllowed(Operations.removeMemberFromGroupItem.Output.MethodNotAllowed) + /// The associated value of the enum case if `self` is `.methodNotAllowed`. + /// + /// - Throws: An error if `self` is not `.methodNotAllowed`. + /// - SeeAlso: `.methodNotAllowed`. + var methodNotAllowed: Operations.removeMemberFromGroupItem.Output.MethodNotAllowed { + get throws { + switch self { + case let .methodNotAllowed(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "methodNotAllowed", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + } + + /// Adds metadata to an item. + /// + /// - Remark: HTTP `PUT /items/{itemname}/metadata/{namespace}`. + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/put(addMetadataToItem)`. + enum addMetadataToItem { + static let id: Swift.String = "addMetadataToItem" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/metadata/{namespace}/PUT/path`. + struct Path: Sendable, Hashable { + /// item name + /// + /// - Remark: Generated from `#/paths/items/{itemname}/metadata/{namespace}/PUT/path/itemname`. + var itemname: Swift.String + /// namespace + /// + /// - Remark: Generated from `#/paths/items/{itemname}/metadata/{namespace}/PUT/path/namespace`. + var namespace: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - itemname: item name + /// - namespace: namespace + init(itemname: Swift.String, + namespace: Swift.String) { + self.itemname = itemname + self.namespace = namespace + } + } + + var path: Operations.addMetadataToItem.Input.Path + /// - Remark: Generated from `#/paths/items/{itemname}/metadata/{namespace}/PUT/requestBody`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/metadata/{namespace}/PUT/requestBody/content/application\/json`. + case json(Components.Schemas.MetadataDTO) + } + + var body: Operations.addMetadataToItem.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - body: + init(path: Operations.addMetadataToItem.Input.Path, + body: Operations.addMetadataToItem.Input.Body) { + self.path = path + self.body = body + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// Creates a new `Ok`. + init() {} + } + + /// OK + /// + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/put(addMetadataToItem)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.addMetadataToItem.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.addMetadataToItem.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct Created: Sendable, Hashable { + /// Creates a new `Created`. + init() {} + } + + /// Created + /// + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/put(addMetadataToItem)/responses/201`. + /// + /// HTTP response code: `201 created`. + case created(Operations.addMetadataToItem.Output.Created) + /// The associated value of the enum case if `self` is `.created`. + /// + /// - Throws: An error if `self` is not `.created`. + /// - SeeAlso: `.created`. + var created: Operations.addMetadataToItem.Output.Created { + get throws { + switch self { + case let .created(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "created", + response: self + ) + } + } + } + + struct BadRequest: Sendable, Hashable { + /// Creates a new `BadRequest`. + init() {} + } + + /// Metadata value empty. + /// + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/put(addMetadataToItem)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.addMetadataToItem.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + var badRequest: Operations.addMetadataToItem.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Item not found. + /// + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/put(addMetadataToItem)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.addMetadataToItem.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.addMetadataToItem.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + struct MethodNotAllowed: Sendable, Hashable { + /// Creates a new `MethodNotAllowed`. + init() {} + } + + /// Metadata not editable. + /// + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/put(addMetadataToItem)/responses/405`. + /// + /// HTTP response code: `405 methodNotAllowed`. + case methodNotAllowed(Operations.addMetadataToItem.Output.MethodNotAllowed) + /// The associated value of the enum case if `self` is `.methodNotAllowed`. + /// + /// - Throws: An error if `self` is not `.methodNotAllowed`. + /// - SeeAlso: `.methodNotAllowed`. + var methodNotAllowed: Operations.addMetadataToItem.Output.MethodNotAllowed { + get throws { + switch self { + case let .methodNotAllowed(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "methodNotAllowed", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + } + + /// Removes metadata from an item. + /// + /// - Remark: HTTP `DELETE /items/{itemname}/metadata/{namespace}`. + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/delete(removeMetadataFromItem)`. + enum removeMetadataFromItem { + static let id: Swift.String = "removeMetadataFromItem" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/metadata/{namespace}/DELETE/path`. + struct Path: Sendable, Hashable { + /// item name + /// + /// - Remark: Generated from `#/paths/items/{itemname}/metadata/{namespace}/DELETE/path/itemname`. + var itemname: Swift.String + /// namespace + /// + /// - Remark: Generated from `#/paths/items/{itemname}/metadata/{namespace}/DELETE/path/namespace`. + var namespace: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - itemname: item name + /// - namespace: namespace + init(itemname: Swift.String, + namespace: Swift.String) { + self.itemname = itemname + self.namespace = namespace + } + } + + var path: Operations.removeMetadataFromItem.Input.Path + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + init(path: Operations.removeMetadataFromItem.Input.Path) { + self.path = path + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// Creates a new `Ok`. + init() {} + } + + /// OK + /// + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/delete(removeMetadataFromItem)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.removeMetadataFromItem.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.removeMetadataFromItem.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Item not found. + /// + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/delete(removeMetadataFromItem)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.removeMetadataFromItem.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.removeMetadataFromItem.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + struct MethodNotAllowed: Sendable, Hashable { + /// Creates a new `MethodNotAllowed`. + init() {} + } + + /// Meta data not editable. + /// + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/delete(removeMetadataFromItem)/responses/405`. + /// + /// HTTP response code: `405 methodNotAllowed`. + case methodNotAllowed(Operations.removeMetadataFromItem.Output.MethodNotAllowed) + /// The associated value of the enum case if `self` is `.methodNotAllowed`. + /// + /// - Throws: An error if `self` is not `.methodNotAllowed`. + /// - SeeAlso: `.methodNotAllowed`. + var methodNotAllowed: Operations.removeMetadataFromItem.Output.MethodNotAllowed { + get throws { + switch self { + case let .methodNotAllowed(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "methodNotAllowed", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + } + + /// Adds a tag to an item. + /// + /// - Remark: HTTP `PUT /items/{itemname}/tags/{tag}`. + /// - Remark: Generated from `#/paths//items/{itemname}/tags/{tag}/put(addTagToItem)`. + enum addTagToItem { + static let id: Swift.String = "addTagToItem" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/tags/{tag}/PUT/path`. + struct Path: Sendable, Hashable { + /// item name + /// + /// - Remark: Generated from `#/paths/items/{itemname}/tags/{tag}/PUT/path/itemname`. + var itemname: Swift.String + /// tag + /// + /// - Remark: Generated from `#/paths/items/{itemname}/tags/{tag}/PUT/path/tag`. + var tag: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - itemname: item name + /// - tag: tag + init(itemname: Swift.String, + tag: Swift.String) { + self.itemname = itemname + self.tag = tag + } + } + + var path: Operations.addTagToItem.Input.Path + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + init(path: Operations.addTagToItem.Input.Path) { + self.path = path + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// Creates a new `Ok`. + init() {} + } + + /// OK + /// + /// - Remark: Generated from `#/paths//items/{itemname}/tags/{tag}/put(addTagToItem)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.addTagToItem.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.addTagToItem.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Item not found. + /// + /// - Remark: Generated from `#/paths//items/{itemname}/tags/{tag}/put(addTagToItem)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.addTagToItem.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.addTagToItem.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + struct MethodNotAllowed: Sendable, Hashable { + /// Creates a new `MethodNotAllowed`. + init() {} + } + + /// Item not editable. + /// + /// - Remark: Generated from `#/paths//items/{itemname}/tags/{tag}/put(addTagToItem)/responses/405`. + /// + /// HTTP response code: `405 methodNotAllowed`. + case methodNotAllowed(Operations.addTagToItem.Output.MethodNotAllowed) + /// The associated value of the enum case if `self` is `.methodNotAllowed`. + /// + /// - Throws: An error if `self` is not `.methodNotAllowed`. + /// - SeeAlso: `.methodNotAllowed`. + var methodNotAllowed: Operations.addTagToItem.Output.MethodNotAllowed { + get throws { + switch self { + case let .methodNotAllowed(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "methodNotAllowed", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + } + + /// Removes a tag from an item. + /// + /// - Remark: HTTP `DELETE /items/{itemname}/tags/{tag}`. + /// - Remark: Generated from `#/paths//items/{itemname}/tags/{tag}/delete(removeTagFromItem)`. + enum removeTagFromItem { + static let id: Swift.String = "removeTagFromItem" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/tags/{tag}/DELETE/path`. + struct Path: Sendable, Hashable { + /// item name + /// + /// - Remark: Generated from `#/paths/items/{itemname}/tags/{tag}/DELETE/path/itemname`. + var itemname: Swift.String + /// tag + /// + /// - Remark: Generated from `#/paths/items/{itemname}/tags/{tag}/DELETE/path/tag`. + var tag: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - itemname: item name + /// - tag: tag + init(itemname: Swift.String, + tag: Swift.String) { + self.itemname = itemname + self.tag = tag + } + } + + var path: Operations.removeTagFromItem.Input.Path + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + init(path: Operations.removeTagFromItem.Input.Path) { + self.path = path + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// Creates a new `Ok`. + init() {} + } + + /// OK + /// + /// - Remark: Generated from `#/paths//items/{itemname}/tags/{tag}/delete(removeTagFromItem)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.removeTagFromItem.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.removeTagFromItem.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Item not found. + /// + /// - Remark: Generated from `#/paths//items/{itemname}/tags/{tag}/delete(removeTagFromItem)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.removeTagFromItem.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.removeTagFromItem.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + struct MethodNotAllowed: Sendable, Hashable { + /// Creates a new `MethodNotAllowed`. + init() {} + } + + /// Item not editable. + /// + /// - Remark: Generated from `#/paths//items/{itemname}/tags/{tag}/delete(removeTagFromItem)/responses/405`. + /// + /// HTTP response code: `405 methodNotAllowed`. + case methodNotAllowed(Operations.removeTagFromItem.Output.MethodNotAllowed) + /// The associated value of the enum case if `self` is `.methodNotAllowed`. + /// + /// - Throws: An error if `self` is not `.methodNotAllowed`. + /// - SeeAlso: `.methodNotAllowed`. + var methodNotAllowed: Operations.removeTagFromItem.Output.MethodNotAllowed { + get throws { + switch self { + case let .methodNotAllowed(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "methodNotAllowed", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + } + + /// Gets a single item. + /// + /// - Remark: HTTP `GET /items/{itemname}`. + /// - Remark: Generated from `#/paths//items/{itemname}/get(getItemByName)`. + enum getItemByName { + static let id: Swift.String = "getItemByName" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/GET/path`. + struct Path: Sendable, Hashable { + /// item name + /// + /// - Remark: Generated from `#/paths/items/{itemname}/GET/path/itemname`. + var itemname: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - itemname: item name + init(itemname: Swift.String) { + self.itemname = itemname + } + } + + var path: Operations.getItemByName.Input.Path + /// - Remark: Generated from `#/paths/items/{itemname}/GET/query`. + struct Query: Sendable, Hashable { + /// metadata selector - a comma separated list or a regular expression (returns all if no value given) + /// + /// - Remark: Generated from `#/paths/items/{itemname}/GET/query/metadata`. + var metadata: Swift.String? + /// get member items if the item is a group item + /// + /// - Remark: Generated from `#/paths/items/{itemname}/GET/query/recursive`. + var recursive: Swift.Bool? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - metadata: metadata selector - a comma separated list or a regular expression (returns all if no value given) + /// - recursive: get member items if the item is a group item + init(metadata: Swift.String? = nil, + recursive: Swift.Bool? = nil) { + self.metadata = metadata + self.recursive = recursive + } + } + + var query: Operations.getItemByName.Input.Query + /// - Remark: Generated from `#/paths/items/{itemname}/GET/header`. + struct Headers: Sendable, Hashable { + /// language + /// + /// - Remark: Generated from `#/paths/items/{itemname}/GET/header/Accept-Language`. + var Accept_hyphen_Language: Swift.String? + var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Accept_hyphen_Language: language + /// - accept: + init(Accept_hyphen_Language: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.Accept_hyphen_Language = Accept_hyphen_Language + self.accept = accept + } + } + + var headers: Operations.getItemByName.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + init(path: Operations.getItemByName.Input.Path, + query: Operations.getItemByName.Input.Query = .init(), + headers: Operations.getItemByName.Input.Headers = .init()) { + self.path = path + self.query = query + self.headers = headers + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/GET/responses/200/content`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/GET/responses/200/content/application\/json`. + case json(Components.Schemas.EnrichedItemDTO) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + var json: Components.Schemas.EnrichedItemDTO { + get throws { + switch self { + case let .json(body): + body + } + } + } + } + + /// Received HTTP response body + var body: Operations.getItemByName.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + init(body: Operations.getItemByName.Output.Ok.Body) { + self.body = body + } + } + + /// OK + /// + /// - Remark: Generated from `#/paths//items/{itemname}/get(getItemByName)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.getItemByName.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.getItemByName.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Item not found + /// + /// - Remark: Generated from `#/paths//items/{itemname}/get(getItemByName)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.getItemByName.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.getItemByName.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + + enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + + var rawValue: Swift.String { + switch self { + case let .other(string): + string + case .json: + "application/json" + } + } + + static var allCases: [Self] { + [ + .json + ] + } + } + } + + /// Sends a command to an item. + /// + /// - Remark: HTTP `POST /items/{itemname}`. + /// - Remark: Generated from `#/paths//items/{itemname}/post(sendItemCommand)`. + enum sendItemCommand { + static let id: Swift.String = "sendItemCommand" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/POST/path`. + struct Path: Sendable, Hashable { + /// item name + /// + /// - Remark: Generated from `#/paths/items/{itemname}/POST/path/itemname`. + var itemname: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - itemname: item name + init(itemname: Swift.String) { + self.itemname = itemname + } + } + + var path: Operations.sendItemCommand.Input.Path + /// - Remark: Generated from `#/paths/items/{itemname}/POST/requestBody`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/POST/requestBody/content/text\/plain`. + case plainText(OpenAPIRuntime.HTTPBody) + } + + var body: Operations.sendItemCommand.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - body: + init(path: Operations.sendItemCommand.Input.Path, + body: Operations.sendItemCommand.Input.Body) { + self.path = path + self.body = body + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// Creates a new `Ok`. + init() {} + } + + /// OK + /// + /// - Remark: Generated from `#/paths//items/{itemname}/post(sendItemCommand)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.sendItemCommand.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.sendItemCommand.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct BadRequest: Sendable, Hashable { + /// Creates a new `BadRequest`. + init() {} + } + + /// Item command null + /// + /// - Remark: Generated from `#/paths//items/{itemname}/post(sendItemCommand)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.sendItemCommand.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + var badRequest: Operations.sendItemCommand.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Item not found + /// + /// - Remark: Generated from `#/paths//items/{itemname}/post(sendItemCommand)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.sendItemCommand.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.sendItemCommand.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + } + + /// Adds a new item to the registry or updates the existing item. + /// + /// - Remark: HTTP `PUT /items/{itemname}`. + /// - Remark: Generated from `#/paths//items/{itemname}/put(addOrUpdateItemInRegistry)`. + enum addOrUpdateItemInRegistry { + static let id: Swift.String = "addOrUpdateItemInRegistry" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/PUT/path`. + struct Path: Sendable, Hashable { + /// item name + /// + /// - Remark: Generated from `#/paths/items/{itemname}/PUT/path/itemname`. + var itemname: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - itemname: item name + init(itemname: Swift.String) { + self.itemname = itemname + } + } + + var path: Operations.addOrUpdateItemInRegistry.Input.Path + /// - Remark: Generated from `#/paths/items/{itemname}/PUT/header`. + struct Headers: Sendable, Hashable { + /// language + /// + /// - Remark: Generated from `#/paths/items/{itemname}/PUT/header/Accept-Language`. + var Accept_hyphen_Language: Swift.String? + var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Accept_hyphen_Language: language + /// - accept: + init(Accept_hyphen_Language: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.Accept_hyphen_Language = Accept_hyphen_Language + self.accept = accept + } + } + + var headers: Operations.addOrUpdateItemInRegistry.Input.Headers + /// - Remark: Generated from `#/paths/items/{itemname}/PUT/requestBody`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/PUT/requestBody/content/application\/json`. + case json(Components.Schemas.GroupItemDTO) + } + + var body: Operations.addOrUpdateItemInRegistry.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + init(path: Operations.addOrUpdateItemInRegistry.Input.Path, + headers: Operations.addOrUpdateItemInRegistry.Input.Headers = .init(), + body: Operations.addOrUpdateItemInRegistry.Input.Body) { + self.path = path + self.headers = headers + self.body = body + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/PUT/responses/200/content`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/PUT/responses/200/content/*\/*`. + case any(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.any`. + /// + /// - Throws: An error if `self` is not `.any`. + /// - SeeAlso: `.any`. + var any: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .any(body): + body + } + } + } + } + + /// Received HTTP response body + var body: Operations.addOrUpdateItemInRegistry.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + init(body: Operations.addOrUpdateItemInRegistry.Output.Ok.Body) { + self.body = body + } + } + + /// OK + /// + /// - Remark: Generated from `#/paths//items/{itemname}/put(addOrUpdateItemInRegistry)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.addOrUpdateItemInRegistry.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.addOrUpdateItemInRegistry.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct Created: Sendable, Hashable { + /// Creates a new `Created`. + init() {} + } + + /// Item created. + /// + /// - Remark: Generated from `#/paths//items/{itemname}/put(addOrUpdateItemInRegistry)/responses/201`. + /// + /// HTTP response code: `201 created`. + case created(Operations.addOrUpdateItemInRegistry.Output.Created) + /// The associated value of the enum case if `self` is `.created`. + /// + /// - Throws: An error if `self` is not `.created`. + /// - SeeAlso: `.created`. + var created: Operations.addOrUpdateItemInRegistry.Output.Created { + get throws { + switch self { + case let .created(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "created", + response: self + ) + } + } + } + + struct BadRequest: Sendable, Hashable { + /// Creates a new `BadRequest`. + init() {} + } + + /// Payload invalid. + /// + /// - Remark: Generated from `#/paths//items/{itemname}/put(addOrUpdateItemInRegistry)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.addOrUpdateItemInRegistry.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + var badRequest: Operations.addOrUpdateItemInRegistry.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Item not found or name in path invalid. + /// + /// - Remark: Generated from `#/paths//items/{itemname}/put(addOrUpdateItemInRegistry)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.addOrUpdateItemInRegistry.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.addOrUpdateItemInRegistry.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + struct MethodNotAllowed: Sendable, Hashable { + /// Creates a new `MethodNotAllowed`. + init() {} + } + + /// Item not editable. + /// + /// - Remark: Generated from `#/paths//items/{itemname}/put(addOrUpdateItemInRegistry)/responses/405`. + /// + /// HTTP response code: `405 methodNotAllowed`. + case methodNotAllowed(Operations.addOrUpdateItemInRegistry.Output.MethodNotAllowed) + /// The associated value of the enum case if `self` is `.methodNotAllowed`. + /// + /// - Throws: An error if `self` is not `.methodNotAllowed`. + /// - SeeAlso: `.methodNotAllowed`. + var methodNotAllowed: Operations.addOrUpdateItemInRegistry.Output.MethodNotAllowed { + get throws { + switch self { + case let .methodNotAllowed(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "methodNotAllowed", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + + enum AcceptableContentType: AcceptableProtocol { + case any + case other(Swift.String) + init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "*/*": + self = .any + default: + self = .other(rawValue) + } + } + + var rawValue: Swift.String { + switch self { + case let .other(string): + string + case .any: + "*/*" + } + } + + static var allCases: [Self] { + [ + .any + ] + } + } + } + + /// Removes an item from the registry. + /// + /// - Remark: HTTP `DELETE /items/{itemname}`. + /// - Remark: Generated from `#/paths//items/{itemname}/delete(removeItemFromRegistry)`. + enum removeItemFromRegistry { + static let id: Swift.String = "removeItemFromRegistry" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/DELETE/path`. + struct Path: Sendable, Hashable { + /// item name + /// + /// - Remark: Generated from `#/paths/items/{itemname}/DELETE/path/itemname`. + var itemname: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - itemname: item name + init(itemname: Swift.String) { + self.itemname = itemname + } + } + + var path: Operations.removeItemFromRegistry.Input.Path + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + init(path: Operations.removeItemFromRegistry.Input.Path) { + self.path = path + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// Creates a new `Ok`. + init() {} + } + + /// OK + /// + /// - Remark: Generated from `#/paths//items/{itemname}/delete(removeItemFromRegistry)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.removeItemFromRegistry.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.removeItemFromRegistry.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Item not found or item is not editable. + /// + /// - Remark: Generated from `#/paths//items/{itemname}/delete(removeItemFromRegistry)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.removeItemFromRegistry.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.removeItemFromRegistry.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + } + + /// Get all available items. + /// + /// - Remark: HTTP `GET /items`. + /// - Remark: Generated from `#/paths//items/get(getItems)`. + enum getItems { + static let id: Swift.String = "getItems" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/GET/query`. + struct Query: Sendable, Hashable { + /// item type filter + /// + /// - Remark: Generated from `#/paths/items/GET/query/type`. + var _type: Swift.String? + /// item tag filter + /// + /// - Remark: Generated from `#/paths/items/GET/query/tags`. + var tags: Swift.String? + /// metadata selector - a comma separated list or a regular expression (returns all if no value given) + /// + /// - Remark: Generated from `#/paths/items/GET/query/metadata`. + var metadata: Swift.String? + /// get member items recursively + /// + /// - Remark: Generated from `#/paths/items/GET/query/recursive`. + var recursive: Swift.Bool? + /// limit output to the given fields (comma separated) + /// + /// - Remark: Generated from `#/paths/items/GET/query/fields`. + var fields: Swift.String? + /// provides a cacheable list of values not expected to change regularly and checks the If-Modified-Since header, all other parameters are ignored except "metadata" + /// + /// - Remark: Generated from `#/paths/items/GET/query/staticDataOnly`. + var staticDataOnly: Swift.Bool? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - _type: item type filter + /// - tags: item tag filter + /// - metadata: metadata selector - a comma separated list or a regular expression (returns all if no value given) + /// - recursive: get member items recursively + /// - fields: limit output to the given fields (comma separated) + /// - staticDataOnly: provides a cacheable list of values not expected to change regularly and checks the If-Modified-Since header, all other parameters are ignored except "metadata" + init(_type: Swift.String? = nil, + tags: Swift.String? = nil, + metadata: Swift.String? = nil, + recursive: Swift.Bool? = nil, + fields: Swift.String? = nil, + staticDataOnly: Swift.Bool? = nil) { + self._type = _type + self.tags = tags + self.metadata = metadata + self.recursive = recursive + self.fields = fields + self.staticDataOnly = staticDataOnly + } + } + + var query: Operations.getItems.Input.Query + /// - Remark: Generated from `#/paths/items/GET/header`. + struct Headers: Sendable, Hashable { + /// language + /// + /// - Remark: Generated from `#/paths/items/GET/header/Accept-Language`. + var Accept_hyphen_Language: Swift.String? + var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Accept_hyphen_Language: language + /// - accept: + init(Accept_hyphen_Language: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.Accept_hyphen_Language = Accept_hyphen_Language + self.accept = accept + } + } + + var headers: Operations.getItems.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - query: + /// - headers: + init(query: Operations.getItems.Input.Query = .init(), + headers: Operations.getItems.Input.Headers = .init()) { + self.query = query + self.headers = headers + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/GET/responses/200/content`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/GET/responses/200/content/application\/json`. + case json([Components.Schemas.EnrichedItemDTO]) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + var json: [Components.Schemas.EnrichedItemDTO] { + get throws { + switch self { + case let .json(body): + body + } + } + } + } + + /// Received HTTP response body + var body: Operations.getItems.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + init(body: Operations.getItems.Output.Ok.Body) { + self.body = body + } + } + + /// OK + /// + /// - Remark: Generated from `#/paths//items/get(getItems)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.getItems.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.getItems.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + + enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + + var rawValue: Swift.String { + switch self { + case let .other(string): + string + case .json: + "application/json" + } + } + + static var allCases: [Self] { + [ + .json + ] + } + } + } + + /// Adds a list of items to the registry or updates the existing items. + /// + /// - Remark: HTTP `PUT /items`. + /// - Remark: Generated from `#/paths//items/put(addOrUpdateItemsInRegistry)`. + enum addOrUpdateItemsInRegistry { + static let id: Swift.String = "addOrUpdateItemsInRegistry" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/PUT/header`. + struct Headers: Sendable, Hashable { + var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + + var headers: Operations.addOrUpdateItemsInRegistry.Input.Headers + /// - Remark: Generated from `#/paths/items/PUT/requestBody`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/PUT/requestBody/content/application\/json`. + case json([Components.Schemas.GroupItemDTO]) + } + + var body: Operations.addOrUpdateItemsInRegistry.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - headers: + /// - body: + init(headers: Operations.addOrUpdateItemsInRegistry.Input.Headers = .init(), + body: Operations.addOrUpdateItemsInRegistry.Input.Body) { + self.headers = headers + self.body = body + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/PUT/responses/200/content`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/PUT/responses/200/content/*\/*`. + case any(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.any`. + /// + /// - Throws: An error if `self` is not `.any`. + /// - SeeAlso: `.any`. + var any: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .any(body): + body + } + } + } + } + + /// Received HTTP response body + var body: Operations.addOrUpdateItemsInRegistry.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + init(body: Operations.addOrUpdateItemsInRegistry.Output.Ok.Body) { + self.body = body + } + } + + /// OK + /// + /// - Remark: Generated from `#/paths//items/put(addOrUpdateItemsInRegistry)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.addOrUpdateItemsInRegistry.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.addOrUpdateItemsInRegistry.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct BadRequest: Sendable, Hashable { + /// Creates a new `BadRequest`. + init() {} + } + + /// Payload is invalid. + /// + /// - Remark: Generated from `#/paths//items/put(addOrUpdateItemsInRegistry)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.addOrUpdateItemsInRegistry.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + var badRequest: Operations.addOrUpdateItemsInRegistry.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + + enum AcceptableContentType: AcceptableProtocol { + case any + case other(Swift.String) + init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "*/*": + self = .any + default: + self = .other(rawValue) + } + } + + var rawValue: Swift.String { + switch self { + case let .other(string): + string + case .any: + "*/*" + } + } + + static var allCases: [Self] { + [ + .any + ] + } + } + } + + /// Gets the state of an item. + /// + /// - Remark: HTTP `GET /items/{itemname}/state`. + /// - Remark: Generated from `#/paths//items/{itemname}/state/get(getItemState_1)`. + enum getItemState_1 { + static let id: Swift.String = "getItemState_1" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/state/GET/path`. + struct Path: Sendable, Hashable { + /// item name + /// + /// - Remark: Generated from `#/paths/items/{itemname}/state/GET/path/itemname`. + var itemname: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - itemname: item name + init(itemname: Swift.String) { + self.itemname = itemname + } + } + + var path: Operations.getItemState_1.Input.Path + /// - Remark: Generated from `#/paths/items/{itemname}/state/GET/header`. + struct Headers: Sendable, Hashable { + var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + + var headers: Operations.getItemState_1.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + init(path: Operations.getItemState_1.Input.Path, + headers: Operations.getItemState_1.Input.Headers = .init()) { + self.path = path + self.headers = headers + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/state/GET/responses/200/content`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/state/GET/responses/200/content/text\/plain`. + case plainText(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.plainText`. + /// + /// - Throws: An error if `self` is not `.plainText`. + /// - SeeAlso: `.plainText`. + var plainText: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .plainText(body): + body + } + } + } + } + + /// Received HTTP response body + var body: Operations.getItemState_1.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + init(body: Operations.getItemState_1.Output.Ok.Body) { + self.body = body + } + } + + /// OK + /// + /// - Remark: Generated from `#/paths//items/{itemname}/state/get(getItemState_1)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.getItemState_1.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.getItemState_1.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Item not found + /// + /// - Remark: Generated from `#/paths//items/{itemname}/state/get(getItemState_1)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.getItemState_1.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.getItemState_1.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + + enum AcceptableContentType: AcceptableProtocol { + case plainText + case other(Swift.String) + init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "text/plain": + self = .plainText + default: + self = .other(rawValue) + } + } + + var rawValue: Swift.String { + switch self { + case let .other(string): + string + case .plainText: + "text/plain" + } + } + + static var allCases: [Self] { + [ + .plainText + ] + } + } + } + + /// Updates the state of an item. + /// + /// - Remark: HTTP `PUT /items/{itemname}/state`. + /// - Remark: Generated from `#/paths//items/{itemname}/state/put(updateItemState)`. + enum updateItemState { + static let id: Swift.String = "updateItemState" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/state/PUT/path`. + struct Path: Sendable, Hashable { + /// item name + /// + /// - Remark: Generated from `#/paths/items/{itemname}/state/PUT/path/itemname`. + var itemname: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - itemname: item name + init(itemname: Swift.String) { + self.itemname = itemname + } + } + + var path: Operations.updateItemState.Input.Path + /// - Remark: Generated from `#/paths/items/{itemname}/state/PUT/header`. + struct Headers: Sendable, Hashable { + /// language + /// + /// - Remark: Generated from `#/paths/items/{itemname}/state/PUT/header/Accept-Language`. + var Accept_hyphen_Language: Swift.String? + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Accept_hyphen_Language: language + init(Accept_hyphen_Language: Swift.String? = nil) { + self.Accept_hyphen_Language = Accept_hyphen_Language + } + } + + var headers: Operations.updateItemState.Input.Headers + /// - Remark: Generated from `#/paths/items/{itemname}/state/PUT/requestBody`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/state/PUT/requestBody/content/text\/plain`. + case plainText(OpenAPIRuntime.HTTPBody) + } + + var body: Operations.updateItemState.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + init(path: Operations.updateItemState.Input.Path, + headers: Operations.updateItemState.Input.Headers = .init(), + body: Operations.updateItemState.Input.Body) { + self.path = path + self.headers = headers + self.body = body + } + } + + enum Output: Sendable, Hashable { + struct Accepted: Sendable, Hashable { + /// Creates a new `Accepted`. + init() {} + } + + /// Accepted + /// + /// - Remark: Generated from `#/paths//items/{itemname}/state/put(updateItemState)/responses/202`. + /// + /// HTTP response code: `202 accepted`. + case accepted(Operations.updateItemState.Output.Accepted) + /// The associated value of the enum case if `self` is `.accepted`. + /// + /// - Throws: An error if `self` is not `.accepted`. + /// - SeeAlso: `.accepted`. + var accepted: Operations.updateItemState.Output.Accepted { + get throws { + switch self { + case let .accepted(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "accepted", + response: self + ) + } + } + } + + struct BadRequest: Sendable, Hashable { + /// Creates a new `BadRequest`. + init() {} + } + + /// Item state null + /// + /// - Remark: Generated from `#/paths//items/{itemname}/state/put(updateItemState)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.updateItemState.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + var badRequest: Operations.updateItemState.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Item not found + /// + /// - Remark: Generated from `#/paths//items/{itemname}/state/put(updateItemState)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.updateItemState.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.updateItemState.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + } + + /// Gets the namespace of an item. + /// + /// - Remark: HTTP `GET /items/{itemname}/metadata/namespaces`. + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/namespaces/get(getItemNamespaces)`. + enum getItemNamespaces { + static let id: Swift.String = "getItemNamespaces" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/metadata/namespaces/GET/path`. + struct Path: Sendable, Hashable { + /// item name + /// + /// - Remark: Generated from `#/paths/items/{itemname}/metadata/namespaces/GET/path/itemname`. + var itemname: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - itemname: item name + init(itemname: Swift.String) { + self.itemname = itemname + } + } + + var path: Operations.getItemNamespaces.Input.Path + /// - Remark: Generated from `#/paths/items/{itemname}/metadata/namespaces/GET/header`. + struct Headers: Sendable, Hashable { + /// language + /// + /// - Remark: Generated from `#/paths/items/{itemname}/metadata/namespaces/GET/header/Accept-Language`. + var Accept_hyphen_Language: Swift.String? + var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Accept_hyphen_Language: language + /// - accept: + init(Accept_hyphen_Language: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.Accept_hyphen_Language = Accept_hyphen_Language + self.accept = accept + } + } + + var headers: Operations.getItemNamespaces.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + init(path: Operations.getItemNamespaces.Input.Path, + headers: Operations.getItemNamespaces.Input.Headers = .init()) { + self.path = path + self.headers = headers + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/metadata/namespaces/GET/responses/200/content`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemname}/metadata/namespaces/GET/responses/200/content/application\/json`. + case json(Swift.String) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + var json: Swift.String { + get throws { + switch self { + case let .json(body): + body + } + } + } + } + + /// Received HTTP response body + var body: Operations.getItemNamespaces.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + init(body: Operations.getItemNamespaces.Output.Ok.Body) { + self.body = body + } + } + + /// OK + /// + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/namespaces/get(getItemNamespaces)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.getItemNamespaces.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.getItemNamespaces.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Item not found + /// + /// - Remark: Generated from `#/paths//items/{itemname}/metadata/namespaces/get(getItemNamespaces)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.getItemNamespaces.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.getItemNamespaces.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + + enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + + var rawValue: Swift.String { + switch self { + case let .other(string): + string + case .json: + "application/json" + } + } + + static var allCases: [Self] { + [ + .json + ] + } + } + } + + /// Gets the item which defines the requested semantics of an item. + /// + /// - Remark: HTTP `GET /items/{itemName}/semantic/{semanticClass}`. + /// - Remark: Generated from `#/paths//items/{itemName}/semantic/{semanticClass}/get(getSemanticItem)`. + enum getSemanticItem { + static let id: Swift.String = "getSemanticItem" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/items/{itemName}/semantic/{semanticClass}/GET/path`. + struct Path: Sendable, Hashable { + /// item name + /// + /// - Remark: Generated from `#/paths/items/{itemName}/semantic/{semanticClass}/GET/path/itemName`. + var itemName: Swift.String + /// semantic class + /// + /// - Remark: Generated from `#/paths/items/{itemName}/semantic/{semanticClass}/GET/path/semanticClass`. + var semanticClass: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - itemName: item name + /// - semanticClass: semantic class + init(itemName: Swift.String, + semanticClass: Swift.String) { + self.itemName = itemName + self.semanticClass = semanticClass + } + } + + var path: Operations.getSemanticItem.Input.Path + /// - Remark: Generated from `#/paths/items/{itemName}/semantic/{semanticClass}/GET/header`. + struct Headers: Sendable, Hashable { + /// language + /// + /// - Remark: Generated from `#/paths/items/{itemName}/semantic/{semanticClass}/GET/header/Accept-Language`. + var Accept_hyphen_Language: Swift.String? + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Accept_hyphen_Language: language + init(Accept_hyphen_Language: Swift.String? = nil) { + self.Accept_hyphen_Language = Accept_hyphen_Language + } + } + + var headers: Operations.getSemanticItem.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + init(path: Operations.getSemanticItem.Input.Path, + headers: Operations.getSemanticItem.Input.Headers = .init()) { + self.path = path + self.headers = headers + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// Creates a new `Ok`. + init() {} + } + + /// OK + /// + /// - Remark: Generated from `#/paths//items/{itemName}/semantic/{semanticClass}/get(getSemanticItem)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.getSemanticItem.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.getSemanticItem.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Item not found + /// + /// - Remark: Generated from `#/paths//items/{itemName}/semantic/{semanticClass}/get(getSemanticItem)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.getSemanticItem.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.getSemanticItem.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + } + + /// Remove unused/orphaned metadata. + /// + /// - Remark: HTTP `POST /items/metadata/purge`. + /// - Remark: Generated from `#/paths//items/metadata/purge/post(purgeDatabase)`. + enum purgeDatabase { + static let id: Swift.String = "purgeDatabase" + struct Input: Sendable, Hashable { + /// Creates a new `Input`. + init() {} + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// Creates a new `Ok`. + init() {} + } + + /// OK + /// + /// - Remark: Generated from `#/paths//items/metadata/purge/post(purgeDatabase)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.purgeDatabase.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.purgeDatabase.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + } + + /// Creates a sitemap event subscription. + /// + /// - Remark: HTTP `POST /sitemaps/events/subscribe`. + /// - Remark: Generated from `#/paths//sitemaps/events/subscribe/post(createSitemapEventSubscription)`. + enum createSitemapEventSubscription { + static let id: Swift.String = "createSitemapEventSubscription" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/events/subscribe/POST/header`. + struct Headers: Sendable, Hashable { + var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + + var headers: Operations.createSitemapEventSubscription.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - headers: + init(headers: Operations.createSitemapEventSubscription.Input.Headers = .init()) { + self.headers = headers + } + } + + enum Output: Sendable, Hashable { + struct Created: Sendable, Hashable { + /// Creates a new `Created`. + init() {} + } + + /// Subscription created. + /// + /// - Remark: Generated from `#/paths//sitemaps/events/subscribe/post(createSitemapEventSubscription)/responses/201`. + /// + /// HTTP response code: `201 created`. + case created(Operations.createSitemapEventSubscription.Output.Created) + /// The associated value of the enum case if `self` is `.created`. + /// + /// - Throws: An error if `self` is not `.created`. + /// - SeeAlso: `.created`. + var created: Operations.createSitemapEventSubscription.Output.Created { + get throws { + switch self { + case let .created(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "created", + response: self + ) + } + } + } + + struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/events/subscribe/POST/responses/200/content`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/events/subscribe/POST/responses/200/content/application\/json`. + case json(Components.Schemas.JerseyResponseBuilderDTO) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + var json: Components.Schemas.JerseyResponseBuilderDTO { + get throws { + switch self { + case let .json(body): + body + } + } + } + } + + /// Received HTTP response body + var body: Operations.createSitemapEventSubscription.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + init(body: Operations.createSitemapEventSubscription.Output.Ok.Body) { + self.body = body + } + } + + /// OK + /// + /// - Remark: Generated from `#/paths//sitemaps/events/subscribe/post(createSitemapEventSubscription)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.createSitemapEventSubscription.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.createSitemapEventSubscription.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct ServiceUnavailable: Sendable, Hashable { + /// Creates a new `ServiceUnavailable`. + init() {} + } + + /// Subscriptions limit reached. + /// + /// - Remark: Generated from `#/paths//sitemaps/events/subscribe/post(createSitemapEventSubscription)/responses/503`. + /// + /// HTTP response code: `503 serviceUnavailable`. + case serviceUnavailable(Operations.createSitemapEventSubscription.Output.ServiceUnavailable) + /// The associated value of the enum case if `self` is `.serviceUnavailable`. + /// + /// - Throws: An error if `self` is not `.serviceUnavailable`. + /// - SeeAlso: `.serviceUnavailable`. + var serviceUnavailable: Operations.createSitemapEventSubscription.Output.ServiceUnavailable { + get throws { + switch self { + case let .serviceUnavailable(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "serviceUnavailable", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + + enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + + var rawValue: Swift.String { + switch self { + case let .other(string): + string + case .json: + "application/json" + } + } + + static var allCases: [Self] { + [ + .json + ] + } + } + } + + /// Polls the data for one page of a sitemap. + /// + /// - Remark: HTTP `GET /sitemaps/{sitemapname}/{pageid}`. + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/{pageid}/get(pollDataForPage)`. + enum pollDataForPage { + static let id: Swift.String = "pollDataForPage" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/path`. + struct Path: Sendable, Hashable { + /// sitemap name + /// + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/path/sitemapname`. + var sitemapname: Swift.String + /// page id + /// + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/path/pageid`. + var pageid: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - sitemapname: sitemap name + /// - pageid: page id + init(sitemapname: Swift.String, + pageid: Swift.String) { + self.sitemapname = sitemapname + self.pageid = pageid + } + } + + var path: Operations.pollDataForPage.Input.Path + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/query`. + struct Query: Sendable, Hashable { + /// subscriptionid + /// + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/query/subscriptionid`. + var subscriptionid: Swift.String? + /// include hidden widgets + /// + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/query/includeHidden`. + var includeHidden: Swift.Bool? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - subscriptionid: subscriptionid + /// - includeHidden: include hidden widgets + init(subscriptionid: Swift.String? = nil, + includeHidden: Swift.Bool? = nil) { + self.subscriptionid = subscriptionid + self.includeHidden = includeHidden + } + } + + var query: Operations.pollDataForPage.Input.Query + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/header`. + struct Headers: Sendable, Hashable { + /// language + /// + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/header/Accept-Language`. + var Accept_hyphen_Language: Swift.String? + /// X-Atmosphere-Transport for long polling + /// + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/header/X-Atmosphere-Transport`. + var X_hyphen_Atmosphere_hyphen_Transport: Swift.String? + var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Accept_hyphen_Language: language + /// - X_hyphen_Atmosphere_hyphen_Transport: X-Atmosphere-Transport for long polling + /// - accept: + init(Accept_hyphen_Language: Swift.String? = nil, + X_hyphen_Atmosphere_hyphen_Transport: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.Accept_hyphen_Language = Accept_hyphen_Language + self.X_hyphen_Atmosphere_hyphen_Transport = X_hyphen_Atmosphere_hyphen_Transport + self.accept = accept + } + } + + var headers: Operations.pollDataForPage.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + init(path: Operations.pollDataForPage.Input.Path, + query: Operations.pollDataForPage.Input.Query = .init(), + headers: Operations.pollDataForPage.Input.Headers = .init()) { + self.path = path + self.query = query + self.headers = headers + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/responses/200/content`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/responses/200/content/application\/json`. + case json(Components.Schemas.PageDTO) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + var json: Components.Schemas.PageDTO { + get throws { + switch self { + case let .json(body): + body + } + } + } + } + + /// Received HTTP response body + var body: Operations.pollDataForPage.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + init(body: Operations.pollDataForPage.Output.Ok.Body) { + self.body = body + } + } + + /// OK + /// + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/{pageid}/get(pollDataForPage)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.pollDataForPage.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.pollDataForPage.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct BadRequest: Sendable, Hashable { + /// Creates a new `BadRequest`. + init() {} + } + + /// Invalid subscription id has been provided. + /// + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/{pageid}/get(pollDataForPage)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.pollDataForPage.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + var badRequest: Operations.pollDataForPage.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Sitemap with requested name does not exist or page does not exist, or page refers to a non-linkable widget + /// + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/{pageid}/get(pollDataForPage)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.pollDataForPage.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.pollDataForPage.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + + enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + + var rawValue: Swift.String { + switch self { + case let .other(string): + string + case .json: + "application/json" + } + } + + static var allCases: [Self] { + [ + .json + ] + } + } + } + + /// Polls the data for a whole sitemap. Not recommended due to potentially high traffic. + /// + /// - Remark: HTTP `GET /sitemaps/{sitemapname}/*`. + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/*/get(pollDataForSitemap)`. + enum pollDataForSitemap { + static let id: Swift.String = "pollDataForSitemap" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/path`. + struct Path: Sendable, Hashable { + /// sitemap name + /// + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/path/sitemapname`. + var sitemapname: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - sitemapname: sitemap name + init(sitemapname: Swift.String) { + self.sitemapname = sitemapname + } + } + + var path: Operations.pollDataForSitemap.Input.Path + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/query`. + struct Query: Sendable, Hashable { + /// subscriptionid + /// + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/query/subscriptionid`. + var subscriptionid: Swift.String? + /// include hidden widgets + /// + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/query/includeHidden`. + var includeHidden: Swift.Bool? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - subscriptionid: subscriptionid + /// - includeHidden: include hidden widgets + init(subscriptionid: Swift.String? = nil, + includeHidden: Swift.Bool? = nil) { + self.subscriptionid = subscriptionid + self.includeHidden = includeHidden + } + } + + var query: Operations.pollDataForSitemap.Input.Query + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/header`. + struct Headers: Sendable, Hashable { + /// language + /// + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/header/Accept-Language`. + var Accept_hyphen_Language: Swift.String? + /// X-Atmosphere-Transport for long polling + /// + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/header/X-Atmosphere-Transport`. + var X_hyphen_Atmosphere_hyphen_Transport: Swift.String? + var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Accept_hyphen_Language: language + /// - X_hyphen_Atmosphere_hyphen_Transport: X-Atmosphere-Transport for long polling + /// - accept: + init(Accept_hyphen_Language: Swift.String? = nil, + X_hyphen_Atmosphere_hyphen_Transport: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.Accept_hyphen_Language = Accept_hyphen_Language + self.X_hyphen_Atmosphere_hyphen_Transport = X_hyphen_Atmosphere_hyphen_Transport + self.accept = accept + } + } + + var headers: Operations.pollDataForSitemap.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + init(path: Operations.pollDataForSitemap.Input.Path, + query: Operations.pollDataForSitemap.Input.Query = .init(), + headers: Operations.pollDataForSitemap.Input.Headers = .init()) { + self.path = path + self.query = query + self.headers = headers + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/responses/200/content`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/responses/200/content/application\/json`. + case json(Components.Schemas.SitemapDTO) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + var json: Components.Schemas.SitemapDTO { + get throws { + switch self { + case let .json(body): + body + } + } + } + } + + /// Received HTTP response body + var body: Operations.pollDataForSitemap.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + init(body: Operations.pollDataForSitemap.Output.Ok.Body) { + self.body = body + } + } + + /// OK + /// + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/*/get(pollDataForSitemap)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.pollDataForSitemap.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.pollDataForSitemap.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct BadRequest: Sendable, Hashable { + /// Creates a new `BadRequest`. + init() {} + } + + /// Invalid subscription id has been provided. + /// + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/*/get(pollDataForSitemap)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.pollDataForSitemap.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + var badRequest: Operations.pollDataForSitemap.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Sitemap with requested name does not exist + /// + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/*/get(pollDataForSitemap)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.pollDataForSitemap.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.pollDataForSitemap.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + + enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + + var rawValue: Swift.String { + switch self { + case let .other(string): + string + case .json: + "application/json" + } + } + + static var allCases: [Self] { + [ + .json + ] + } + } + } + + /// Get sitemap by name. + /// + /// - Remark: HTTP `GET /sitemaps/{sitemapname}`. + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/get(getSitemapByName)`. + enum getSitemapByName { + static let id: Swift.String = "getSitemapByName" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/path`. + struct Path: Sendable, Hashable { + /// sitemap name + /// + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/path/sitemapname`. + var sitemapname: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - sitemapname: sitemap name + init(sitemapname: Swift.String) { + self.sitemapname = sitemapname + } + } + + var path: Operations.getSitemapByName.Input.Path + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/query`. + struct Query: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/query/type`. + var _type: Swift.String? + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/query/jsoncallback`. + var jsoncallback: Swift.String? + /// include hidden widgets + /// + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/query/includeHidden`. + var includeHidden: Swift.Bool? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - _type: + /// - jsoncallback: + /// - includeHidden: include hidden widgets + init(_type: Swift.String? = nil, + jsoncallback: Swift.String? = nil, + includeHidden: Swift.Bool? = nil) { + self._type = _type + self.jsoncallback = jsoncallback + self.includeHidden = includeHidden + } + } + + var query: Operations.getSitemapByName.Input.Query + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/header`. + struct Headers: Sendable, Hashable { + /// language + /// + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/header/Accept-Language`. + var Accept_hyphen_Language: Swift.String? + var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Accept_hyphen_Language: language + /// - accept: + init(Accept_hyphen_Language: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.Accept_hyphen_Language = Accept_hyphen_Language + self.accept = accept + } + } + + var headers: Operations.getSitemapByName.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + init(path: Operations.getSitemapByName.Input.Path, + query: Operations.getSitemapByName.Input.Query = .init(), + headers: Operations.getSitemapByName.Input.Headers = .init()) { + self.path = path + self.query = query + self.headers = headers + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/responses/200/content`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/responses/200/content/application\/json`. + case json(Components.Schemas.SitemapDTO) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + var json: Components.Schemas.SitemapDTO { + get throws { + switch self { + case let .json(body): + body + } + } + } + } + + /// Received HTTP response body + var body: Operations.getSitemapByName.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + init(body: Operations.getSitemapByName.Output.Ok.Body) { + self.body = body + } + } + + /// OK + /// + /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/get(getSitemapByName)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.getSitemapByName.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.getSitemapByName.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + + enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + + var rawValue: Swift.String { + switch self { + case let .other(string): + string + case .json: + "application/json" + } + } + + static var allCases: [Self] { + [ + .json + ] + } + } + } + + /// Get sitemap events for a whole sitemap. Not recommended due to potentially high traffic. + /// + /// - Remark: HTTP `GET /sitemaps/events/{subscriptionid}/*`. + /// - Remark: Generated from `#/paths//sitemaps/events/{subscriptionid}/*/get(getSitemapEvents)`. + enum getSitemapEvents { + static let id: Swift.String = "getSitemapEvents" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/*/GET/path`. + struct Path: Sendable, Hashable { + /// subscription id + /// + /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/*/GET/path/subscriptionid`. + var subscriptionid: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - subscriptionid: subscription id + init(subscriptionid: Swift.String) { + self.subscriptionid = subscriptionid + } + } + + var path: Operations.getSitemapEvents.Input.Path + /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/*/GET/query`. + struct Query: Sendable, Hashable { + /// sitemap name + /// + /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/*/GET/query/sitemap`. + var sitemap: Swift.String? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - sitemap: sitemap name + init(sitemap: Swift.String? = nil) { + self.sitemap = sitemap + } + } + + var query: Operations.getSitemapEvents.Input.Query + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + init(path: Operations.getSitemapEvents.Input.Path, + query: Operations.getSitemapEvents.Input.Query = .init()) { + self.path = path + self.query = query + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// Creates a new `Ok`. + init() {} + } + + /// OK + /// + /// - Remark: Generated from `#/paths//sitemaps/events/{subscriptionid}/*/get(getSitemapEvents)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.getSitemapEvents.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.getSitemapEvents.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct BadRequest: Sendable, Hashable { + /// Creates a new `BadRequest`. + init() {} + } + + /// Missing sitemap parameter, or sitemap not linked successfully to the subscription. + /// + /// - Remark: Generated from `#/paths//sitemaps/events/{subscriptionid}/*/get(getSitemapEvents)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.getSitemapEvents.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + var badRequest: Operations.getSitemapEvents.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Subscription not found. + /// + /// - Remark: Generated from `#/paths//sitemaps/events/{subscriptionid}/*/get(getSitemapEvents)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.getSitemapEvents.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.getSitemapEvents.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + } + + /// Get sitemap events. + /// + /// - Remark: HTTP `GET /sitemaps/events/{subscriptionid}`. + /// - Remark: Generated from `#/paths//sitemaps/events/{subscriptionid}/get(getSitemapEvents_1)`. + enum getSitemapEvents_1 { + static let id: Swift.String = "getSitemapEvents_1" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/GET/path`. + struct Path: Sendable, Hashable { + /// subscription id + /// + /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/GET/path/subscriptionid`. + var subscriptionid: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - subscriptionid: subscription id + init(subscriptionid: Swift.String) { + self.subscriptionid = subscriptionid + } + } + + var path: Operations.getSitemapEvents_1.Input.Path + /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/GET/query`. + struct Query: Sendable, Hashable { + /// sitemap name + /// + /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/GET/query/sitemap`. + var sitemap: Swift.String? + /// page id + /// + /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/GET/query/pageid`. + var pageid: Swift.String? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - sitemap: sitemap name + /// - pageid: page id + init(sitemap: Swift.String? = nil, + pageid: Swift.String? = nil) { + self.sitemap = sitemap + self.pageid = pageid + } + } + + var query: Operations.getSitemapEvents_1.Input.Query + /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/GET/header`. + struct Headers: Sendable, Hashable { + var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + + var headers: Operations.getSitemapEvents_1.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + init(path: Operations.getSitemapEvents_1.Input.Path, + query: Operations.getSitemapEvents_1.Input.Query = .init(), + headers: Operations.getSitemapEvents_1.Input.Headers = .init()) { + self.path = path + self.query = query + self.headers = headers + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/GET/responses/200/content`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/GET/responses/200/content/text\/event-stream`. + case text_event_hyphen_stream(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.text_event_hyphen_stream`. + /// + /// - Throws: An error if `self` is not `.text_event_hyphen_stream`. + /// - SeeAlso: `.text_event_hyphen_stream`. + var text_event_hyphen_stream: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .text_event_hyphen_stream(body): + body + default: + try throwUnexpectedResponseBody( + expectedContent: "text/event-stream", + body: self + ) + } + } + } + + /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/GET/responses/200/content/application\/json`. + case json(Components.Schemas.SitemapWidgetEvent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + var json: Components.Schemas.SitemapWidgetEvent { + get throws { + switch self { + case let .json(body): + body + default: + try throwUnexpectedResponseBody( + expectedContent: "application/json", + body: self + ) + } + } + } + } + + /// Received HTTP response body + var body: Operations.getSitemapEvents_1.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + init(body: Operations.getSitemapEvents_1.Output.Ok.Body) { + self.body = body + } + } + + /// OK + /// + /// - Remark: Generated from `#/paths//sitemaps/events/{subscriptionid}/get(getSitemapEvents_1)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.getSitemapEvents_1.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.getSitemapEvents_1.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct BadRequest: Sendable, Hashable { + /// Creates a new `BadRequest`. + init() {} + } + + /// Missing sitemap or page parameter, or page not linked successfully to the subscription. + /// + /// - Remark: Generated from `#/paths//sitemaps/events/{subscriptionid}/get(getSitemapEvents_1)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.getSitemapEvents_1.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + var badRequest: Operations.getSitemapEvents_1.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Subscription not found. + /// + /// - Remark: Generated from `#/paths//sitemaps/events/{subscriptionid}/get(getSitemapEvents_1)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.getSitemapEvents_1.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.getSitemapEvents_1.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + + enum AcceptableContentType: AcceptableProtocol { + case text_event_hyphen_stream + case json + case other(Swift.String) + init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "text/event-stream": + self = .text_event_hyphen_stream + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + + var rawValue: Swift.String { + switch self { + case let .other(string): + string + case .text_event_hyphen_stream: + "text/event-stream" + case .json: + "application/json" + } + } + + static var allCases: [Self] { + [ + .text_event_hyphen_stream, + .json + ] + } + } + } + + /// Get all available sitemaps. + /// + /// - Remark: HTTP `GET /sitemaps`. + /// - Remark: Generated from `#/paths//sitemaps/get(getSitemaps)`. + enum getSitemaps { + static let id: Swift.String = "getSitemaps" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/GET/header`. + struct Headers: Sendable, Hashable { + var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + + var headers: Operations.getSitemaps.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - headers: + init(headers: Operations.getSitemaps.Input.Headers = .init()) { + self.headers = headers + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/GET/responses/200/content`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/sitemaps/GET/responses/200/content/application\/json`. + case json([Components.Schemas.SitemapDTO]) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + var json: [Components.Schemas.SitemapDTO] { + get throws { + switch self { + case let .json(body): + body + } + } + } + } + + /// Received HTTP response body + var body: Operations.getSitemaps.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + init(body: Operations.getSitemaps.Output.Ok.Body) { + self.body = body + } + } + + /// OK + /// + /// - Remark: Generated from `#/paths//sitemaps/get(getSitemaps)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.getSitemaps.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.getSitemaps.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + + enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + + var rawValue: Swift.String { + switch self { + case let .other(string): + string + case .json: + "application/json" + } + } + + static var allCases: [Self] { + [ + .json + ] + } + } + } + + /// Get all registered UI components in the specified namespace. + /// + /// - Remark: HTTP `GET /ui/components/{namespace}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/get(getRegisteredUIComponentsInNamespace)`. + enum getRegisteredUIComponentsInNamespace { + static let id: Swift.String = "getRegisteredUIComponentsInNamespace" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/GET/path`. + struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/GET/path/namespace`. + var namespace: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - namespace: + init(namespace: Swift.String) { + self.namespace = namespace + } + } + + var path: Operations.getRegisteredUIComponentsInNamespace.Input.Path + /// - Remark: Generated from `#/paths/ui/components/{namespace}/GET/query`. + struct Query: Sendable, Hashable { + /// summary fields only + /// + /// - Remark: Generated from `#/paths/ui/components/{namespace}/GET/query/summary`. + var summary: Swift.Bool? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - summary: summary fields only + init(summary: Swift.Bool? = nil) { + self.summary = summary + } + } + + var query: Operations.getRegisteredUIComponentsInNamespace.Input.Query + /// - Remark: Generated from `#/paths/ui/components/{namespace}/GET/header`. + struct Headers: Sendable, Hashable { + var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + + var headers: Operations.getRegisteredUIComponentsInNamespace.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + init(path: Operations.getRegisteredUIComponentsInNamespace.Input.Path, + query: Operations.getRegisteredUIComponentsInNamespace.Input.Query = .init(), + headers: Operations.getRegisteredUIComponentsInNamespace.Input.Headers = .init()) { + self.path = path + self.query = query + self.headers = headers + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/GET/responses/200/content`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/GET/responses/200/content/application\/json`. + case json([Components.Schemas.RootUIComponent]) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + var json: [Components.Schemas.RootUIComponent] { + get throws { + switch self { + case let .json(body): + body + } + } + } + } + + /// Received HTTP response body + var body: Operations.getRegisteredUIComponentsInNamespace.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + init(body: Operations.getRegisteredUIComponentsInNamespace.Output.Ok.Body) { + self.body = body + } + } + + /// OK + /// + /// - Remark: Generated from `#/paths//ui/components/{namespace}/get(getRegisteredUIComponentsInNamespace)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.getRegisteredUIComponentsInNamespace.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.getRegisteredUIComponentsInNamespace.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + + enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + + var rawValue: Swift.String { + switch self { + case let .other(string): + string + case .json: + "application/json" + } + } + + static var allCases: [Self] { + [ + .json + ] + } + } + } + + /// Add a UI component in the specified namespace. + /// + /// - Remark: HTTP `POST /ui/components/{namespace}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/post(addUIComponentToNamespace)`. + enum addUIComponentToNamespace { + static let id: Swift.String = "addUIComponentToNamespace" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/POST/path`. + struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/POST/path/namespace`. + var namespace: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - namespace: + init(namespace: Swift.String) { + self.namespace = namespace + } + } + + var path: Operations.addUIComponentToNamespace.Input.Path + /// - Remark: Generated from `#/paths/ui/components/{namespace}/POST/header`. + struct Headers: Sendable, Hashable { + var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + + var headers: Operations.addUIComponentToNamespace.Input.Headers + /// - Remark: Generated from `#/paths/ui/components/{namespace}/POST/requestBody`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/POST/requestBody/content/application\/json`. + case json(Components.Schemas.RootUIComponent) + } + + var body: Operations.addUIComponentToNamespace.Input.Body? + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + init(path: Operations.addUIComponentToNamespace.Input.Path, + headers: Operations.addUIComponentToNamespace.Input.Headers = .init(), + body: Operations.addUIComponentToNamespace.Input.Body? = nil) { + self.path = path + self.headers = headers + self.body = body + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/POST/responses/200/content`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/POST/responses/200/content/application\/json`. + case json(Components.Schemas.RootUIComponent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + var json: Components.Schemas.RootUIComponent { + get throws { + switch self { + case let .json(body): + body + } + } + } + } + + /// Received HTTP response body + var body: Operations.addUIComponentToNamespace.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + init(body: Operations.addUIComponentToNamespace.Output.Ok.Body) { + self.body = body + } + } + + /// OK + /// + /// - Remark: Generated from `#/paths//ui/components/{namespace}/post(addUIComponentToNamespace)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.addUIComponentToNamespace.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.addUIComponentToNamespace.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + + enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + + var rawValue: Swift.String { + switch self { + case let .other(string): + string + case .json: + "application/json" + } + } + + static var allCases: [Self] { + [ + .json + ] + } + } + } + + /// Get a specific UI component in the specified namespace. + /// + /// - Remark: HTTP `GET /ui/components/{namespace}/{componentUID}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/get(getUIComponentInNamespace)`. + enum getUIComponentInNamespace { + static let id: Swift.String = "getUIComponentInNamespace" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/GET/path`. + struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/GET/path/namespace`. + var namespace: Swift.String + /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/GET/path/componentUID`. + var componentUID: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - namespace: + /// - componentUID: + init(namespace: Swift.String, + componentUID: Swift.String) { + self.namespace = namespace + self.componentUID = componentUID + } + } + + var path: Operations.getUIComponentInNamespace.Input.Path + /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/GET/header`. + struct Headers: Sendable, Hashable { + var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + + var headers: Operations.getUIComponentInNamespace.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + init(path: Operations.getUIComponentInNamespace.Input.Path, + headers: Operations.getUIComponentInNamespace.Input.Headers = .init()) { + self.path = path + self.headers = headers + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/GET/responses/200/content`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/GET/responses/200/content/application\/json`. + case json(Components.Schemas.RootUIComponent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + var json: Components.Schemas.RootUIComponent { + get throws { + switch self { + case let .json(body): + body + } + } + } + } + + /// Received HTTP response body + var body: Operations.getUIComponentInNamespace.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + init(body: Operations.getUIComponentInNamespace.Output.Ok.Body) { + self.body = body + } + } + + /// OK + /// + /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/get(getUIComponentInNamespace)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.getUIComponentInNamespace.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.getUIComponentInNamespace.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Component not found + /// + /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/get(getUIComponentInNamespace)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.getUIComponentInNamespace.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.getUIComponentInNamespace.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + + enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + + var rawValue: Swift.String { + switch self { + case let .other(string): + string + case .json: + "application/json" + } + } + + static var allCases: [Self] { + [ + .json + ] + } + } + } + + /// Update a specific UI component in the specified namespace. + /// + /// - Remark: HTTP `PUT /ui/components/{namespace}/{componentUID}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/put(updateUIComponentInNamespace)`. + enum updateUIComponentInNamespace { + static let id: Swift.String = "updateUIComponentInNamespace" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/PUT/path`. + struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/PUT/path/namespace`. + var namespace: Swift.String + /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/PUT/path/componentUID`. + var componentUID: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - namespace: + /// - componentUID: + init(namespace: Swift.String, + componentUID: Swift.String) { + self.namespace = namespace + self.componentUID = componentUID + } + } + + var path: Operations.updateUIComponentInNamespace.Input.Path + /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/PUT/header`. + struct Headers: Sendable, Hashable { + var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + + var headers: Operations.updateUIComponentInNamespace.Input.Headers + /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/PUT/requestBody`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/PUT/requestBody/content/application\/json`. + case json(Components.Schemas.RootUIComponent) + } + + var body: Operations.updateUIComponentInNamespace.Input.Body? + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + init(path: Operations.updateUIComponentInNamespace.Input.Path, + headers: Operations.updateUIComponentInNamespace.Input.Headers = .init(), + body: Operations.updateUIComponentInNamespace.Input.Body? = nil) { + self.path = path + self.headers = headers + self.body = body + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/PUT/responses/200/content`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/PUT/responses/200/content/application\/json`. + case json(Components.Schemas.RootUIComponent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + var json: Components.Schemas.RootUIComponent { + get throws { + switch self { + case let .json(body): + body + } + } + } + } + + /// Received HTTP response body + var body: Operations.updateUIComponentInNamespace.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + init(body: Operations.updateUIComponentInNamespace.Output.Ok.Body) { + self.body = body + } + } + + /// OK + /// + /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/put(updateUIComponentInNamespace)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.updateUIComponentInNamespace.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.updateUIComponentInNamespace.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Component not found + /// + /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/put(updateUIComponentInNamespace)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.updateUIComponentInNamespace.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.updateUIComponentInNamespace.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + + enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + + var rawValue: Swift.String { + switch self { + case let .other(string): + string + case .json: + "application/json" + } + } + + static var allCases: [Self] { + [ + .json + ] + } + } + } + + /// Remove a specific UI component in the specified namespace. + /// + /// - Remark: HTTP `DELETE /ui/components/{namespace}/{componentUID}`. + /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/delete(removeUIComponentFromNamespace)`. + enum removeUIComponentFromNamespace { + static let id: Swift.String = "removeUIComponentFromNamespace" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/DELETE/path`. + struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/DELETE/path/namespace`. + var namespace: Swift.String + /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/DELETE/path/componentUID`. + var componentUID: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - namespace: + /// - componentUID: + init(namespace: Swift.String, + componentUID: Swift.String) { + self.namespace = namespace + self.componentUID = componentUID + } + } + + var path: Operations.removeUIComponentFromNamespace.Input.Path + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + init(path: Operations.removeUIComponentFromNamespace.Input.Path) { + self.path = path + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// Creates a new `Ok`. + init() {} + } + + /// OK + /// + /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/delete(removeUIComponentFromNamespace)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.removeUIComponentFromNamespace.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.removeUIComponentFromNamespace.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + init() {} + } + + /// Component not found + /// + /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/delete(removeUIComponentFromNamespace)/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.removeUIComponentFromNamespace.Output.NotFound) + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + var notFound: Operations.removeUIComponentFromNamespace.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + } + + /// Get all registered UI tiles. + /// + /// - Remark: HTTP `GET /ui/tiles`. + /// - Remark: Generated from `#/paths//ui/tiles/get(getUITiles)`. + enum getUITiles { + static let id: Swift.String = "getUITiles" + struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/tiles/GET/header`. + struct Headers: Sendable, Hashable { + var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + + var headers: Operations.getUITiles.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - headers: + init(headers: Operations.getUITiles.Input.Headers = .init()) { + self.headers = headers + } + } + + enum Output: Sendable, Hashable { + struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/tiles/GET/responses/200/content`. + enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/ui/tiles/GET/responses/200/content/application\/json`. + case json([Components.Schemas.TileDTO]) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + var json: [Components.Schemas.TileDTO] { + get throws { + switch self { + case let .json(body): + body + } + } + } + } + + /// Received HTTP response body + var body: Operations.getUITiles.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + init(body: Operations.getUITiles.Output.Ok.Body) { + self.body = body + } + } + + /// OK + /// + /// - Remark: Generated from `#/paths//ui/tiles/get(getUITiles)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.getUITiles.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + var ok: Operations.getUITiles.Output.Ok { + get throws { + switch self { + case let .ok(response): + response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + + enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + + var rawValue: Swift.String { + switch self { + case let .other(string): + string + case .json: + "application/json" + } + } + + static var allCases: [Self] { + [ + .json + ] + } + } + } +} diff --git a/OpenHABCore/Sources/OpenHABCore/Model/APIActor.swift b/OpenHABCore/Sources/OpenHABCore/Model/APIActor.swift index b0b70859..f1433b84 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/APIActor.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/APIActor.swift @@ -9,20 +9,12 @@ // // SPDX-License-Identifier: EPL-2.0 -// -// File.swift -// -// -// Created by Tim on 10.08.24. -// import Foundation import HTTPTypes import OpenAPIRuntime import OpenAPIURLSession import os -let logger = Logger(subsystem: "org.openhab.app", category: "apiactor") - public protocol OpenHABSitemapsService { func openHABSitemaps() async throws -> [OpenHABSitemap] } @@ -41,8 +33,9 @@ public actor APIActor { var username: String var password: String - public init(username: String = "", password: String = "", alwaysSendBasicAuth: Bool = true) { - let url = "about:blank" + private let logger = Logger(subsystem: "org.openhab.app", category: "apiactor") + + public init(username: String = "", password: String = "", alwaysSendBasicAuth: Bool = true, url: URL = URL(staticString: "about:blank")) async { // TODO: Make use of prepareURLSessionConfiguration let config = URLSessionConfiguration.default // config.timeoutIntervalForRequest = if longPolling { 35.0 } else { 20.0 } @@ -51,11 +44,15 @@ public actor APIActor { self.username = username self.password = password self.alwaysSendBasicAuth = alwaysSendBasicAuth + self.url = url api = Client( - serverURL: URL(string: url)!, + serverURL: url.appending(path: "/rest"), transport: URLSessionTransport(configuration: .init(session: session)), - middlewares: [AuthorisationMiddleware(username: username, password: password, alwaysSendBasicAuth: alwaysSendBasicAuth)] + middlewares: [ + AuthorisationMiddleware(username: username, password: password, alwaysSendBasicAuth: alwaysSendBasicAuth), + LoggingMiddleware() + ] ) } @@ -74,7 +71,10 @@ public actor APIActor { api = Client( serverURL: newURL.appending(path: "/rest"), transport: URLSessionTransport(configuration: .init(session: session)), - middlewares: [AuthorisationMiddleware(username: username, password: password)] + middlewares: [ + AuthorisationMiddleware(username: username, password: password), + LoggingMiddleware() + ] ) } } @@ -88,17 +88,27 @@ public actor APIActor { api = Client( serverURL: url!.appending(path: "/rest"), transport: URLSessionTransport(configuration: .init(session: session)), - middlewares: [AuthorisationMiddleware(username: username, password: password)] + middlewares: [ + AuthorisationMiddleware(username: username, password: password), + LoggingMiddleware() + ] ) } } } +public enum APIActorError: Error { + case undocumented +} + extension APIActor: OpenHABSitemapsService { public func openHABSitemaps() async throws -> [OpenHABSitemap] { - try await api.getSitemaps(.init()) - .ok.body.json - .map(OpenHABSitemap.init) + // swiftformat:disable:next redundantSelf + logger.log("Trying to getSitemaps for : \(self.url?.debugDescription ?? "No URL")") + switch try await api.getSitemaps(.init()) { + case let .ok(okresponse): return try okresponse.body.json.map(OpenHABSitemap.init) + case .undocumented: throw APIActorError.undocumented + } } } @@ -110,19 +120,65 @@ extension APIActor: OpenHABUiTileService { } } -extension APIActor { - func openHABSitemap(path: Operations.getSitemapByName.Input.Path) async throws -> OpenHABSitemap? { - let result = try await api.getSitemapByName(path: path) - .ok.body.json - return OpenHABSitemap(result) +public extension AsyncThrowingStream { +// func map(_ transform: @escaping (Self.Element) -> Transformed) -> AsyncThrowingStream { +// AsyncThrowingStream { continuation in +// Task { +// for try await element in self { +// continuation.yield(transform(element)) +// } +// continuation.finish() +// } +// } +// } + + func map2(transform: @escaping (Self.Element) -> T) -> AsyncThrowingStream { + AsyncThrowingStream { continuation in + let task = Task { + for try await element in self { + continuation.yield(transform(element)) + } + continuation.finish() + } + continuation.onTermination = { _ in task.cancel() } + } + } +} + +public extension APIActor { + func openHABcreateSubscription() async throws -> String? { + logger.info("Creating subscription") + let result = try await api.createSitemapEventSubscription() + guard let urlString = try result.ok.body.json.context?.headers?.Location?.first else { return nil } + return URL(string: urlString)?.lastPathComponent + } + + func openHABSitemapWidgetEvents(subscriptionid: String, sitemap: String) async throws -> String { +// AsyncThrowingStream { + let path = Operations.getSitemapEvents_1.Input.Path(subscriptionid: subscriptionid) + let query = Operations.getSitemapEvents_1.Input.Query(sitemap: sitemap, pageid: sitemap) + let stream = try await api.getSitemapEvents_1(path: path, query: query).ok.body.text_event_hyphen_stream.asDecodedServerSentEventsWithJSONData(of: Components.Schemas.SitemapWidgetEvent.self).compactMap { (value) -> OpenHABSitemapWidgetEvent? in + guard let data = value.data else { return nil } + return OpenHABSitemapWidgetEvent(data) + } +// return stream.map2 + + for try await line in stream { + print(line) + print("\n") + } + return "" + + logger.debug("subscription date received") } } extension APIActor { // Internal function for pollPage func openHABpollPage(path: Operations.pollDataForPage.Input.Path, + query: Operations.pollDataForPage.Input.Query = .init(), headers: Operations.pollDataForPage.Input.Headers) async throws -> OpenHABPage? { - let result = try await api.pollDataForPage(path: path, headers: headers) + let result = try await api.pollDataForPage(path: path, query: query, headers: headers) .ok.body.json return OpenHABPage(result) } @@ -133,7 +189,6 @@ extension APIActor { /// - longPolling: set to true for long-polling public func openHABpollPage(sitemapname: String, longPolling: Bool) async throws -> OpenHABPage? { var headers = Operations.pollDataForPage.Input.Headers() - if longPolling { logger.info("Long-polling, setting X-Atmosphere-Transport") headers.X_hyphen_Atmosphere_hyphen_Transport = "long-polling" @@ -144,15 +199,29 @@ extension APIActor { await updateForLongPolling(longPolling) return try await openHABpollPage(path: path, headers: headers) } -} -extension APIActor { - func openHABSitemap(path: Operations.getSitemapByName.Input.Path, - headers: Operations.getSitemapByName.Input.Headers) async throws -> OpenHABSitemap? { - let result = try await api.getSitemapByName(path: path, headers: headers) + // Internal function for pollSitemap + func openHABpollSitemap(path: Operations.pollDataForSitemap.Input.Path, + query: Operations.pollDataForSitemap.Input.Query = .init(), + headers: Operations.pollDataForSitemap.Input.Headers) async throws -> OpenHABSitemap? { + let result = try await api.pollDataForSitemap(path: path, query: query, headers: headers) .ok.body.json return OpenHABSitemap(result) } + + public func openHABpollSitemap(sitemapname: String, longPolling: Bool, subscriptionId: String? = nil) async throws -> OpenHABSitemap? { + var headers = Operations.pollDataForSitemap.Input.Headers() + if longPolling { + logger.info("Long-polling, setting X-Atmosphere-Transport") + headers.X_hyphen_Atmosphere_hyphen_Transport = "long-polling" + } else { + headers.X_hyphen_Atmosphere_hyphen_Transport = nil + } + let query = Operations.pollDataForSitemap.Input.Query(subscriptionid: subscriptionId) + let path = Operations.pollDataForSitemap.Input.Path(sitemapname: sitemapname) + await updateForLongPolling(longPolling) + return try await openHABpollSitemap(path: path, query: query, headers: headers) + } } // MARK: State changes and commands @@ -173,6 +242,44 @@ public extension APIActor { } } +class OpenHABSitemapWidgetEvent { + init(sitemapName: String? = nil, pageId: String? = nil, widgetId: String? = nil, label: String? = nil, labelSource: String? = nil, icon: String? = nil, reloadIcon: Bool? = nil, labelcolor: String? = nil, valuecolor: String? = nil, iconcolor: String? = nil, visibility: Bool? = nil, state: String? = nil, enrichedItem: OpenHABItem? = nil, descriptionChanged: Bool? = nil) { + self.sitemapName = sitemapName + self.pageId = pageId + self.widgetId = widgetId + self.label = label + self.labelSource = labelSource + self.icon = icon + self.reloadIcon = reloadIcon + self.labelcolor = labelcolor + self.valuecolor = valuecolor + self.iconcolor = iconcolor + self.visibility = visibility + self.state = state + self.enrichedItem = enrichedItem + self.descriptionChanged = descriptionChanged + } + + convenience init(_ event: Components.Schemas.SitemapWidgetEvent) { + self.init(sitemapName: event.sitemapName, pageId: event.pageId, widgetId: event.widgetId, label: event.label, labelSource: event.labelSource, icon: event.icon, reloadIcon: event.reloadIcon, labelcolor: event.labelcolor, valuecolor: event.valuecolor, iconcolor: event.iconcolor, visibility: event.visibility, state: event.state, enrichedItem: OpenHABItem(event.item), descriptionChanged: event.descriptionChanged) + } + + var sitemapName: String? + var pageId: String? + var widgetId: String? + var label: String? + var labelSource: String? + var icon: String? + var reloadIcon: Bool? + var labelcolor: String? + var valuecolor: String? + var iconcolor: String? + var visibility: Bool? + var state: String? + var enrichedItem: OpenHABItem? + var descriptionChanged: Bool? +} + public struct AuthorisationMiddleware { private let username: String private let password: String @@ -199,12 +306,10 @@ extension AuthorisationMiddleware: ClientMiddleware { // Use a mutable copy of request var request = request - if ((baseURL.host?.hasSuffix("myopenhab.org")) == nil), alwaysSendBasicAuth, !username.isEmpty, !password.isEmpty { + if baseURL.host?.hasSuffix("myopenhab.org") == nil, alwaysSendBasicAuth, !username.isEmpty, !password.isEmpty { request.headerFields[.authorization] = basicAuthHeader() } - logger.info("Outgoing request: \(request.headerFields.debugDescription, privacy: .public)") let (response, body) = try await next(request, body, baseURL) - logger.debug("Incoming response \(response.headerFields.debugDescription)") return (response, body) } } diff --git a/OpenHABCore/Sources/OpenHABCore/Model/LoggingMiddleware.swift b/OpenHABCore/Sources/OpenHABCore/Model/LoggingMiddleware.swift new file mode 100644 index 00000000..cc4f12e8 --- /dev/null +++ b/OpenHABCore/Sources/OpenHABCore/Model/LoggingMiddleware.swift @@ -0,0 +1,115 @@ +// Copyright (c) 2010-2024 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation +import HTTPTypes +import OpenAPIRuntime +import os + +// swiftlint:disable file_types_order +package actor LoggingMiddleware { + private static var defaultLogger: Logger { + Logger(subsystem: "org.openhab.app", category: "logging-middleware") + } + + private let logger: Logger + package let bodyLoggingPolicy: BodyLoggingPolicy + + package init(logger: Logger = defaultLogger, bodyLoggingConfiguration: BodyLoggingPolicy = .never) { + self.logger = logger + bodyLoggingPolicy = bodyLoggingConfiguration + } +} + +extension LoggingMiddleware: ClientMiddleware { + package func intercept(_ request: HTTPRequest, + body: HTTPBody?, + baseURL: URL, + operationID: String, + next: @Sendable (HTTPRequest, HTTPBody?, URL) async throws -> (HTTPResponse, HTTPBody?)) async throws -> (HTTPResponse, HTTPBody?) { + let (requestBodyToLog, requestBodyForNext) = try await bodyLoggingPolicy.process(body) + log(request, requestBodyToLog) + do { + let (response, responseBody) = try await next(request, requestBodyForNext, baseURL) + let (responseBodyToLog, responseBodyForNext) = try await bodyLoggingPolicy.process(responseBody) + log(request, response, responseBodyToLog) + return (response, responseBodyForNext) + } catch { + log(request, failedWith: error) + throw error + } + } +} + +extension LoggingMiddleware { + func log(_ request: HTTPRequest, _ requestBody: BodyLoggingPolicy.BodyLog) { + logger.debug( + "Request: \(request.method, privacy: .public) \(request.path ?? "", privacy: .public) body: \(requestBody, privacy: .auto)" + ) + } + + func log(_ request: HTTPRequest, _ response: HTTPResponse, _ responseBody: BodyLoggingPolicy.BodyLog) { + logger.debug( + "Response: \(request.method, privacy: .public) \(request.path ?? "", privacy: .public) \(response.status, privacy: .public) body: \(responseBody, privacy: .auto)" + ) + } + + func log(_ request: HTTPRequest, failedWith error: any Error) { + logger.warning("Request failed. Error: \(error.localizedDescription)") + } +} + +// swiftlint:enable file_types_order + +package enum BodyLoggingPolicy { + /// Never log request or response bodies. + case never + /// Log request and response bodies that have a known length less than or equal to `maxBytes`. + case upTo(maxBytes: Int) + + enum BodyLog: Equatable, CustomStringConvertible { + /// There is no body to log. + case none + /// The policy forbids logging the body. + case redacted + /// The body was of unknown length. + case unknownLength + /// The body exceeds the maximum size for logging allowed by the policy. + case tooManyBytesToLog(Int64) + /// The body can be logged. + case complete(Data) + + var description: String { + switch self { + case .none: return "" + case .redacted: return "" + case .unknownLength: return "" + case let .tooManyBytesToLog(byteCount): return "<\(byteCount) bytes>" + case let .complete(data): + if let string = String(data: data, encoding: .utf8) { return string } + return String(describing: data) + } + } + } + + func process(_ body: HTTPBody?) async throws -> (bodyToLog: BodyLog, bodyForNext: HTTPBody?) { + switch (body?.length, self) { + case (.none, _): return (.none, body) + case (_, .never): return (.redacted, body) + case (.unknown, _): return (.unknownLength, body) + case let (.known(length), .upTo(maxBytesToLog)) where length > maxBytesToLog: + return (.tooManyBytesToLog(length), body) + case let (.known, .upTo(maxBytesToLog)): + let bodyData = try await Data(collecting: body!, upTo: maxBytesToLog) + return (.complete(bodyData), HTTPBody(bodyData)) + } + } +} diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABItem.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABItem.swift index 9c2e97ad..aab719bf 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABItem.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABItem.swift @@ -13,7 +13,7 @@ import CoreLocation import os.log import UIKit -public final class OpenHABItem: NSObject, CommItem { +public class OpenHABItem: NSObject, CommItem { public enum ItemType: String { case color = "Color" case contact = "Contact" diff --git a/OpenHABCore/Sources/OpenHABCore/openapi/openapi.json b/OpenHABCore/Sources/OpenHABCore/openapi/openapi.json index facdf003..d34f3343 100644 --- a/OpenHABCore/Sources/OpenHABCore/openapi/openapi.json +++ b/OpenHABCore/Sources/OpenHABCore/openapi/openapi.json @@ -5501,7 +5501,17 @@ "operationId": "createSitemapEventSubscription", "responses": { "201": { - "description": "Subscription created." + "description": "Subscription created.", + }, + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JerseyResponseBuilderDTO" + } + } + } }, "503": { "description": "Subscriptions limit reached." @@ -5606,6 +5616,14 @@ "type": "string" } }, + { + "name": "X-Atmosphere-Transport", + "in": "header", + "description": "X-Atmosphere-Transport for long polling", + "schema": { + "type": "string" + } + }, { "name": "sitemapname", "in": "path", @@ -5794,7 +5812,15 @@ ], "responses": { "200": { - "description": "OK" + "description": "OK", + "content": { + "text/event-stream": {}, + "application/json": { + "schema": { + "$ref": "#/components/schemas/SitemapWidgetEvent" + } + } + } }, "400": { "description": "Missing sitemap or page parameter, or page not linked successfully to the subscription." @@ -9001,6 +9027,36 @@ } } }, + "JerseyResponseBuilderDTO": { + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "context": { + "$ref": "#/components/schemas/ContextDTO" + } + } + }, + "ContextDTO": { + "type": "object", + "properties": { + "headers": { + "$ref": "#/components/schemas/HeadersDTO" + } + } + }, + "HeadersDTO": { + "type": "object", + "properties": { + "Location": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, "ChannelDefinitionDTO": { "type": "object", "properties": { @@ -9450,6 +9506,53 @@ } } }, + "SitemapWidgetEvent": { + "type": "object", + "properties": { + "widgetId": { + "type": "string" + }, + "label": { + "type": "string" + }, + "labelSource": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "labelcolor": { + "type": "string" + }, + "valuecolor": { + "type": "string" + }, + "iconcolor": { + "type": "string" + }, + "state": { + "type": "string" + }, + "reloadIcon": { + "type": "boolean" + }, + "visibility": { + "type": "boolean" + }, + "descriptionChanged": { + "type": "boolean" + }, + "item": { + "$ref": "#/components/schemas/EnrichedItemDTO" + }, + "sitemapName": { + "type": "string" + }, + "pageId": { + "type": "string" + } + } + }, "SitemapDTO": { "type": "object", "properties": { diff --git a/openHAB/OpenHABDrawerTableViewController.swift b/openHAB/OpenHABDrawerTableViewController.swift index cbe48ed7..ee009bf8 100644 --- a/openHAB/OpenHABDrawerTableViewController.swift +++ b/openHAB/OpenHABDrawerTableViewController.swift @@ -16,6 +16,8 @@ import os.log import SafariServices import UIKit +let logger = Logger(subsystem: "org.openhab.app", category: "OpenHABDrawerTableViewController") + struct UiTile: Decodable { var name: String var url: String @@ -37,17 +39,7 @@ class OpenHABDrawerTableViewController: UITableViewController { AppDelegate.appDelegate.appData } - private let apiactor: APIActor - - init() { - apiactor = APIActor() - super.init(nibName: nil, bundle: nil) - } - - required init?(coder aDecoder: NSCoder) { - apiactor = APIActor() - super.init(coder: aDecoder) - } + private var apiactor: APIActor? override func viewDidLoad() { super.viewDidLoad() @@ -65,9 +57,8 @@ class OpenHABDrawerTableViewController: UITableViewController { Task { do { - await apiactor.updateBaseURL(with: URL(string: appData?.openHABRootUrl ?? "")!) - - sitemaps = try await apiactor.openHABSitemaps() + apiactor = await APIActor(username: appData!.openHABUsername, password: appData!.openHABPassword, alwaysSendBasicAuth: appData!.openHABAlwaysSendCreds, url: URL(string: appData?.openHABRootUrl ?? "")!) + sitemaps = try await apiactor?.openHABSitemaps() ?? [] if sitemaps.last?.name == "_default", sitemaps.count > 1 { sitemaps = Array(sitemaps.dropLast()) } @@ -81,7 +72,7 @@ class OpenHABDrawerTableViewController: UITableViewController { self.setStandardDrawerItems() self.tableView.reloadData() } catch { - os_log("%{PUBLIC}@", log: .default, type: .error, error.localizedDescription) + os_log("Error %{PUBLIC}@", log: .default, type: .error, error.localizedDescription) self.drawerItems.removeAll() self.setStandardDrawerItems() self.tableView.reloadData() @@ -90,8 +81,8 @@ class OpenHABDrawerTableViewController: UITableViewController { Task { do { - await apiactor.updateBaseURL(with: URL(string: appData?.openHABRootUrl ?? "")!) - uiTiles = try await apiactor.openHABTiles() + await apiactor = APIActor(username: appData!.openHABUsername, password: appData!.openHABPassword, alwaysSendBasicAuth: appData!.openHABAlwaysSendCreds, url: URL(string: appData?.openHABRootUrl ?? "")!) + uiTiles = try await apiactor?.openHABTiles() ?? [] os_log("ui tiles response", log: .viewCycle, type: .info) self.tableView.reloadData() } catch { diff --git a/openHAB/OpenHABSitemapViewController.swift b/openHAB/OpenHABSitemapViewController.swift index 9b01fb65..7ff07ff6 100644 --- a/openHAB/OpenHABSitemapViewController.swift +++ b/openHAB/OpenHABSitemapViewController.swift @@ -112,7 +112,7 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel search.isActive && !searchBarIsEmpty } - private let apiactor = APIActor() + private var apiactor: APIActor? @IBOutlet private var widgetTableView: UITableView! @@ -124,6 +124,7 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel pageNetworkStatus = nil sitemaps = [] widgetTableView.tableFooterView = UIView() + Task { await apiactor = APIActor(username: openHABUsername, password: openHABPassword, alwaysSendBasicAuth: openHABAlwaysSendCreds, url: URL(string: openHABRootUrl) ?? URL(staticString: "about:blank")) } registerTableViewCells() configureTableView() @@ -182,7 +183,7 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel OpenHABTracker.shared.multicastDelegate.add(self) OpenHABTracker.shared.restart() } else { - Task { await apiactor.updateBaseURL(with: URL(string: appData!.openHABRootUrl)!) } + Task { await apiactor?.updateBaseURL(with: URL(string: appData!.openHABRootUrl)!) } if !pageNetworkStatusChanged() { os_log("OpenHABSitemapViewController pageUrl = %{PUBLIC}@", log: .notifications, type: .info, pageUrl) loadPage(false) @@ -330,9 +331,14 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel } asyncOperation = Task { do { - await apiactor.updateBaseURL(with: URL(string: appData?.openHABRootUrl ?? "")!) + await apiactor?.updateBaseURL(with: URL(string: appData?.openHABRootUrl ?? "")!) - currentPage = try await apiactor.openHABpollPage(sitemapname: defaultSitemap, longPolling: longPolling) +// if let subscriptionid = try await apiactor?.openHABcreateSubscription() { +// let sitemap = try await apiactor?.openHABpollSitemap(sitemapname: defaultSitemap, longPolling: longPolling, subscriptionId: subscriptionid) +// try await apiactor?.openHABSitemapWidgetEvents(subscriptionid: subscriptionid, sitemap: defaultSitemap) +// } + + currentPage = try await apiactor?.openHABpollPage(sitemapname: defaultSitemap, longPolling: longPolling) if isFiltering { filterContentForSearchText(search.searchBar.text) @@ -379,9 +385,9 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel func selectSitemap() { Task { do { - await apiactor.updateBaseURL(with: URL(string: appData?.openHABRootUrl ?? "")!) - - sitemaps = try await apiactor.openHABSitemaps() + logger.debug("Running selectSitemap for URL: \(self.appData?.openHABRootUrl ?? "")") + apiactor = await APIActor(username: appData!.openHABUsername, password: appData!.openHABPassword, alwaysSendBasicAuth: appData!.openHABAlwaysSendCreds, url: URL(string: appData?.openHABRootUrl ?? "")!) + sitemaps = try await apiactor?.openHABSitemaps() ?? [] switch sitemaps.count { case 2...: @@ -407,6 +413,8 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel default: break } widgetTableView.reloadData() + } catch let error as APIActorError { + logger.debug("APIActorError on OpenHABSitemapViewController") } catch { os_log("%{PUBLIC}@", log: .default, type: .error, error.localizedDescription) DispatchQueue.main.async { @@ -491,11 +499,12 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel } func sendCommand(itemname: String, command: String) { - Task { try await apiactor.openHABSendItemCommand(itemname: itemname, command: command) } + Task { try await apiactor?.openHABSendItemCommand(itemname: itemname, command: command) } } override func reloadView() { defaultSitemap = Preferences.defaultSitemap + logger.debug("Reload view") selectSitemap() } diff --git a/openHAB/OpenHABWebViewController.swift b/openHAB/OpenHABWebViewController.swift index e0cbb224..e68e0616 100644 --- a/openHAB/OpenHABWebViewController.swift +++ b/openHAB/OpenHABWebViewController.swift @@ -13,7 +13,6 @@ import OpenHABCore import os.log import SafariServices import SideMenu -import SwiftMessages import UIKit import WebKit From eecb27eac02f61dfb1672cb01fb78878a823aefa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=BCller-Seydlitz?= Date: Sun, 18 Aug 2024 22:31:11 +0200 Subject: [PATCH 04/13] Created LoggingMiddleware to be separated from AuthorisationMiddleware update OpenHABWidget with OpenHABSitemapWidgetEvent Update to swift-tools-version 5.10 --- OpenHABCore/Package.swift | 2 +- .../{Model => Util}/APIActor.swift | 121 +++++++++++++----- .../Util/AuthorisationMiddleware.swift | 49 +++++++ .../{Model => Util}/LoggingMiddleware.swift | 0 .../xcshareddata/swiftpm/Package.resolved | 3 +- 5 files changed, 138 insertions(+), 37 deletions(-) rename OpenHABCore/Sources/OpenHABCore/{Model => Util}/APIActor.swift (81%) create mode 100644 OpenHABCore/Sources/OpenHABCore/Util/AuthorisationMiddleware.swift rename OpenHABCore/Sources/OpenHABCore/{Model => Util}/LoggingMiddleware.swift (100%) diff --git a/OpenHABCore/Package.swift b/OpenHABCore/Package.swift index ffe19e38..eab75daa 100644 --- a/OpenHABCore/Package.swift +++ b/OpenHABCore/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.9 +// swift-tools-version:5.10 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription diff --git a/OpenHABCore/Sources/OpenHABCore/Model/APIActor.swift b/OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift similarity index 81% rename from OpenHABCore/Sources/OpenHABCore/Model/APIActor.swift rename to OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift index f1433b84..b2cd57f5 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/APIActor.swift +++ b/OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift @@ -40,7 +40,9 @@ public actor APIActor { let config = URLSessionConfiguration.default // config.timeoutIntervalForRequest = if longPolling { 35.0 } else { 20.0 } // config.timeoutIntervalForResource = config.timeoutIntervalForRequest + 25 - let session = URLSession(configuration: config) + + let delegate = APIActorDelegate(username: username, password: password) + let session = URLSession(configuration: config, delegate: delegate, delegateQueue: nil) self.username = username self.password = password self.alwaysSendBasicAuth = alwaysSendBasicAuth @@ -242,6 +244,89 @@ public extension APIActor { } } +// MARK: - URLSessionDelegate for Client Certificates and Basic Auth + +class APIActorDelegate: NSObject, URLSessionDelegate, URLSessionTaskDelegate { + private let username: String + private let password: String + + init(username: String, password: String) { + self.username = username + self.password = password + } + + public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { + await urlSessionInternal(session, task: nil, didReceive: challenge) + } + + public func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { + await urlSessionInternal(session, task: task, didReceive: challenge) + } + + private func urlSessionInternal(_ session: URLSession, task: URLSessionTask?, didReceive challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { + os_log("URLAuthenticationChallenge: %{public}@", log: .networking, type: .info, challenge.protectionSpace.authenticationMethod) + let authenticationMethod = challenge.protectionSpace.authenticationMethod + switch authenticationMethod { + case NSURLAuthenticationMethodServerTrust: + return await handleServerTrust(challenge: challenge) + case NSURLAuthenticationMethodDefault, NSURLAuthenticationMethodHTTPBasic: + if let task { + task.authAttemptCount += 1 + if task.authAttemptCount > 1 { + return (.cancelAuthenticationChallenge, nil) + } else { + return await handleBasicAuth(challenge: challenge) + } + } else { + return await handleBasicAuth(challenge: challenge) + } + case NSURLAuthenticationMethodClientCertificate: + return await handleClientCertificateAuth(challenge: challenge) + default: + return (.performDefaultHandling, nil) + } + } + + private func handleServerTrust(challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { + guard let serverTrust = challenge.protectionSpace.serverTrust else { + return (.performDefaultHandling, nil) + } + let credential = URLCredential(trust: serverTrust) + return (.useCredential, credential) + } + + private func handleBasicAuth(challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { + let credential = URLCredential(user: username, password: password, persistence: .forSession) + return (.useCredential, credential) + } + + private func handleClientCertificateAuth(challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { + let certificateManager = ClientCertificateManager() + let (disposition, credential) = certificateManager.evaluateTrust(with: challenge) + return (disposition, credential) + } +} + +extension OpenHABWidget { + func update(with event: OpenHABSitemapWidgetEvent) { + + state = event.state ?? self.state + icon = event.icon ?? self.icon + label = event.label ?? self.label + iconColor = event.iconcolor ?? "" + labelcolor = event.labelcolor ?? "" + valuecolor = event.valuecolor ?? "" + visibility = event.visibility ?? self.visibility + + if let enrichedItem = event.enrichedItem { + if let link = self.item?.link { + enrichedItem.link = link + } + item = enrichedItem + } + } +} + class OpenHABSitemapWidgetEvent { init(sitemapName: String? = nil, pageId: String? = nil, widgetId: String? = nil, label: String? = nil, labelSource: String? = nil, icon: String? = nil, reloadIcon: Bool? = nil, labelcolor: String? = nil, valuecolor: String? = nil, iconcolor: String? = nil, visibility: Bool? = nil, state: String? = nil, enrichedItem: OpenHABItem? = nil, descriptionChanged: Bool? = nil) { self.sitemapName = sitemapName @@ -280,40 +365,6 @@ class OpenHABSitemapWidgetEvent { var descriptionChanged: Bool? } -public struct AuthorisationMiddleware { - private let username: String - private let password: String - private let alwaysSendBasicAuth: Bool - - public init(username: String, password: String, alwaysSendBasicAuth: Bool = false) { - self.username = username - self.password = password - self.alwaysSendBasicAuth = alwaysSendBasicAuth - } -} - -extension AuthorisationMiddleware: ClientMiddleware { - private func basicAuthHeader() -> String { - let credential = Data("\(username):\(password)".utf8).base64EncodedString() - return "Basic \(credential)" - } - - public func intercept(_ request: HTTPRequest, - body: HTTPBody?, - baseURL: URL, - operationID: String, - next: @Sendable (HTTPRequest, HTTPBody?, URL) async throws -> (HTTPResponse, HTTPBody?)) async throws -> (HTTPResponse, HTTPBody?) { - // Use a mutable copy of request - var request = request - - if baseURL.host?.hasSuffix("myopenhab.org") == nil, alwaysSendBasicAuth, !username.isEmpty, !password.isEmpty { - request.headerFields[.authorization] = basicAuthHeader() - } - let (response, body) = try await next(request, body, baseURL) - return (response, body) - } -} - extension OpenHABUiTile { convenience init(_ tile: Components.Schemas.TileDTO) { self.init(name: tile.name.orEmpty, url: tile.url.orEmpty, imageUrl: tile.imageUrl.orEmpty) diff --git a/OpenHABCore/Sources/OpenHABCore/Util/AuthorisationMiddleware.swift b/OpenHABCore/Sources/OpenHABCore/Util/AuthorisationMiddleware.swift new file mode 100644 index 00000000..82ae3c67 --- /dev/null +++ b/OpenHABCore/Sources/OpenHABCore/Util/AuthorisationMiddleware.swift @@ -0,0 +1,49 @@ +// Copyright (c) 2010-2024 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation +import HTTPTypes +import OpenAPIRuntime +import OpenAPIURLSession +import os + +public struct AuthorisationMiddleware { + private let username: String + private let password: String + private let alwaysSendBasicAuth: Bool + + public init(username: String, password: String, alwaysSendBasicAuth: Bool = false) { + self.username = username + self.password = password + self.alwaysSendBasicAuth = alwaysSendBasicAuth + } +} + +extension AuthorisationMiddleware: ClientMiddleware { + private func basicAuthHeader() -> String { + let credential = Data("\(username):\(password)".utf8).base64EncodedString() + return "Basic \(credential)" + } + + public func intercept(_ request: HTTPRequest, + body: HTTPBody?, + baseURL: URL, + operationID: String, + next: @Sendable (HTTPRequest, HTTPBody?, URL) async throws -> (HTTPResponse, HTTPBody?)) async throws -> (HTTPResponse, HTTPBody?) { + // Use a mutable copy of request + var request = request + if baseURL.host?.hasSuffix("myopenhab.org") == nil, alwaysSendBasicAuth, !username.isEmpty, !password.isEmpty { + request.headerFields[.authorization] = basicAuthHeader() + } + let (response, body) = try await next(request, body, baseURL) + return (response, body) + } +} diff --git a/OpenHABCore/Sources/OpenHABCore/Model/LoggingMiddleware.swift b/OpenHABCore/Sources/OpenHABCore/Util/LoggingMiddleware.swift similarity index 100% rename from OpenHABCore/Sources/OpenHABCore/Model/LoggingMiddleware.swift rename to OpenHABCore/Sources/OpenHABCore/Util/LoggingMiddleware.swift diff --git a/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved b/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved index 9636f6eb..8f57eb61 100644 --- a/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,4 +1,5 @@ { + "originHash" : "3bc6a2e9afce7e9424388f65dacbd328261dab0cfc5ae52bc4c92551494b6d12", "pins" : [ { "identity" : "abseil-cpp-binary", @@ -253,5 +254,5 @@ } } ], - "version" : 2 + "version" : 3 } From 7a32f3927f54a4fab7ac526c68ad9e8ee328fb33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=BCller-Seydlitz?= Date: Mon, 19 Aug 2024 21:48:54 +0200 Subject: [PATCH 05/13] Subcribe to events and map received events to OpenHABSitemapWidgetEvents In order not to expose decode OpenHABSitemapWidgetEvents manually. Some relaxations required on OpenHABItem --- .../OpenHABCore/Model/OpenHABItem.swift | 7 +- .../Sources/OpenHABCore/Util/APIActor.swift | 108 ++++++++++++------ openHAB/OpenHABSitemapViewController.swift | 17 ++- 3 files changed, 86 insertions(+), 46 deletions(-) diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABItem.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABItem.swift index aab719bf..ac4d7c17 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABItem.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABItem.swift @@ -28,6 +28,7 @@ public class OpenHABItem: NSObject, CommItem { case rollershutter = "Rollershutter" case stringItem = "String" case switchItem = "Switch" + case undetermind = "" // Relevant only for SitemapWidgetEvent } public var type: ItemType? @@ -125,10 +126,10 @@ public extension OpenHABItem { public extension OpenHABItem { struct CodingData: Decodable { - let type: String + let type: String? let groupType: String? let name: String - let link: String + let link: String? let state: String? let label: String? let stateDescription: OpenHABStateDescription.CodingData? @@ -144,7 +145,7 @@ public extension OpenHABItem.CodingData { var openHABItem: OpenHABItem { let mappedMembers = members?.map(\.openHABItem) ?? [] - return OpenHABItem(name: name, type: type, state: state, link: link, label: label, groupType: groupType, stateDescription: stateDescription?.openHABStateDescription, commandDescription: commandDescription?.openHABCommandDescription, members: mappedMembers, category: category, options: options) + return OpenHABItem(name: name, type: type ?? "", state: state, link: link ?? "", label: label, groupType: groupType, stateDescription: stateDescription?.openHABStateDescription, commandDescription: commandDescription?.openHABCommandDescription, members: mappedMembers, category: category, options: options) } } diff --git a/OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift b/OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift index b2cd57f5..3793082d 100644 --- a/OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift +++ b/OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift @@ -155,23 +155,16 @@ public extension APIActor { return URL(string: urlString)?.lastPathComponent } - func openHABSitemapWidgetEvents(subscriptionid: String, sitemap: String) async throws -> String { -// AsyncThrowingStream { + func openHABSitemapWidgetEvents(subscriptionid: String, sitemap: String) async throws -> AsyncThrowingCompactMapSequence>, OpenHABSitemapWidgetEvent> { let path = Operations.getSitemapEvents_1.Input.Path(subscriptionid: subscriptionid) let query = Operations.getSitemapEvents_1.Input.Query(sitemap: sitemap, pageid: sitemap) - let stream = try await api.getSitemapEvents_1(path: path, query: query).ok.body.text_event_hyphen_stream.asDecodedServerSentEventsWithJSONData(of: Components.Schemas.SitemapWidgetEvent.self).compactMap { (value) -> OpenHABSitemapWidgetEvent? in - guard let data = value.data else { return nil } - return OpenHABSitemapWidgetEvent(data) + let decodedSequence = try await api.getSitemapEvents_1(path: path, query: query).ok.body.text_event_hyphen_stream.asDecodedServerSentEvents() + let opaqueSequence = decodedSequence.compactMap { (event) in + if let data = event.data { + try JSONDecoder().decode(OpenHABSitemapWidgetEvent.CodingData.self, from: Data(data.utf8)).openHABSitemapWidgetEvent + } else { nil } } -// return stream.map2 - - for try await line in stream { - print(line) - print("\n") - } - return "" - - logger.debug("subscription date received") + return opaqueSequence } } @@ -309,17 +302,16 @@ class APIActorDelegate: NSObject, URLSessionDelegate, URLSessionTaskDelegate { extension OpenHABWidget { func update(with event: OpenHABSitemapWidgetEvent) { - - state = event.state ?? self.state - icon = event.icon ?? self.icon - label = event.label ?? self.label + state = event.state ?? state + icon = event.icon ?? icon + label = event.label ?? label iconColor = event.iconcolor ?? "" labelcolor = event.labelcolor ?? "" valuecolor = event.valuecolor ?? "" - visibility = event.visibility ?? self.visibility - + visibility = event.visibility ?? visibility + if let enrichedItem = event.enrichedItem { - if let link = self.item?.link { + if let link = item?.link { enrichedItem.link = link } item = enrichedItem @@ -327,7 +319,22 @@ extension OpenHABWidget { } } -class OpenHABSitemapWidgetEvent { +public class OpenHABSitemapWidgetEvent { + var sitemapName: String? + var pageId: String? + var widgetId: String? + var label: String? + var labelSource: String? + var icon: String? + var reloadIcon: Bool? + var labelcolor: String? + var valuecolor: String? + var iconcolor: String? + var visibility: Bool? + var state: String? + var enrichedItem: OpenHABItem? + var descriptionChanged: Bool? + init(sitemapName: String? = nil, pageId: String? = nil, widgetId: String? = nil, label: String? = nil, labelSource: String? = nil, icon: String? = nil, reloadIcon: Bool? = nil, labelcolor: String? = nil, valuecolor: String? = nil, iconcolor: String? = nil, visibility: Bool? = nil, state: String? = nil, enrichedItem: OpenHABItem? = nil, descriptionChanged: Bool? = nil) { self.sitemapName = sitemapName self.pageId = pageId @@ -345,24 +352,51 @@ class OpenHABSitemapWidgetEvent { self.descriptionChanged = descriptionChanged } - convenience init(_ event: Components.Schemas.SitemapWidgetEvent) { + convenience init?(_ event: Components.Schemas.SitemapWidgetEvent?) { + guard let event else { return nil } self.init(sitemapName: event.sitemapName, pageId: event.pageId, widgetId: event.widgetId, label: event.label, labelSource: event.labelSource, icon: event.icon, reloadIcon: event.reloadIcon, labelcolor: event.labelcolor, valuecolor: event.valuecolor, iconcolor: event.iconcolor, visibility: event.visibility, state: event.state, enrichedItem: OpenHABItem(event.item), descriptionChanged: event.descriptionChanged) } +} - var sitemapName: String? - var pageId: String? - var widgetId: String? - var label: String? - var labelSource: String? - var icon: String? - var reloadIcon: Bool? - var labelcolor: String? - var valuecolor: String? - var iconcolor: String? - var visibility: Bool? - var state: String? - var enrichedItem: OpenHABItem? - var descriptionChanged: Bool? +extension OpenHABSitemapWidgetEvent: CustomStringConvertible { + public var description: String { + "\(widgetId) \(label) \(enrichedItem?.state)" + } +} + +public extension OpenHABSitemapWidgetEvent { + struct CodingData: Decodable, Hashable, Equatable { + public static func == (lhs: OpenHABSitemapWidgetEvent.CodingData, rhs: OpenHABSitemapWidgetEvent.CodingData) -> Bool { + lhs.widgetId == rhs.widgetId + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(widgetId) + } + + var sitemapName: String? + var pageId: String? + var widgetId: String? + var label: String? + var labelSource: String? + var icon: String? + var reloadIcon: Bool? + var labelcolor: String? + var valuecolor: String? + var iconcolor: String? + var visibility: Bool? +// var state: String? + var item: OpenHABItem.CodingData? + var descriptionChanged: Bool? + var link: String? + } +} + +extension OpenHABSitemapWidgetEvent.CodingData { + var openHABSitemapWidgetEvent: OpenHABSitemapWidgetEvent { + // swiftlint:disable:next line_length + OpenHABSitemapWidgetEvent(sitemapName: sitemapName, pageId: pageId, widgetId: widgetId, label: label, labelSource: labelSource, icon: icon, reloadIcon: reloadIcon, labelcolor: labelcolor, valuecolor: valuecolor, iconcolor: iconcolor, visibility: visibility, enrichedItem: item?.openHABItem, descriptionChanged: descriptionChanged) + } } extension OpenHABUiTile { diff --git a/openHAB/OpenHABSitemapViewController.swift b/openHAB/OpenHABSitemapViewController.swift index 7ff07ff6..d627c743 100644 --- a/openHAB/OpenHABSitemapViewController.swift +++ b/openHAB/OpenHABSitemapViewController.swift @@ -331,12 +331,17 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel } asyncOperation = Task { do { - await apiactor?.updateBaseURL(with: URL(string: appData?.openHABRootUrl ?? "")!) - -// if let subscriptionid = try await apiactor?.openHABcreateSubscription() { -// let sitemap = try await apiactor?.openHABpollSitemap(sitemapname: defaultSitemap, longPolling: longPolling, subscriptionId: subscriptionid) -// try await apiactor?.openHABSitemapWidgetEvents(subscriptionid: subscriptionid, sitemap: defaultSitemap) -// } + if let apiactor { + await apiactor.updateBaseURL(with: URL(string: appData?.openHABRootUrl ?? "")!) + + if let subscriptionid = try await apiactor.openHABcreateSubscription() { + let sitemap = try await apiactor.openHABpollSitemap(sitemapname: defaultSitemap, longPolling: longPolling, subscriptionId: subscriptionid) + let events = try await apiactor.openHABSitemapWidgetEvents(subscriptionid: subscriptionid, sitemap: defaultSitemap) + for try await event in events { + print(event) + } + } + } currentPage = try await apiactor?.openHABpollPage(sitemapname: defaultSitemap, longPolling: longPolling) From aaf8b49e87132e8ef185854104eba5a7f32975fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=BCller-Seydlitz?= Date: Tue, 20 Aug 2024 21:58:40 +0200 Subject: [PATCH 06/13] Using logger --- .../Sources/OpenHABCore/Util/APIActor.swift | 25 ------------------- openHAB/OpenHABSitemapViewController.swift | 4 ++- 2 files changed, 3 insertions(+), 26 deletions(-) diff --git a/OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift b/OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift index 3793082d..0083c97b 100644 --- a/OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift +++ b/OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift @@ -122,31 +122,6 @@ extension APIActor: OpenHABUiTileService { } } -public extension AsyncThrowingStream { -// func map(_ transform: @escaping (Self.Element) -> Transformed) -> AsyncThrowingStream { -// AsyncThrowingStream { continuation in -// Task { -// for try await element in self { -// continuation.yield(transform(element)) -// } -// continuation.finish() -// } -// } -// } - - func map2(transform: @escaping (Self.Element) -> T) -> AsyncThrowingStream { - AsyncThrowingStream { continuation in - let task = Task { - for try await element in self { - continuation.yield(transform(element)) - } - continuation.finish() - } - continuation.onTermination = { _ in task.cancel() } - } - } -} - public extension APIActor { func openHABcreateSubscription() async throws -> String? { logger.info("Creating subscription") diff --git a/openHAB/OpenHABSitemapViewController.swift b/openHAB/OpenHABSitemapViewController.swift index d627c743..0056255a 100644 --- a/openHAB/OpenHABSitemapViewController.swift +++ b/openHAB/OpenHABSitemapViewController.swift @@ -87,6 +87,8 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel private var isWaitingToReload = false private var asyncOperation: Task? + private let logger = Logger(subsystem: "org.openhab.app", category: "OpenHABSitemapViewController") + var relevantPage: OpenHABPage? { if isFiltering { filteredPage @@ -333,8 +335,8 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel do { if let apiactor { await apiactor.updateBaseURL(with: URL(string: appData?.openHABRootUrl ?? "")!) - if let subscriptionid = try await apiactor.openHABcreateSubscription() { + logger.log("Got subscriptionid: \(subscriptionid)") let sitemap = try await apiactor.openHABpollSitemap(sitemapname: defaultSitemap, longPolling: longPolling, subscriptionId: subscriptionid) let events = try await apiactor.openHABSitemapWidgetEvents(subscriptionid: subscriptionid, sitemap: defaultSitemap) for try await event in events { From ec0fc85553a28cfc7189c59299893a3f7fc6e090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=BCller-Seydlitz?= Date: Mon, 26 Aug 2024 19:45:47 +0200 Subject: [PATCH 07/13] Changed accessModifier to public - To be changed back to internal when switching to swift 6.0 --- .../GeneratedSources/openapi/Client.swift | 70 +- .../GeneratedSources/openapi/Types.swift | 2410 ++++++++--------- .../Sources/OpenHABCore/Util/APIActor.swift | 14 +- .../openapi/openapi-generator-config.yml | 2 +- openHAB/OpenHABSitemapViewController.swift | 1 + 5 files changed, 1248 insertions(+), 1249 deletions(-) diff --git a/OpenHABCore/Sources/OpenHABCore/GeneratedSources/openapi/Client.swift b/OpenHABCore/Sources/OpenHABCore/GeneratedSources/openapi/Client.swift index 9f0f22bf..65925680 100644 --- a/OpenHABCore/Sources/OpenHABCore/GeneratedSources/openapi/Client.swift +++ b/OpenHABCore/Sources/OpenHABCore/GeneratedSources/openapi/Client.swift @@ -22,7 +22,7 @@ import struct Foundation.URL #endif import HTTPTypes -struct Client: APIProtocol { +public struct Client: APIProtocol { /// The underlying HTTP client. private let client: UniversalClient /// Creates a new client. @@ -33,10 +33,10 @@ struct Client: APIProtocol { /// - configuration: A set of configuration values for the client. /// - transport: A transport that performs HTTP operations. /// - middlewares: A list of middlewares to call before the transport. - init(serverURL: Foundation.URL, - configuration: Configuration = .init(), - transport: any ClientTransport, - middlewares: [any ClientMiddleware] = []) { + public init(serverURL: Foundation.URL, + configuration: Configuration = .init(), + transport: any ClientTransport, + middlewares: [any ClientMiddleware] = []) { client = .init( serverURL: serverURL, configuration: configuration, @@ -53,7 +53,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `PUT /items/{itemName}/members/{memberItemName}`. /// - Remark: Generated from `#/paths//items/{itemName}/members/{memberItemName}/put(addMemberToGroupItem)`. - func addMemberToGroupItem(_ input: Operations.addMemberToGroupItem.Input) async throws -> Operations.addMemberToGroupItem.Output { + public func addMemberToGroupItem(_ input: Operations.addMemberToGroupItem.Input) async throws -> Operations.addMemberToGroupItem.Output { try await client.send( input: input, forOperation: Operations.addMemberToGroupItem.id, @@ -97,7 +97,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `DELETE /items/{itemName}/members/{memberItemName}`. /// - Remark: Generated from `#/paths//items/{itemName}/members/{memberItemName}/delete(removeMemberFromGroupItem)`. - func removeMemberFromGroupItem(_ input: Operations.removeMemberFromGroupItem.Input) async throws -> Operations.removeMemberFromGroupItem.Output { + public func removeMemberFromGroupItem(_ input: Operations.removeMemberFromGroupItem.Input) async throws -> Operations.removeMemberFromGroupItem.Output { try await client.send( input: input, forOperation: Operations.removeMemberFromGroupItem.id, @@ -141,7 +141,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `PUT /items/{itemname}/metadata/{namespace}`. /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/put(addMetadataToItem)`. - func addMetadataToItem(_ input: Operations.addMetadataToItem.Input) async throws -> Operations.addMetadataToItem.Output { + public func addMetadataToItem(_ input: Operations.addMetadataToItem.Input) async throws -> Operations.addMetadataToItem.Output { try await client.send( input: input, forOperation: Operations.addMetadataToItem.id, @@ -197,7 +197,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `DELETE /items/{itemname}/metadata/{namespace}`. /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/delete(removeMetadataFromItem)`. - func removeMetadataFromItem(_ input: Operations.removeMetadataFromItem.Input) async throws -> Operations.removeMetadataFromItem.Output { + public func removeMetadataFromItem(_ input: Operations.removeMetadataFromItem.Input) async throws -> Operations.removeMetadataFromItem.Output { try await client.send( input: input, forOperation: Operations.removeMetadataFromItem.id, @@ -241,7 +241,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `PUT /items/{itemname}/tags/{tag}`. /// - Remark: Generated from `#/paths//items/{itemname}/tags/{tag}/put(addTagToItem)`. - func addTagToItem(_ input: Operations.addTagToItem.Input) async throws -> Operations.addTagToItem.Output { + public func addTagToItem(_ input: Operations.addTagToItem.Input) async throws -> Operations.addTagToItem.Output { try await client.send( input: input, forOperation: Operations.addTagToItem.id, @@ -285,7 +285,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `DELETE /items/{itemname}/tags/{tag}`. /// - Remark: Generated from `#/paths//items/{itemname}/tags/{tag}/delete(removeTagFromItem)`. - func removeTagFromItem(_ input: Operations.removeTagFromItem.Input) async throws -> Operations.removeTagFromItem.Output { + public func removeTagFromItem(_ input: Operations.removeTagFromItem.Input) async throws -> Operations.removeTagFromItem.Output { try await client.send( input: input, forOperation: Operations.removeTagFromItem.id, @@ -329,7 +329,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `GET /items/{itemname}`. /// - Remark: Generated from `#/paths//items/{itemname}/get(getItemByName)`. - func getItemByName(_ input: Operations.getItemByName.Input) async throws -> Operations.getItemByName.Output { + public func getItemByName(_ input: Operations.getItemByName.Input) async throws -> Operations.getItemByName.Output { try await client.send( input: input, forOperation: Operations.getItemByName.id, @@ -413,7 +413,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `POST /items/{itemname}`. /// - Remark: Generated from `#/paths//items/{itemname}/post(sendItemCommand)`. - func sendItemCommand(_ input: Operations.sendItemCommand.Input) async throws -> Operations.sendItemCommand.Output { + public func sendItemCommand(_ input: Operations.sendItemCommand.Input) async throws -> Operations.sendItemCommand.Output { try await client.send( input: input, forOperation: Operations.sendItemCommand.id, @@ -464,7 +464,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `PUT /items/{itemname}`. /// - Remark: Generated from `#/paths//items/{itemname}/put(addOrUpdateItemInRegistry)`. - func addOrUpdateItemInRegistry(_ input: Operations.addOrUpdateItemInRegistry.Input) async throws -> Operations.addOrUpdateItemInRegistry.Output { + public func addOrUpdateItemInRegistry(_ input: Operations.addOrUpdateItemInRegistry.Input) async throws -> Operations.addOrUpdateItemInRegistry.Output { try await client.send( input: input, forOperation: Operations.addOrUpdateItemInRegistry.id, @@ -548,7 +548,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `DELETE /items/{itemname}`. /// - Remark: Generated from `#/paths//items/{itemname}/delete(removeItemFromRegistry)`. - func removeItemFromRegistry(_ input: Operations.removeItemFromRegistry.Input) async throws -> Operations.removeItemFromRegistry.Output { + public func removeItemFromRegistry(_ input: Operations.removeItemFromRegistry.Input) async throws -> Operations.removeItemFromRegistry.Output { try await client.send( input: input, forOperation: Operations.removeItemFromRegistry.id, @@ -589,7 +589,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `GET /items`. /// - Remark: Generated from `#/paths//items/get(getItems)`. - func getItems(_ input: Operations.getItems.Input) async throws -> Operations.getItems.Output { + public func getItems(_ input: Operations.getItems.Input) async throws -> Operations.getItems.Output { try await client.send( input: input, forOperation: Operations.getItems.id, @@ -697,7 +697,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `PUT /items`. /// - Remark: Generated from `#/paths//items/put(addOrUpdateItemsInRegistry)`. - func addOrUpdateItemsInRegistry(_ input: Operations.addOrUpdateItemsInRegistry.Input) async throws -> Operations.addOrUpdateItemsInRegistry.Output { + public func addOrUpdateItemsInRegistry(_ input: Operations.addOrUpdateItemsInRegistry.Input) async throws -> Operations.addOrUpdateItemsInRegistry.Output { try await client.send( input: input, forOperation: Operations.addOrUpdateItemsInRegistry.id, @@ -768,7 +768,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `GET /items/{itemname}/state`. /// - Remark: Generated from `#/paths//items/{itemname}/state/get(getItemState_1)`. - func getItemState_1(_ input: Operations.getItemState_1.Input) async throws -> Operations.getItemState_1.Output { + public func getItemState_1(_ input: Operations.getItemState_1.Input) async throws -> Operations.getItemState_1.Output { try await client.send( input: input, forOperation: Operations.getItemState_1.id, @@ -833,7 +833,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `PUT /items/{itemname}/state`. /// - Remark: Generated from `#/paths//items/{itemname}/state/put(updateItemState)`. - func updateItemState(_ input: Operations.updateItemState.Input) async throws -> Operations.updateItemState.Output { + public func updateItemState(_ input: Operations.updateItemState.Input) async throws -> Operations.updateItemState.Output { try await client.send( input: input, forOperation: Operations.updateItemState.id, @@ -889,7 +889,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `GET /items/{itemname}/metadata/namespaces`. /// - Remark: Generated from `#/paths//items/{itemname}/metadata/namespaces/get(getItemNamespaces)`. - func getItemNamespaces(_ input: Operations.getItemNamespaces.Input) async throws -> Operations.getItemNamespaces.Output { + public func getItemNamespaces(_ input: Operations.getItemNamespaces.Input) async throws -> Operations.getItemNamespaces.Output { try await client.send( input: input, forOperation: Operations.getItemNamespaces.id, @@ -959,7 +959,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `GET /items/{itemName}/semantic/{semanticClass}`. /// - Remark: Generated from `#/paths//items/{itemName}/semantic/{semanticClass}/get(getSemanticItem)`. - func getSemanticItem(_ input: Operations.getSemanticItem.Input) async throws -> Operations.getSemanticItem.Output { + public func getSemanticItem(_ input: Operations.getSemanticItem.Input) async throws -> Operations.getSemanticItem.Output { try await client.send( input: input, forOperation: Operations.getSemanticItem.id, @@ -1006,7 +1006,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `POST /items/metadata/purge`. /// - Remark: Generated from `#/paths//items/metadata/purge/post(purgeDatabase)`. - func purgeDatabase(_ input: Operations.purgeDatabase.Input) async throws -> Operations.purgeDatabase.Output { + public func purgeDatabase(_ input: Operations.purgeDatabase.Input) async throws -> Operations.purgeDatabase.Output { try await client.send( input: input, forOperation: Operations.purgeDatabase.id, @@ -1043,7 +1043,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `POST /sitemaps/events/subscribe`. /// - Remark: Generated from `#/paths//sitemaps/events/subscribe/post(createSitemapEventSubscription)`. - func createSitemapEventSubscription(_ input: Operations.createSitemapEventSubscription.Input) async throws -> Operations.createSitemapEventSubscription.Output { + public func createSitemapEventSubscription(_ input: Operations.createSitemapEventSubscription.Input) async throws -> Operations.createSitemapEventSubscription.Output { try await client.send( input: input, forOperation: Operations.createSitemapEventSubscription.id, @@ -1108,7 +1108,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `GET /sitemaps/{sitemapname}/{pageid}`. /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/{pageid}/get(pollDataForPage)`. - func pollDataForPage(_ input: Operations.pollDataForPage.Input) async throws -> Operations.pollDataForPage.Output { + public func pollDataForPage(_ input: Operations.pollDataForPage.Input) async throws -> Operations.pollDataForPage.Output { try await client.send( input: input, forOperation: Operations.pollDataForPage.id, @@ -1200,7 +1200,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `GET /sitemaps/{sitemapname}/*`. /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/*/get(pollDataForSitemap)`. - func pollDataForSitemap(_ input: Operations.pollDataForSitemap.Input) async throws -> Operations.pollDataForSitemap.Output { + public func pollDataForSitemap(_ input: Operations.pollDataForSitemap.Input) async throws -> Operations.pollDataForSitemap.Output { try await client.send( input: input, forOperation: Operations.pollDataForSitemap.id, @@ -1291,7 +1291,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `GET /sitemaps/{sitemapname}`. /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/get(getSitemapByName)`. - func getSitemapByName(_ input: Operations.getSitemapByName.Input) async throws -> Operations.getSitemapByName.Output { + public func getSitemapByName(_ input: Operations.getSitemapByName.Input) async throws -> Operations.getSitemapByName.Output { try await client.send( input: input, forOperation: Operations.getSitemapByName.id, @@ -1380,7 +1380,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `GET /sitemaps/events/{subscriptionid}/*`. /// - Remark: Generated from `#/paths//sitemaps/events/{subscriptionid}/*/get(getSitemapEvents)`. - func getSitemapEvents(_ input: Operations.getSitemapEvents.Input) async throws -> Operations.getSitemapEvents.Output { + public func getSitemapEvents(_ input: Operations.getSitemapEvents.Input) async throws -> Operations.getSitemapEvents.Output { try await client.send( input: input, forOperation: Operations.getSitemapEvents.id, @@ -1430,7 +1430,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `GET /sitemaps/events/{subscriptionid}`. /// - Remark: Generated from `#/paths//sitemaps/events/{subscriptionid}/get(getSitemapEvents_1)`. - func getSitemapEvents_1(_ input: Operations.getSitemapEvents_1.Input) async throws -> Operations.getSitemapEvents_1.Output { + public func getSitemapEvents_1(_ input: Operations.getSitemapEvents_1.Input) async throws -> Operations.getSitemapEvents_1.Output { try await client.send( input: input, forOperation: Operations.getSitemapEvents_1.id, @@ -1520,7 +1520,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `GET /sitemaps`. /// - Remark: Generated from `#/paths//sitemaps/get(getSitemaps)`. - func getSitemaps(_ input: Operations.getSitemaps.Input) async throws -> Operations.getSitemaps.Output { + public func getSitemaps(_ input: Operations.getSitemaps.Input) async throws -> Operations.getSitemaps.Output { try await client.send( input: input, forOperation: Operations.getSitemaps.id, @@ -1581,7 +1581,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `GET /ui/components/{namespace}`. /// - Remark: Generated from `#/paths//ui/components/{namespace}/get(getRegisteredUIComponentsInNamespace)`. - func getRegisteredUIComponentsInNamespace(_ input: Operations.getRegisteredUIComponentsInNamespace.Input) async throws -> Operations.getRegisteredUIComponentsInNamespace.Output { + public func getRegisteredUIComponentsInNamespace(_ input: Operations.getRegisteredUIComponentsInNamespace.Input) async throws -> Operations.getRegisteredUIComponentsInNamespace.Output { try await client.send( input: input, forOperation: Operations.getRegisteredUIComponentsInNamespace.id, @@ -1651,7 +1651,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `POST /ui/components/{namespace}`. /// - Remark: Generated from `#/paths//ui/components/{namespace}/post(addUIComponentToNamespace)`. - func addUIComponentToNamespace(_ input: Operations.addUIComponentToNamespace.Input) async throws -> Operations.addUIComponentToNamespace.Output { + public func addUIComponentToNamespace(_ input: Operations.addUIComponentToNamespace.Input) async throws -> Operations.addUIComponentToNamespace.Output { try await client.send( input: input, forOperation: Operations.addUIComponentToNamespace.id, @@ -1724,7 +1724,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `GET /ui/components/{namespace}/{componentUID}`. /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/get(getUIComponentInNamespace)`. - func getUIComponentInNamespace(_ input: Operations.getUIComponentInNamespace.Input) async throws -> Operations.getUIComponentInNamespace.Output { + public func getUIComponentInNamespace(_ input: Operations.getUIComponentInNamespace.Input) async throws -> Operations.getUIComponentInNamespace.Output { try await client.send( input: input, forOperation: Operations.getUIComponentInNamespace.id, @@ -1790,7 +1790,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `PUT /ui/components/{namespace}/{componentUID}`. /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/put(updateUIComponentInNamespace)`. - func updateUIComponentInNamespace(_ input: Operations.updateUIComponentInNamespace.Input) async throws -> Operations.updateUIComponentInNamespace.Output { + public func updateUIComponentInNamespace(_ input: Operations.updateUIComponentInNamespace.Input) async throws -> Operations.updateUIComponentInNamespace.Output { try await client.send( input: input, forOperation: Operations.updateUIComponentInNamespace.id, @@ -1866,7 +1866,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `DELETE /ui/components/{namespace}/{componentUID}`. /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/delete(removeUIComponentFromNamespace)`. - func removeUIComponentFromNamespace(_ input: Operations.removeUIComponentFromNamespace.Input) async throws -> Operations.removeUIComponentFromNamespace.Output { + public func removeUIComponentFromNamespace(_ input: Operations.removeUIComponentFromNamespace.Input) async throws -> Operations.removeUIComponentFromNamespace.Output { try await client.send( input: input, forOperation: Operations.removeUIComponentFromNamespace.id, @@ -1908,7 +1908,7 @@ struct Client: APIProtocol { /// /// - Remark: HTTP `GET /ui/tiles`. /// - Remark: Generated from `#/paths//ui/tiles/get(getUITiles)`. - func getUITiles(_ input: Operations.getUITiles.Input) async throws -> Operations.getUITiles.Output { + public func getUITiles(_ input: Operations.getUITiles.Input) async throws -> Operations.getUITiles.Output { try await client.send( input: input, forOperation: Operations.getUITiles.id, diff --git a/OpenHABCore/Sources/OpenHABCore/GeneratedSources/openapi/Types.swift b/OpenHABCore/Sources/OpenHABCore/GeneratedSources/openapi/Types.swift index 23afee90..ed7400a1 100644 --- a/OpenHABCore/Sources/OpenHABCore/GeneratedSources/openapi/Types.swift +++ b/OpenHABCore/Sources/OpenHABCore/GeneratedSources/openapi/Types.swift @@ -21,7 +21,7 @@ import struct Foundation.Date import struct Foundation.URL #endif /// A type that performs HTTP operations defined by the OpenAPI document. -protocol APIProtocol: Sendable { +public protocol APIProtocol: Sendable { /// Adds a new member to a group item. /// /// - Remark: HTTP `PUT /items/{itemName}/members/{memberItemName}`. @@ -175,7 +175,7 @@ protocol APIProtocol: Sendable { } /// Convenience overloads for operation inputs. -extension APIProtocol { +public extension APIProtocol { /// Adds a new member to a group item. /// /// - Remark: HTTP `PUT /items/{itemName}/members/{memberItemName}`. @@ -514,8 +514,8 @@ extension APIProtocol { } /// Server URLs defined in the OpenAPI document. -enum Servers { - static func server1() throws -> Foundation.URL { +public enum Servers { + public static func server1() throws -> Foundation.URL { try Foundation.URL( validatingOpenAPIServerURL: "/rest", variables: [] @@ -524,25 +524,25 @@ enum Servers { } /// Types generated from the components section of the OpenAPI document. -enum Components { +public enum Components { /// Types generated from the `#/components/schemas` section of the OpenAPI document. - enum Schemas { + public enum Schemas { /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO`. - struct ConfigDescriptionParameterDTO: Codable, Hashable, Sendable { + public struct ConfigDescriptionParameterDTO: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/context`. - var context: Swift.String? + public var context: Swift.String? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/defaultValue`. - var defaultValue: Swift.String? + public var defaultValue: Swift.String? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/description`. - var description: Swift.String? + public var description: Swift.String? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/label`. - var label: Swift.String? + public var label: Swift.String? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/name`. - var name: Swift.String? + public var name: Swift.String? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/required`. - var required: Swift.Bool? + public var required: Swift.Bool? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/type`. - enum _typePayload: String, Codable, Hashable, Sendable, CaseIterable { + @frozen public enum _typePayload: String, Codable, Hashable, Sendable, CaseIterable { case TEXT case INTEGER case DECIMAL @@ -550,37 +550,37 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/type`. - var _type: Components.Schemas.ConfigDescriptionParameterDTO._typePayload? + public var _type: Components.Schemas.ConfigDescriptionParameterDTO._typePayload? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/min`. - var min: Swift.Double? + public var min: Swift.Double? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/max`. - var max: Swift.Double? + public var max: Swift.Double? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/stepsize`. - var stepsize: Swift.Double? + public var stepsize: Swift.Double? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/pattern`. - var pattern: Swift.String? + public var pattern: Swift.String? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/readOnly`. - var readOnly: Swift.Bool? + public var readOnly: Swift.Bool? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/multiple`. - var multiple: Swift.Bool? + public var multiple: Swift.Bool? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/multipleLimit`. - var multipleLimit: Swift.Int32? + public var multipleLimit: Swift.Int32? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/groupName`. - var groupName: Swift.String? + public var groupName: Swift.String? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/advanced`. - var advanced: Swift.Bool? + public var advanced: Swift.Bool? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/verify`. - var verify: Swift.Bool? + public var verify: Swift.Bool? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/limitToOptions`. - var limitToOptions: Swift.Bool? + public var limitToOptions: Swift.Bool? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/unit`. - var unit: Swift.String? + public var unit: Swift.String? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/unitLabel`. - var unitLabel: Swift.String? + public var unitLabel: Swift.String? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/options`. - var options: [Components.Schemas.ParameterOptionDTO]? + public var options: [Components.Schemas.ParameterOptionDTO]? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterDTO/filterCriteria`. - var filterCriteria: [Components.Schemas.FilterCriteriaDTO]? + public var filterCriteria: [Components.Schemas.FilterCriteriaDTO]? /// Creates a new `ConfigDescriptionParameterDTO`. /// /// - Parameters: @@ -606,28 +606,28 @@ enum Components { /// - unitLabel: /// - options: /// - filterCriteria: - init(context: Swift.String? = nil, - defaultValue: Swift.String? = nil, - description: Swift.String? = nil, - label: Swift.String? = nil, - name: Swift.String? = nil, - required: Swift.Bool? = nil, - _type: Components.Schemas.ConfigDescriptionParameterDTO._typePayload? = nil, - min: Swift.Double? = nil, - max: Swift.Double? = nil, - stepsize: Swift.Double? = nil, - pattern: Swift.String? = nil, - readOnly: Swift.Bool? = nil, - multiple: Swift.Bool? = nil, - multipleLimit: Swift.Int32? = nil, - groupName: Swift.String? = nil, - advanced: Swift.Bool? = nil, - verify: Swift.Bool? = nil, - limitToOptions: Swift.Bool? = nil, - unit: Swift.String? = nil, - unitLabel: Swift.String? = nil, - options: [Components.Schemas.ParameterOptionDTO]? = nil, - filterCriteria: [Components.Schemas.FilterCriteriaDTO]? = nil) { + public init(context: Swift.String? = nil, + defaultValue: Swift.String? = nil, + description: Swift.String? = nil, + label: Swift.String? = nil, + name: Swift.String? = nil, + required: Swift.Bool? = nil, + _type: Components.Schemas.ConfigDescriptionParameterDTO._typePayload? = nil, + min: Swift.Double? = nil, + max: Swift.Double? = nil, + stepsize: Swift.Double? = nil, + pattern: Swift.String? = nil, + readOnly: Swift.Bool? = nil, + multiple: Swift.Bool? = nil, + multipleLimit: Swift.Int32? = nil, + groupName: Swift.String? = nil, + advanced: Swift.Bool? = nil, + verify: Swift.Bool? = nil, + limitToOptions: Swift.Bool? = nil, + unit: Swift.String? = nil, + unitLabel: Swift.String? = nil, + options: [Components.Schemas.ParameterOptionDTO]? = nil, + filterCriteria: [Components.Schemas.FilterCriteriaDTO]? = nil) { self.context = context self.defaultValue = defaultValue self.description = description @@ -652,7 +652,7 @@ enum Components { self.filterCriteria = filterCriteria } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case context case defaultValue case description @@ -679,103 +679,103 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/FilterCriteriaDTO`. - struct FilterCriteriaDTO: Codable, Hashable, Sendable { + public struct FilterCriteriaDTO: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/FilterCriteriaDTO/value`. - var value: Swift.String? + public var value: Swift.String? /// - Remark: Generated from `#/components/schemas/FilterCriteriaDTO/name`. - var name: Swift.String? + public var name: Swift.String? /// Creates a new `FilterCriteriaDTO`. /// /// - Parameters: /// - value: /// - name: - init(value: Swift.String? = nil, - name: Swift.String? = nil) { + public init(value: Swift.String? = nil, + name: Swift.String? = nil) { self.value = value self.name = name } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case value case name } } /// - Remark: Generated from `#/components/schemas/ParameterOptionDTO`. - struct ParameterOptionDTO: Codable, Hashable, Sendable { + public struct ParameterOptionDTO: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/ParameterOptionDTO/label`. - var label: Swift.String? + public var label: Swift.String? /// - Remark: Generated from `#/components/schemas/ParameterOptionDTO/value`. - var value: Swift.String? + public var value: Swift.String? /// Creates a new `ParameterOptionDTO`. /// /// - Parameters: /// - label: /// - value: - init(label: Swift.String? = nil, - value: Swift.String? = nil) { + public init(label: Swift.String? = nil, + value: Swift.String? = nil) { self.label = label self.value = value } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case label case value } } /// - Remark: Generated from `#/components/schemas/CommandDescription`. - struct CommandDescription: Codable, Hashable, Sendable { + public struct CommandDescription: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/CommandDescription/commandOptions`. - var commandOptions: [Components.Schemas.CommandOption]? + public var commandOptions: [Components.Schemas.CommandOption]? /// Creates a new `CommandDescription`. /// /// - Parameters: /// - commandOptions: - init(commandOptions: [Components.Schemas.CommandOption]? = nil) { + public init(commandOptions: [Components.Schemas.CommandOption]? = nil) { self.commandOptions = commandOptions } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case commandOptions } } /// - Remark: Generated from `#/components/schemas/CommandOption`. - struct CommandOption: Codable, Hashable, Sendable { + public struct CommandOption: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/CommandOption/command`. - var command: Swift.String? + public var command: Swift.String? /// - Remark: Generated from `#/components/schemas/CommandOption/label`. - var label: Swift.String? + public var label: Swift.String? /// Creates a new `CommandOption`. /// /// - Parameters: /// - command: /// - label: - init(command: Swift.String? = nil, - label: Swift.String? = nil) { + public init(command: Swift.String? = nil, + label: Swift.String? = nil) { self.command = command self.label = label } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case command case label } } /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterGroupDTO`. - struct ConfigDescriptionParameterGroupDTO: Codable, Hashable, Sendable { + public struct ConfigDescriptionParameterGroupDTO: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterGroupDTO/name`. - var name: Swift.String? + public var name: Swift.String? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterGroupDTO/context`. - var context: Swift.String? + public var context: Swift.String? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterGroupDTO/advanced`. - var advanced: Swift.Bool? + public var advanced: Swift.Bool? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterGroupDTO/label`. - var label: Swift.String? + public var label: Swift.String? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionParameterGroupDTO/description`. - var description: Swift.String? + public var description: Swift.String? /// Creates a new `ConfigDescriptionParameterGroupDTO`. /// /// - Parameters: @@ -784,11 +784,11 @@ enum Components { /// - advanced: /// - label: /// - description: - init(name: Swift.String? = nil, - context: Swift.String? = nil, - advanced: Swift.Bool? = nil, - label: Swift.String? = nil, - description: Swift.String? = nil) { + public init(name: Swift.String? = nil, + context: Swift.String? = nil, + advanced: Swift.Bool? = nil, + label: Swift.String? = nil, + description: Swift.String? = nil) { self.name = name self.context = context self.advanced = advanced @@ -796,7 +796,7 @@ enum Components { self.description = description } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case name case context case advanced @@ -806,19 +806,19 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/StateDescription`. - struct StateDescription: Codable, Hashable, Sendable { + public struct StateDescription: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/StateDescription/minimum`. - var minimum: Swift.Double? + public var minimum: Swift.Double? /// - Remark: Generated from `#/components/schemas/StateDescription/maximum`. - var maximum: Swift.Double? + public var maximum: Swift.Double? /// - Remark: Generated from `#/components/schemas/StateDescription/step`. - var step: Swift.Double? + public var step: Swift.Double? /// - Remark: Generated from `#/components/schemas/StateDescription/pattern`. - var pattern: Swift.String? + public var pattern: Swift.String? /// - Remark: Generated from `#/components/schemas/StateDescription/readOnly`. - var readOnly: Swift.Bool? + public var readOnly: Swift.Bool? /// - Remark: Generated from `#/components/schemas/StateDescription/options`. - var options: [Components.Schemas.StateOption]? + public var options: [Components.Schemas.StateOption]? /// Creates a new `StateDescription`. /// /// - Parameters: @@ -828,12 +828,12 @@ enum Components { /// - pattern: /// - readOnly: /// - options: - init(minimum: Swift.Double? = nil, - maximum: Swift.Double? = nil, - step: Swift.Double? = nil, - pattern: Swift.String? = nil, - readOnly: Swift.Bool? = nil, - options: [Components.Schemas.StateOption]? = nil) { + public init(minimum: Swift.Double? = nil, + maximum: Swift.Double? = nil, + step: Swift.Double? = nil, + pattern: Swift.String? = nil, + readOnly: Swift.Bool? = nil, + options: [Components.Schemas.StateOption]? = nil) { self.minimum = minimum self.maximum = maximum self.step = step @@ -842,7 +842,7 @@ enum Components { self.options = options } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case minimum case maximum case step @@ -853,51 +853,51 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/StateOption`. - struct StateOption: Codable, Hashable, Sendable { + public struct StateOption: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/StateOption/value`. - var value: Swift.String? + public var value: Swift.String? /// - Remark: Generated from `#/components/schemas/StateOption/label`. - var label: Swift.String? + public var label: Swift.String? /// Creates a new `StateOption`. /// /// - Parameters: /// - value: /// - label: - init(value: Swift.String? = nil, - label: Swift.String? = nil) { + public init(value: Swift.String? = nil, + label: Swift.String? = nil) { self.value = value self.label = label } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case value case label } } /// - Remark: Generated from `#/components/schemas/ConfigDescriptionDTO`. - struct ConfigDescriptionDTO: Codable, Hashable, Sendable { + public struct ConfigDescriptionDTO: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/ConfigDescriptionDTO/uri`. - var uri: Swift.String? + public var uri: Swift.String? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionDTO/parameters`. - var parameters: [Components.Schemas.ConfigDescriptionParameterDTO]? + public var parameters: [Components.Schemas.ConfigDescriptionParameterDTO]? /// - Remark: Generated from `#/components/schemas/ConfigDescriptionDTO/parameterGroups`. - var parameterGroups: [Components.Schemas.ConfigDescriptionParameterGroupDTO]? + public var parameterGroups: [Components.Schemas.ConfigDescriptionParameterGroupDTO]? /// Creates a new `ConfigDescriptionDTO`. /// /// - Parameters: /// - uri: /// - parameters: /// - parameterGroups: - init(uri: Swift.String? = nil, - parameters: [Components.Schemas.ConfigDescriptionParameterDTO]? = nil, - parameterGroups: [Components.Schemas.ConfigDescriptionParameterGroupDTO]? = nil) { + public init(uri: Swift.String? = nil, + parameters: [Components.Schemas.ConfigDescriptionParameterDTO]? = nil, + parameterGroups: [Components.Schemas.ConfigDescriptionParameterGroupDTO]? = nil) { self.uri = uri self.parameters = parameters self.parameterGroups = parameterGroups } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case uri case parameters case parameterGroups @@ -905,100 +905,100 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/MetadataDTO`. - struct MetadataDTO: Codable, Hashable, Sendable { + public struct MetadataDTO: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/MetadataDTO/value`. - var value: Swift.String? + public var value: Swift.String? /// - Remark: Generated from `#/components/schemas/MetadataDTO/config`. - struct configPayload: Codable, Hashable, Sendable { + public struct configPayload: Codable, Hashable, Sendable { /// A container of undocumented properties. - var additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] + public var additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] /// Creates a new `configPayload`. /// /// - Parameters: /// - additionalProperties: A container of undocumented properties. - init(additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] = .init()) { + public init(additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] = .init()) { self.additionalProperties = additionalProperties } - init(from decoder: any Decoder) throws { + public init(from decoder: any Decoder) throws { additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) } - func encode(to encoder: any Encoder) throws { + public func encode(to encoder: any Encoder) throws { try encoder.encodeAdditionalProperties(additionalProperties) } } /// - Remark: Generated from `#/components/schemas/MetadataDTO/config`. - var config: Components.Schemas.MetadataDTO.configPayload? + public var config: Components.Schemas.MetadataDTO.configPayload? /// Creates a new `MetadataDTO`. /// /// - Parameters: /// - value: /// - config: - init(value: Swift.String? = nil, - config: Components.Schemas.MetadataDTO.configPayload? = nil) { + public init(value: Swift.String? = nil, + config: Components.Schemas.MetadataDTO.configPayload? = nil) { self.value = value self.config = config } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case value case config } } /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO`. - struct EnrichedItemDTO: Codable, Hashable, Sendable { + public struct EnrichedItemDTO: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/type`. - var _type: Swift.String? + public var _type: Swift.String? /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/name`. - var name: Swift.String? + public var name: Swift.String? /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/label`. - var label: Swift.String? + public var label: Swift.String? /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/category`. - var category: Swift.String? + public var category: Swift.String? /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/tags`. - var tags: [Swift.String]? + public var tags: [Swift.String]? /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/groupNames`. - var groupNames: [Swift.String]? + public var groupNames: [Swift.String]? /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/link`. - var link: Swift.String? + public var link: Swift.String? /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/state`. - var state: Swift.String? + public var state: Swift.String? /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/transformedState`. - var transformedState: Swift.String? + public var transformedState: Swift.String? /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/stateDescription`. - var stateDescription: Components.Schemas.StateDescription? + public var stateDescription: Components.Schemas.StateDescription? /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/unitSymbol`. - var unitSymbol: Swift.String? + public var unitSymbol: Swift.String? /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/commandDescription`. - var commandDescription: Components.Schemas.CommandDescription? + public var commandDescription: Components.Schemas.CommandDescription? /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/metadata`. - struct metadataPayload: Codable, Hashable, Sendable { + public struct metadataPayload: Codable, Hashable, Sendable { /// A container of undocumented properties. - var additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] + public var additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] /// Creates a new `metadataPayload`. /// /// - Parameters: /// - additionalProperties: A container of undocumented properties. - init(additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] = .init()) { + public init(additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] = .init()) { self.additionalProperties = additionalProperties } - init(from decoder: any Decoder) throws { + public init(from decoder: any Decoder) throws { additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) } - func encode(to encoder: any Encoder) throws { + public func encode(to encoder: any Encoder) throws { try encoder.encodeAdditionalProperties(additionalProperties) } } /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/metadata`. - var metadata: Components.Schemas.EnrichedItemDTO.metadataPayload? + public var metadata: Components.Schemas.EnrichedItemDTO.metadataPayload? /// - Remark: Generated from `#/components/schemas/EnrichedItemDTO/editable`. - var editable: Swift.Bool? + public var editable: Swift.Bool? /// Creates a new `EnrichedItemDTO`. /// /// - Parameters: @@ -1016,20 +1016,20 @@ enum Components { /// - commandDescription: /// - metadata: /// - editable: - init(_type: Swift.String? = nil, - name: Swift.String? = nil, - label: Swift.String? = nil, - category: Swift.String? = nil, - tags: [Swift.String]? = nil, - groupNames: [Swift.String]? = nil, - link: Swift.String? = nil, - state: Swift.String? = nil, - transformedState: Swift.String? = nil, - stateDescription: Components.Schemas.StateDescription? = nil, - unitSymbol: Swift.String? = nil, - commandDescription: Components.Schemas.CommandDescription? = nil, - metadata: Components.Schemas.EnrichedItemDTO.metadataPayload? = nil, - editable: Swift.Bool? = nil) { + public init(_type: Swift.String? = nil, + name: Swift.String? = nil, + label: Swift.String? = nil, + category: Swift.String? = nil, + tags: [Swift.String]? = nil, + groupNames: [Swift.String]? = nil, + link: Swift.String? = nil, + state: Swift.String? = nil, + transformedState: Swift.String? = nil, + stateDescription: Components.Schemas.StateDescription? = nil, + unitSymbol: Swift.String? = nil, + commandDescription: Components.Schemas.CommandDescription? = nil, + metadata: Components.Schemas.EnrichedItemDTO.metadataPayload? = nil, + editable: Swift.Bool? = nil) { self._type = _type self.name = name self.label = label @@ -1046,7 +1046,7 @@ enum Components { self.editable = editable } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case _type = "type" case name case label @@ -1065,46 +1065,46 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/GroupFunctionDTO`. - struct GroupFunctionDTO: Codable, Hashable, Sendable { + public struct GroupFunctionDTO: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/GroupFunctionDTO/name`. - var name: Swift.String? + public var name: Swift.String? /// - Remark: Generated from `#/components/schemas/GroupFunctionDTO/params`. - var params: [Swift.String]? + public var params: [Swift.String]? /// Creates a new `GroupFunctionDTO`. /// /// - Parameters: /// - name: /// - params: - init(name: Swift.String? = nil, - params: [Swift.String]? = nil) { + public init(name: Swift.String? = nil, + params: [Swift.String]? = nil) { self.name = name self.params = params } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case name case params } } /// - Remark: Generated from `#/components/schemas/GroupItemDTO`. - struct GroupItemDTO: Codable, Hashable, Sendable { + public struct GroupItemDTO: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/GroupItemDTO/type`. - var _type: Swift.String? + public var _type: Swift.String? /// - Remark: Generated from `#/components/schemas/GroupItemDTO/name`. - var name: Swift.String? + public var name: Swift.String? /// - Remark: Generated from `#/components/schemas/GroupItemDTO/label`. - var label: Swift.String? + public var label: Swift.String? /// - Remark: Generated from `#/components/schemas/GroupItemDTO/category`. - var category: Swift.String? + public var category: Swift.String? /// - Remark: Generated from `#/components/schemas/GroupItemDTO/tags`. - var tags: [Swift.String]? + public var tags: [Swift.String]? /// - Remark: Generated from `#/components/schemas/GroupItemDTO/groupNames`. - var groupNames: [Swift.String]? + public var groupNames: [Swift.String]? /// - Remark: Generated from `#/components/schemas/GroupItemDTO/groupType`. - var groupType: Swift.String? + public var groupType: Swift.String? /// - Remark: Generated from `#/components/schemas/GroupItemDTO/function`. - var function: Components.Schemas.GroupFunctionDTO? + public var function: Components.Schemas.GroupFunctionDTO? /// Creates a new `GroupItemDTO`. /// /// - Parameters: @@ -1116,14 +1116,14 @@ enum Components { /// - groupNames: /// - groupType: /// - function: - init(_type: Swift.String? = nil, - name: Swift.String? = nil, - label: Swift.String? = nil, - category: Swift.String? = nil, - tags: [Swift.String]? = nil, - groupNames: [Swift.String]? = nil, - groupType: Swift.String? = nil, - function: Components.Schemas.GroupFunctionDTO? = nil) { + public init(_type: Swift.String? = nil, + name: Swift.String? = nil, + label: Swift.String? = nil, + category: Swift.String? = nil, + tags: [Swift.String]? = nil, + groupNames: [Swift.String]? = nil, + groupType: Swift.String? = nil, + function: Components.Schemas.GroupFunctionDTO? = nil) { self._type = _type self.name = name self.label = label @@ -1134,7 +1134,7 @@ enum Components { self.function = function } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case _type = "type" case name case label @@ -1147,76 +1147,76 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/JerseyResponseBuilderDTO`. - struct JerseyResponseBuilderDTO: Codable, Hashable, Sendable { + public struct JerseyResponseBuilderDTO: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/JerseyResponseBuilderDTO/status`. - var status: Swift.String? + public var status: Swift.String? /// - Remark: Generated from `#/components/schemas/JerseyResponseBuilderDTO/context`. - var context: Components.Schemas.ContextDTO? + public var context: Components.Schemas.ContextDTO? /// Creates a new `JerseyResponseBuilderDTO`. /// /// - Parameters: /// - status: /// - context: - init(status: Swift.String? = nil, - context: Components.Schemas.ContextDTO? = nil) { + public init(status: Swift.String? = nil, + context: Components.Schemas.ContextDTO? = nil) { self.status = status self.context = context } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case status case context } } /// - Remark: Generated from `#/components/schemas/ContextDTO`. - struct ContextDTO: Codable, Hashable, Sendable { + public struct ContextDTO: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/ContextDTO/headers`. - var headers: Components.Schemas.HeadersDTO? + public var headers: Components.Schemas.HeadersDTO? /// Creates a new `ContextDTO`. /// /// - Parameters: /// - headers: - init(headers: Components.Schemas.HeadersDTO? = nil) { + public init(headers: Components.Schemas.HeadersDTO? = nil) { self.headers = headers } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case headers } } /// - Remark: Generated from `#/components/schemas/HeadersDTO`. - struct HeadersDTO: Codable, Hashable, Sendable { + public struct HeadersDTO: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/HeadersDTO/Location`. - var Location: [Swift.String]? + public var Location: [Swift.String]? /// Creates a new `HeadersDTO`. /// /// - Parameters: /// - Location: - init(Location: [Swift.String]? = nil) { + public init(Location: [Swift.String]? = nil) { self.Location = Location } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case Location } } /// - Remark: Generated from `#/components/schemas/MappingDTO`. - struct MappingDTO: Codable, Hashable, Sendable { + public struct MappingDTO: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/MappingDTO/row`. - var row: Swift.Int32? + public var row: Swift.Int32? /// - Remark: Generated from `#/components/schemas/MappingDTO/column`. - var column: Swift.Int32? + public var column: Swift.Int32? /// - Remark: Generated from `#/components/schemas/MappingDTO/command`. - var command: Swift.String? + public var command: Swift.String? /// - Remark: Generated from `#/components/schemas/MappingDTO/releaseCommand`. - var releaseCommand: Swift.String? + public var releaseCommand: Swift.String? /// - Remark: Generated from `#/components/schemas/MappingDTO/label`. - var label: Swift.String? + public var label: Swift.String? /// - Remark: Generated from `#/components/schemas/MappingDTO/icon`. - var icon: Swift.String? + public var icon: Swift.String? /// Creates a new `MappingDTO`. /// /// - Parameters: @@ -1226,12 +1226,12 @@ enum Components { /// - releaseCommand: /// - label: /// - icon: - init(row: Swift.Int32? = nil, - column: Swift.Int32? = nil, - command: Swift.String? = nil, - releaseCommand: Swift.String? = nil, - label: Swift.String? = nil, - icon: Swift.String? = nil) { + public init(row: Swift.Int32? = nil, + column: Swift.Int32? = nil, + command: Swift.String? = nil, + releaseCommand: Swift.String? = nil, + label: Swift.String? = nil, + icon: Swift.String? = nil) { self.row = row self.column = column self.command = command @@ -1240,7 +1240,7 @@ enum Components { self.icon = icon } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case row case column case command @@ -1251,9 +1251,9 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/PageDTO`. - struct PageDTO: Codable, Hashable, Sendable { + public struct PageDTO: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/PageDTO/id`. - var id: Swift.String? { + public var id: Swift.String? { get { storage.value.id } @@ -1263,7 +1263,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/PageDTO/title`. - var title: Swift.String? { + public var title: Swift.String? { get { storage.value.title } @@ -1273,7 +1273,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/PageDTO/icon`. - var icon: Swift.String? { + public var icon: Swift.String? { get { storage.value.icon } @@ -1283,7 +1283,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/PageDTO/link`. - var link: Swift.String? { + public var link: Swift.String? { get { storage.value.link } @@ -1293,7 +1293,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/PageDTO/parent`. - var parent: Components.Schemas.PageDTO? { + public var parent: Components.Schemas.PageDTO? { get { storage.value.parent } @@ -1303,7 +1303,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/PageDTO/leaf`. - var leaf: Swift.Bool? { + public var leaf: Swift.Bool? { get { storage.value.leaf } @@ -1313,7 +1313,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/PageDTO/timeout`. - var timeout: Swift.Bool? { + public var timeout: Swift.Bool? { get { storage.value.timeout } @@ -1323,7 +1323,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/PageDTO/widgets`. - var widgets: [Components.Schemas.WidgetDTO]? { + public var widgets: [Components.Schemas.WidgetDTO]? { get { storage.value.widgets } @@ -1343,14 +1343,14 @@ enum Components { /// - leaf: /// - timeout: /// - widgets: - init(id: Swift.String? = nil, - title: Swift.String? = nil, - icon: Swift.String? = nil, - link: Swift.String? = nil, - parent: Components.Schemas.PageDTO? = nil, - leaf: Swift.Bool? = nil, - timeout: Swift.Bool? = nil, - widgets: [Components.Schemas.WidgetDTO]? = nil) { + public init(id: Swift.String? = nil, + title: Swift.String? = nil, + icon: Swift.String? = nil, + link: Swift.String? = nil, + parent: Components.Schemas.PageDTO? = nil, + leaf: Swift.Bool? = nil, + timeout: Swift.Bool? = nil, + widgets: [Components.Schemas.WidgetDTO]? = nil) { storage = .init(value: .init( id: id, title: title, @@ -1363,7 +1363,7 @@ enum Components { )) } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case id case title case icon @@ -1374,11 +1374,11 @@ enum Components { case widgets } - init(from decoder: any Decoder) throws { + public init(from decoder: any Decoder) throws { storage = try .init(from: decoder) } - func encode(to encoder: any Encoder) throws { + public func encode(to encoder: any Encoder) throws { try storage.encode(to: encoder) } @@ -1424,9 +1424,9 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO`. - struct WidgetDTO: Codable, Hashable, Sendable { + public struct WidgetDTO: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/WidgetDTO/widgetId`. - var widgetId: Swift.String? { + public var widgetId: Swift.String? { get { storage.value.widgetId } @@ -1436,7 +1436,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/type`. - var _type: Swift.String? { + public var _type: Swift.String? { get { storage.value._type } @@ -1446,7 +1446,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/name`. - var name: Swift.String? { + public var name: Swift.String? { get { storage.value.name } @@ -1456,7 +1456,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/visibility`. - var visibility: Swift.Bool? { + public var visibility: Swift.Bool? { get { storage.value.visibility } @@ -1466,7 +1466,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/label`. - var label: Swift.String? { + public var label: Swift.String? { get { storage.value.label } @@ -1476,7 +1476,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/labelSource`. - var labelSource: Swift.String? { + public var labelSource: Swift.String? { get { storage.value.labelSource } @@ -1486,7 +1486,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/icon`. - var icon: Swift.String? { + public var icon: Swift.String? { get { storage.value.icon } @@ -1496,7 +1496,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/staticIcon`. - var staticIcon: Swift.Bool? { + public var staticIcon: Swift.Bool? { get { storage.value.staticIcon } @@ -1506,7 +1506,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/labelcolor`. - var labelcolor: Swift.String? { + public var labelcolor: Swift.String? { get { storage.value.labelcolor } @@ -1516,7 +1516,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/valuecolor`. - var valuecolor: Swift.String? { + public var valuecolor: Swift.String? { get { storage.value.valuecolor } @@ -1526,7 +1526,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/iconcolor`. - var iconcolor: Swift.String? { + public var iconcolor: Swift.String? { get { storage.value.iconcolor } @@ -1536,7 +1536,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/pattern`. - var pattern: Swift.String? { + public var pattern: Swift.String? { get { storage.value.pattern } @@ -1546,7 +1546,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/unit`. - var unit: Swift.String? { + public var unit: Swift.String? { get { storage.value.unit } @@ -1556,7 +1556,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/mappings`. - var mappings: [Components.Schemas.MappingDTO]? { + public var mappings: [Components.Schemas.MappingDTO]? { get { storage.value.mappings } @@ -1566,7 +1566,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/switchSupport`. - var switchSupport: Swift.Bool? { + public var switchSupport: Swift.Bool? { get { storage.value.switchSupport } @@ -1576,7 +1576,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/releaseOnly`. - var releaseOnly: Swift.Bool? { + public var releaseOnly: Swift.Bool? { get { storage.value.releaseOnly } @@ -1586,7 +1586,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/sendFrequency`. - var sendFrequency: Swift.Int32? { + public var sendFrequency: Swift.Int32? { get { storage.value.sendFrequency } @@ -1596,7 +1596,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/refresh`. - var refresh: Swift.Int32? { + public var refresh: Swift.Int32? { get { storage.value.refresh } @@ -1606,7 +1606,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/height`. - var height: Swift.Int32? { + public var height: Swift.Int32? { get { storage.value.height } @@ -1616,7 +1616,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/minValue`. - var minValue: Swift.Double? { + public var minValue: Swift.Double? { get { storage.value.minValue } @@ -1626,7 +1626,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/maxValue`. - var maxValue: Swift.Double? { + public var maxValue: Swift.Double? { get { storage.value.maxValue } @@ -1636,7 +1636,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/step`. - var step: Swift.Double? { + public var step: Swift.Double? { get { storage.value.step } @@ -1646,7 +1646,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/inputHint`. - var inputHint: Swift.String? { + public var inputHint: Swift.String? { get { storage.value.inputHint } @@ -1656,7 +1656,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/url`. - var url: Swift.String? { + public var url: Swift.String? { get { storage.value.url } @@ -1666,7 +1666,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/encoding`. - var encoding: Swift.String? { + public var encoding: Swift.String? { get { storage.value.encoding } @@ -1676,7 +1676,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/service`. - var service: Swift.String? { + public var service: Swift.String? { get { storage.value.service } @@ -1686,7 +1686,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/period`. - var period: Swift.String? { + public var period: Swift.String? { get { storage.value.period } @@ -1696,7 +1696,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/yAxisDecimalPattern`. - var yAxisDecimalPattern: Swift.String? { + public var yAxisDecimalPattern: Swift.String? { get { storage.value.yAxisDecimalPattern } @@ -1706,7 +1706,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/legend`. - var legend: Swift.Bool? { + public var legend: Swift.Bool? { get { storage.value.legend } @@ -1716,7 +1716,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/forceAsItem`. - var forceAsItem: Swift.Bool? { + public var forceAsItem: Swift.Bool? { get { storage.value.forceAsItem } @@ -1726,7 +1726,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/row`. - var row: Swift.Int32? { + public var row: Swift.Int32? { get { storage.value.row } @@ -1736,7 +1736,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/column`. - var column: Swift.Int32? { + public var column: Swift.Int32? { get { storage.value.column } @@ -1746,7 +1746,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/command`. - var command: Swift.String? { + public var command: Swift.String? { get { storage.value.command } @@ -1756,7 +1756,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/releaseCommand`. - var releaseCommand: Swift.String? { + public var releaseCommand: Swift.String? { get { storage.value.releaseCommand } @@ -1766,7 +1766,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/stateless`. - var stateless: Swift.Bool? { + public var stateless: Swift.Bool? { get { storage.value.stateless } @@ -1776,7 +1776,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/state`. - var state: Swift.String? { + public var state: Swift.String? { get { storage.value.state } @@ -1786,7 +1786,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/item`. - var item: Components.Schemas.EnrichedItemDTO? { + public var item: Components.Schemas.EnrichedItemDTO? { get { storage.value.item } @@ -1796,7 +1796,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/linkedPage`. - var linkedPage: Components.Schemas.PageDTO? { + public var linkedPage: Components.Schemas.PageDTO? { get { storage.value.linkedPage } @@ -1806,7 +1806,7 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/WidgetDTO/widgets`. - var widgets: [Components.Schemas.WidgetDTO]? { + public var widgets: [Components.Schemas.WidgetDTO]? { get { storage.value.widgets } @@ -1857,45 +1857,45 @@ enum Components { /// - item: /// - linkedPage: /// - widgets: - init(widgetId: Swift.String? = nil, - _type: Swift.String? = nil, - name: Swift.String? = nil, - visibility: Swift.Bool? = nil, - label: Swift.String? = nil, - labelSource: Swift.String? = nil, - icon: Swift.String? = nil, - staticIcon: Swift.Bool? = nil, - labelcolor: Swift.String? = nil, - valuecolor: Swift.String? = nil, - iconcolor: Swift.String? = nil, - pattern: Swift.String? = nil, - unit: Swift.String? = nil, - mappings: [Components.Schemas.MappingDTO]? = nil, - switchSupport: Swift.Bool? = nil, - releaseOnly: Swift.Bool? = nil, - sendFrequency: Swift.Int32? = nil, - refresh: Swift.Int32? = nil, - height: Swift.Int32? = nil, - minValue: Swift.Double? = nil, - maxValue: Swift.Double? = nil, - step: Swift.Double? = nil, - inputHint: Swift.String? = nil, - url: Swift.String? = nil, - encoding: Swift.String? = nil, - service: Swift.String? = nil, - period: Swift.String? = nil, - yAxisDecimalPattern: Swift.String? = nil, - legend: Swift.Bool? = nil, - forceAsItem: Swift.Bool? = nil, - row: Swift.Int32? = nil, - column: Swift.Int32? = nil, - command: Swift.String? = nil, - releaseCommand: Swift.String? = nil, - stateless: Swift.Bool? = nil, - state: Swift.String? = nil, - item: Components.Schemas.EnrichedItemDTO? = nil, - linkedPage: Components.Schemas.PageDTO? = nil, - widgets: [Components.Schemas.WidgetDTO]? = nil) { + public init(widgetId: Swift.String? = nil, + _type: Swift.String? = nil, + name: Swift.String? = nil, + visibility: Swift.Bool? = nil, + label: Swift.String? = nil, + labelSource: Swift.String? = nil, + icon: Swift.String? = nil, + staticIcon: Swift.Bool? = nil, + labelcolor: Swift.String? = nil, + valuecolor: Swift.String? = nil, + iconcolor: Swift.String? = nil, + pattern: Swift.String? = nil, + unit: Swift.String? = nil, + mappings: [Components.Schemas.MappingDTO]? = nil, + switchSupport: Swift.Bool? = nil, + releaseOnly: Swift.Bool? = nil, + sendFrequency: Swift.Int32? = nil, + refresh: Swift.Int32? = nil, + height: Swift.Int32? = nil, + minValue: Swift.Double? = nil, + maxValue: Swift.Double? = nil, + step: Swift.Double? = nil, + inputHint: Swift.String? = nil, + url: Swift.String? = nil, + encoding: Swift.String? = nil, + service: Swift.String? = nil, + period: Swift.String? = nil, + yAxisDecimalPattern: Swift.String? = nil, + legend: Swift.Bool? = nil, + forceAsItem: Swift.Bool? = nil, + row: Swift.Int32? = nil, + column: Swift.Int32? = nil, + command: Swift.String? = nil, + releaseCommand: Swift.String? = nil, + stateless: Swift.Bool? = nil, + state: Swift.String? = nil, + item: Components.Schemas.EnrichedItemDTO? = nil, + linkedPage: Components.Schemas.PageDTO? = nil, + widgets: [Components.Schemas.WidgetDTO]? = nil) { storage = .init(value: .init( widgetId: widgetId, _type: _type, @@ -1939,7 +1939,7 @@ enum Components { )) } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case widgetId case _type = "type" case name @@ -1981,11 +1981,11 @@ enum Components { case widgets } - init(from decoder: any Decoder) throws { + public init(from decoder: any Decoder) throws { storage = try .init(from: decoder) } - func encode(to encoder: any Encoder) throws { + public func encode(to encoder: any Encoder) throws { try storage.encode(to: encoder) } @@ -2155,35 +2155,35 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent`. - struct SitemapWidgetEvent: Codable, Hashable, Sendable { + public struct SitemapWidgetEvent: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/widgetId`. - var widgetId: Swift.String? + public var widgetId: Swift.String? /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/label`. - var label: Swift.String? + public var label: Swift.String? /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/labelSource`. - var labelSource: Swift.String? + public var labelSource: Swift.String? /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/icon`. - var icon: Swift.String? + public var icon: Swift.String? /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/labelcolor`. - var labelcolor: Swift.String? + public var labelcolor: Swift.String? /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/valuecolor`. - var valuecolor: Swift.String? + public var valuecolor: Swift.String? /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/iconcolor`. - var iconcolor: Swift.String? + public var iconcolor: Swift.String? /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/state`. - var state: Swift.String? + public var state: Swift.String? /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/reloadIcon`. - var reloadIcon: Swift.Bool? + public var reloadIcon: Swift.Bool? /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/visibility`. - var visibility: Swift.Bool? + public var visibility: Swift.Bool? /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/descriptionChanged`. - var descriptionChanged: Swift.Bool? + public var descriptionChanged: Swift.Bool? /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/item`. - var item: Components.Schemas.EnrichedItemDTO? + public var item: Components.Schemas.EnrichedItemDTO? /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/sitemapName`. - var sitemapName: Swift.String? + public var sitemapName: Swift.String? /// - Remark: Generated from `#/components/schemas/SitemapWidgetEvent/pageId`. - var pageId: Swift.String? + public var pageId: Swift.String? /// Creates a new `SitemapWidgetEvent`. /// /// - Parameters: @@ -2201,20 +2201,20 @@ enum Components { /// - item: /// - sitemapName: /// - pageId: - init(widgetId: Swift.String? = nil, - label: Swift.String? = nil, - labelSource: Swift.String? = nil, - icon: Swift.String? = nil, - labelcolor: Swift.String? = nil, - valuecolor: Swift.String? = nil, - iconcolor: Swift.String? = nil, - state: Swift.String? = nil, - reloadIcon: Swift.Bool? = nil, - visibility: Swift.Bool? = nil, - descriptionChanged: Swift.Bool? = nil, - item: Components.Schemas.EnrichedItemDTO? = nil, - sitemapName: Swift.String? = nil, - pageId: Swift.String? = nil) { + public init(widgetId: Swift.String? = nil, + label: Swift.String? = nil, + labelSource: Swift.String? = nil, + icon: Swift.String? = nil, + labelcolor: Swift.String? = nil, + valuecolor: Swift.String? = nil, + iconcolor: Swift.String? = nil, + state: Swift.String? = nil, + reloadIcon: Swift.Bool? = nil, + visibility: Swift.Bool? = nil, + descriptionChanged: Swift.Bool? = nil, + item: Components.Schemas.EnrichedItemDTO? = nil, + sitemapName: Swift.String? = nil, + pageId: Swift.String? = nil) { self.widgetId = widgetId self.label = label self.labelSource = labelSource @@ -2231,7 +2231,7 @@ enum Components { self.pageId = pageId } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case widgetId case label case labelSource @@ -2250,17 +2250,17 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/SitemapDTO`. - struct SitemapDTO: Codable, Hashable, Sendable { + public struct SitemapDTO: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/SitemapDTO/name`. - var name: Swift.String? + public var name: Swift.String? /// - Remark: Generated from `#/components/schemas/SitemapDTO/icon`. - var icon: Swift.String? + public var icon: Swift.String? /// - Remark: Generated from `#/components/schemas/SitemapDTO/label`. - var label: Swift.String? + public var label: Swift.String? /// - Remark: Generated from `#/components/schemas/SitemapDTO/link`. - var link: Swift.String? + public var link: Swift.String? /// - Remark: Generated from `#/components/schemas/SitemapDTO/homepage`. - var homepage: Components.Schemas.PageDTO? + public var homepage: Components.Schemas.PageDTO? /// Creates a new `SitemapDTO`. /// /// - Parameters: @@ -2269,11 +2269,11 @@ enum Components { /// - label: /// - link: /// - homepage: - init(name: Swift.String? = nil, - icon: Swift.String? = nil, - label: Swift.String? = nil, - link: Swift.String? = nil, - homepage: Components.Schemas.PageDTO? = nil) { + public init(name: Swift.String? = nil, + icon: Swift.String? = nil, + label: Swift.String? = nil, + link: Swift.String? = nil, + homepage: Components.Schemas.PageDTO? = nil) { self.name = name self.icon = icon self.label = label @@ -2281,7 +2281,7 @@ enum Components { self.homepage = homepage } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case name case icon case label @@ -2291,65 +2291,65 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/RootUIComponent`. - struct RootUIComponent: Codable, Hashable, Sendable { + public struct RootUIComponent: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/RootUIComponent/component`. - var component: Swift.String? + public var component: Swift.String? /// - Remark: Generated from `#/components/schemas/RootUIComponent/config`. - struct configPayload: Codable, Hashable, Sendable { + public struct configPayload: Codable, Hashable, Sendable { /// A container of undocumented properties. - var additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] + public var additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] /// Creates a new `configPayload`. /// /// - Parameters: /// - additionalProperties: A container of undocumented properties. - init(additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] = .init()) { + public init(additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] = .init()) { self.additionalProperties = additionalProperties } - init(from decoder: any Decoder) throws { + public init(from decoder: any Decoder) throws { additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) } - func encode(to encoder: any Encoder) throws { + public func encode(to encoder: any Encoder) throws { try encoder.encodeAdditionalProperties(additionalProperties) } } /// - Remark: Generated from `#/components/schemas/RootUIComponent/config`. - var config: Components.Schemas.RootUIComponent.configPayload? + public var config: Components.Schemas.RootUIComponent.configPayload? /// - Remark: Generated from `#/components/schemas/RootUIComponent/slots`. - struct slotsPayload: Codable, Hashable, Sendable { + public struct slotsPayload: Codable, Hashable, Sendable { /// A container of undocumented properties. - var additionalProperties: [String: [Components.Schemas.UIComponent]] + public var additionalProperties: [String: [Components.Schemas.UIComponent]] /// Creates a new `slotsPayload`. /// /// - Parameters: /// - additionalProperties: A container of undocumented properties. - init(additionalProperties: [String: [Components.Schemas.UIComponent]] = .init()) { + public init(additionalProperties: [String: [Components.Schemas.UIComponent]] = .init()) { self.additionalProperties = additionalProperties } - init(from decoder: any Decoder) throws { + public init(from decoder: any Decoder) throws { additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) } - func encode(to encoder: any Encoder) throws { + public func encode(to encoder: any Encoder) throws { try encoder.encodeAdditionalProperties(additionalProperties) } } /// - Remark: Generated from `#/components/schemas/RootUIComponent/slots`. - var slots: Components.Schemas.RootUIComponent.slotsPayload? + public var slots: Components.Schemas.RootUIComponent.slotsPayload? /// - Remark: Generated from `#/components/schemas/RootUIComponent/uid`. - var uid: Swift.String? + public var uid: Swift.String? /// - Remark: Generated from `#/components/schemas/RootUIComponent/tags`. - var tags: [Swift.String]? + public var tags: [Swift.String]? /// - Remark: Generated from `#/components/schemas/RootUIComponent/props`. - var props: Components.Schemas.ConfigDescriptionDTO? + public var props: Components.Schemas.ConfigDescriptionDTO? /// - Remark: Generated from `#/components/schemas/RootUIComponent/timestamp`. - var timestamp: Foundation.Date? + public var timestamp: Foundation.Date? /// - Remark: Generated from `#/components/schemas/RootUIComponent/type`. - var _type: Swift.String? + public var _type: Swift.String? /// Creates a new `RootUIComponent`. /// /// - Parameters: @@ -2361,14 +2361,14 @@ enum Components { /// - props: /// - timestamp: /// - _type: - init(component: Swift.String? = nil, - config: Components.Schemas.RootUIComponent.configPayload? = nil, - slots: Components.Schemas.RootUIComponent.slotsPayload? = nil, - uid: Swift.String? = nil, - tags: [Swift.String]? = nil, - props: Components.Schemas.ConfigDescriptionDTO? = nil, - timestamp: Foundation.Date? = nil, - _type: Swift.String? = nil) { + public init(component: Swift.String? = nil, + config: Components.Schemas.RootUIComponent.configPayload? = nil, + slots: Components.Schemas.RootUIComponent.slotsPayload? = nil, + uid: Swift.String? = nil, + tags: [Swift.String]? = nil, + props: Components.Schemas.ConfigDescriptionDTO? = nil, + timestamp: Foundation.Date? = nil, + _type: Swift.String? = nil) { self.component = component self.config = config self.slots = slots @@ -2379,7 +2379,7 @@ enum Components { self._type = _type } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case component case config case slots @@ -2392,49 +2392,49 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/UIComponent`. - struct UIComponent: Codable, Hashable, Sendable { + public struct UIComponent: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/UIComponent/component`. - var component: Swift.String? + public var component: Swift.String? /// - Remark: Generated from `#/components/schemas/UIComponent/config`. - struct configPayload: Codable, Hashable, Sendable { + public struct configPayload: Codable, Hashable, Sendable { /// A container of undocumented properties. - var additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] + public var additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] /// Creates a new `configPayload`. /// /// - Parameters: /// - additionalProperties: A container of undocumented properties. - init(additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] = .init()) { + public init(additionalProperties: [String: OpenAPIRuntime.OpenAPIObjectContainer] = .init()) { self.additionalProperties = additionalProperties } - init(from decoder: any Decoder) throws { + public init(from decoder: any Decoder) throws { additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) } - func encode(to encoder: any Encoder) throws { + public func encode(to encoder: any Encoder) throws { try encoder.encodeAdditionalProperties(additionalProperties) } } /// - Remark: Generated from `#/components/schemas/UIComponent/config`. - var config: Components.Schemas.UIComponent.configPayload? + public var config: Components.Schemas.UIComponent.configPayload? /// - Remark: Generated from `#/components/schemas/UIComponent/type`. - var _type: Swift.String? + public var _type: Swift.String? /// Creates a new `UIComponent`. /// /// - Parameters: /// - component: /// - config: /// - _type: - init(component: Swift.String? = nil, - config: Components.Schemas.UIComponent.configPayload? = nil, - _type: Swift.String? = nil) { + public init(component: Swift.String? = nil, + config: Components.Schemas.UIComponent.configPayload? = nil, + _type: Swift.String? = nil) { self.component = component self.config = config self._type = _type } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case component case config case _type = "type" @@ -2442,15 +2442,15 @@ enum Components { } /// - Remark: Generated from `#/components/schemas/TileDTO`. - struct TileDTO: Codable, Hashable, Sendable { + public struct TileDTO: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/TileDTO/name`. - var name: Swift.String? + public var name: Swift.String? /// - Remark: Generated from `#/components/schemas/TileDTO/url`. - var url: Swift.String? + public var url: Swift.String? /// - Remark: Generated from `#/components/schemas/TileDTO/overlay`. - var overlay: Swift.String? + public var overlay: Swift.String? /// - Remark: Generated from `#/components/schemas/TileDTO/imageUrl`. - var imageUrl: Swift.String? + public var imageUrl: Swift.String? /// Creates a new `TileDTO`. /// /// - Parameters: @@ -2458,17 +2458,17 @@ enum Components { /// - url: /// - overlay: /// - imageUrl: - init(name: Swift.String? = nil, - url: Swift.String? = nil, - overlay: Swift.String? = nil, - imageUrl: Swift.String? = nil) { + public init(name: Swift.String? = nil, + url: Swift.String? = nil, + overlay: Swift.String? = nil, + imageUrl: Swift.String? = nil) { self.name = name self.url = url self.overlay = overlay self.imageUrl = imageUrl } - enum CodingKeys: String, CodingKey { + public enum CodingKeys: String, CodingKey { case name case url case overlay @@ -2478,60 +2478,60 @@ enum Components { } /// Types generated from the `#/components/parameters` section of the OpenAPI document. - enum Parameters {} + public enum Parameters {} /// Types generated from the `#/components/requestBodies` section of the OpenAPI document. - enum RequestBodies {} + public enum RequestBodies {} /// Types generated from the `#/components/responses` section of the OpenAPI document. - enum Responses {} + public enum Responses {} /// Types generated from the `#/components/headers` section of the OpenAPI document. - enum Headers {} + public enum Headers {} } /// API operations, with input and output types, generated from `#/paths` in the OpenAPI document. -enum Operations { +public enum Operations { /// Adds a new member to a group item. /// /// - Remark: HTTP `PUT /items/{itemName}/members/{memberItemName}`. /// - Remark: Generated from `#/paths//items/{itemName}/members/{memberItemName}/put(addMemberToGroupItem)`. - enum addMemberToGroupItem { - static let id: Swift.String = "addMemberToGroupItem" - struct Input: Sendable, Hashable { + public enum addMemberToGroupItem { + public static let id: Swift.String = "addMemberToGroupItem" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemName}/members/{memberItemName}/PUT/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// item name /// /// - Remark: Generated from `#/paths/items/{itemName}/members/{memberItemName}/PUT/path/itemName`. - var itemName: Swift.String + public var itemName: Swift.String /// member item name /// /// - Remark: Generated from `#/paths/items/{itemName}/members/{memberItemName}/PUT/path/memberItemName`. - var memberItemName: Swift.String + public var memberItemName: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - itemName: item name /// - memberItemName: member item name - init(itemName: Swift.String, - memberItemName: Swift.String) { + public init(itemName: Swift.String, + memberItemName: Swift.String) { self.itemName = itemName self.memberItemName = memberItemName } } - var path: Operations.addMemberToGroupItem.Input.Path + public var path: Operations.addMemberToGroupItem.Input.Path /// Creates a new `Input`. /// /// - Parameters: /// - path: - init(path: Operations.addMemberToGroupItem.Input.Path) { + public init(path: Operations.addMemberToGroupItem.Input.Path) { self.path = path } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// Creates a new `Ok`. - init() {} + public init() {} } /// OK @@ -2544,7 +2544,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.addMemberToGroupItem.Output.Ok { + public var ok: Operations.addMemberToGroupItem.Output.Ok { get throws { switch self { case let .ok(response): @@ -2558,9 +2558,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Item or member item not found or item is not of type group item. @@ -2573,7 +2573,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.addMemberToGroupItem.Output.NotFound { + public var notFound: Operations.addMemberToGroupItem.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -2587,9 +2587,9 @@ enum Operations { } } - struct MethodNotAllowed: Sendable, Hashable { + public struct MethodNotAllowed: Sendable, Hashable { /// Creates a new `MethodNotAllowed`. - init() {} + public init() {} } /// Member item is not editable. @@ -2602,7 +2602,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.methodNotAllowed`. /// - SeeAlso: `.methodNotAllowed`. - var methodNotAllowed: Operations.addMemberToGroupItem.Output.MethodNotAllowed { + public var methodNotAllowed: Operations.addMemberToGroupItem.Output.MethodNotAllowed { get throws { switch self { case let .methodNotAllowed(response): @@ -2627,45 +2627,45 @@ enum Operations { /// /// - Remark: HTTP `DELETE /items/{itemName}/members/{memberItemName}`. /// - Remark: Generated from `#/paths//items/{itemName}/members/{memberItemName}/delete(removeMemberFromGroupItem)`. - enum removeMemberFromGroupItem { - static let id: Swift.String = "removeMemberFromGroupItem" - struct Input: Sendable, Hashable { + public enum removeMemberFromGroupItem { + public static let id: Swift.String = "removeMemberFromGroupItem" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemName}/members/{memberItemName}/DELETE/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// item name /// /// - Remark: Generated from `#/paths/items/{itemName}/members/{memberItemName}/DELETE/path/itemName`. - var itemName: Swift.String + public var itemName: Swift.String /// member item name /// /// - Remark: Generated from `#/paths/items/{itemName}/members/{memberItemName}/DELETE/path/memberItemName`. - var memberItemName: Swift.String + public var memberItemName: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - itemName: item name /// - memberItemName: member item name - init(itemName: Swift.String, - memberItemName: Swift.String) { + public init(itemName: Swift.String, + memberItemName: Swift.String) { self.itemName = itemName self.memberItemName = memberItemName } } - var path: Operations.removeMemberFromGroupItem.Input.Path + public var path: Operations.removeMemberFromGroupItem.Input.Path /// Creates a new `Input`. /// /// - Parameters: /// - path: - init(path: Operations.removeMemberFromGroupItem.Input.Path) { + public init(path: Operations.removeMemberFromGroupItem.Input.Path) { self.path = path } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// Creates a new `Ok`. - init() {} + public init() {} } /// OK @@ -2678,7 +2678,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.removeMemberFromGroupItem.Output.Ok { + public var ok: Operations.removeMemberFromGroupItem.Output.Ok { get throws { switch self { case let .ok(response): @@ -2692,9 +2692,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Item or member item not found or item is not of type group item. @@ -2707,7 +2707,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.removeMemberFromGroupItem.Output.NotFound { + public var notFound: Operations.removeMemberFromGroupItem.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -2721,9 +2721,9 @@ enum Operations { } } - struct MethodNotAllowed: Sendable, Hashable { + public struct MethodNotAllowed: Sendable, Hashable { /// Creates a new `MethodNotAllowed`. - init() {} + public init() {} } /// Member item is not editable. @@ -2736,7 +2736,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.methodNotAllowed`. /// - SeeAlso: `.methodNotAllowed`. - var methodNotAllowed: Operations.removeMemberFromGroupItem.Output.MethodNotAllowed { + public var methodNotAllowed: Operations.removeMemberFromGroupItem.Output.MethodNotAllowed { get throws { switch self { case let .methodNotAllowed(response): @@ -2761,55 +2761,55 @@ enum Operations { /// /// - Remark: HTTP `PUT /items/{itemname}/metadata/{namespace}`. /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/put(addMetadataToItem)`. - enum addMetadataToItem { - static let id: Swift.String = "addMetadataToItem" - struct Input: Sendable, Hashable { + public enum addMetadataToItem { + public static let id: Swift.String = "addMetadataToItem" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/metadata/{namespace}/PUT/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// item name /// /// - Remark: Generated from `#/paths/items/{itemname}/metadata/{namespace}/PUT/path/itemname`. - var itemname: Swift.String + public var itemname: Swift.String /// namespace /// /// - Remark: Generated from `#/paths/items/{itemname}/metadata/{namespace}/PUT/path/namespace`. - var namespace: Swift.String + public var namespace: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - itemname: item name /// - namespace: namespace - init(itemname: Swift.String, - namespace: Swift.String) { + public init(itemname: Swift.String, + namespace: Swift.String) { self.itemname = itemname self.namespace = namespace } } - var path: Operations.addMetadataToItem.Input.Path + public var path: Operations.addMetadataToItem.Input.Path /// - Remark: Generated from `#/paths/items/{itemname}/metadata/{namespace}/PUT/requestBody`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/metadata/{namespace}/PUT/requestBody/content/application\/json`. case json(Components.Schemas.MetadataDTO) } - var body: Operations.addMetadataToItem.Input.Body + public var body: Operations.addMetadataToItem.Input.Body /// Creates a new `Input`. /// /// - Parameters: /// - path: /// - body: - init(path: Operations.addMetadataToItem.Input.Path, - body: Operations.addMetadataToItem.Input.Body) { + public init(path: Operations.addMetadataToItem.Input.Path, + body: Operations.addMetadataToItem.Input.Body) { self.path = path self.body = body } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// Creates a new `Ok`. - init() {} + public init() {} } /// OK @@ -2822,7 +2822,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.addMetadataToItem.Output.Ok { + public var ok: Operations.addMetadataToItem.Output.Ok { get throws { switch self { case let .ok(response): @@ -2836,9 +2836,9 @@ enum Operations { } } - struct Created: Sendable, Hashable { + public struct Created: Sendable, Hashable { /// Creates a new `Created`. - init() {} + public init() {} } /// Created @@ -2851,7 +2851,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.created`. /// - SeeAlso: `.created`. - var created: Operations.addMetadataToItem.Output.Created { + public var created: Operations.addMetadataToItem.Output.Created { get throws { switch self { case let .created(response): @@ -2865,9 +2865,9 @@ enum Operations { } } - struct BadRequest: Sendable, Hashable { + public struct BadRequest: Sendable, Hashable { /// Creates a new `BadRequest`. - init() {} + public init() {} } /// Metadata value empty. @@ -2880,7 +2880,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.badRequest`. /// - SeeAlso: `.badRequest`. - var badRequest: Operations.addMetadataToItem.Output.BadRequest { + public var badRequest: Operations.addMetadataToItem.Output.BadRequest { get throws { switch self { case let .badRequest(response): @@ -2894,9 +2894,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Item not found. @@ -2909,7 +2909,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.addMetadataToItem.Output.NotFound { + public var notFound: Operations.addMetadataToItem.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -2923,9 +2923,9 @@ enum Operations { } } - struct MethodNotAllowed: Sendable, Hashable { + public struct MethodNotAllowed: Sendable, Hashable { /// Creates a new `MethodNotAllowed`. - init() {} + public init() {} } /// Metadata not editable. @@ -2938,7 +2938,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.methodNotAllowed`. /// - SeeAlso: `.methodNotAllowed`. - var methodNotAllowed: Operations.addMetadataToItem.Output.MethodNotAllowed { + public var methodNotAllowed: Operations.addMetadataToItem.Output.MethodNotAllowed { get throws { switch self { case let .methodNotAllowed(response): @@ -2963,45 +2963,45 @@ enum Operations { /// /// - Remark: HTTP `DELETE /items/{itemname}/metadata/{namespace}`. /// - Remark: Generated from `#/paths//items/{itemname}/metadata/{namespace}/delete(removeMetadataFromItem)`. - enum removeMetadataFromItem { - static let id: Swift.String = "removeMetadataFromItem" - struct Input: Sendable, Hashable { + public enum removeMetadataFromItem { + public static let id: Swift.String = "removeMetadataFromItem" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/metadata/{namespace}/DELETE/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// item name /// /// - Remark: Generated from `#/paths/items/{itemname}/metadata/{namespace}/DELETE/path/itemname`. - var itemname: Swift.String + public var itemname: Swift.String /// namespace /// /// - Remark: Generated from `#/paths/items/{itemname}/metadata/{namespace}/DELETE/path/namespace`. - var namespace: Swift.String + public var namespace: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - itemname: item name /// - namespace: namespace - init(itemname: Swift.String, - namespace: Swift.String) { + public init(itemname: Swift.String, + namespace: Swift.String) { self.itemname = itemname self.namespace = namespace } } - var path: Operations.removeMetadataFromItem.Input.Path + public var path: Operations.removeMetadataFromItem.Input.Path /// Creates a new `Input`. /// /// - Parameters: /// - path: - init(path: Operations.removeMetadataFromItem.Input.Path) { + public init(path: Operations.removeMetadataFromItem.Input.Path) { self.path = path } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// Creates a new `Ok`. - init() {} + public init() {} } /// OK @@ -3014,7 +3014,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.removeMetadataFromItem.Output.Ok { + public var ok: Operations.removeMetadataFromItem.Output.Ok { get throws { switch self { case let .ok(response): @@ -3028,9 +3028,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Item not found. @@ -3043,7 +3043,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.removeMetadataFromItem.Output.NotFound { + public var notFound: Operations.removeMetadataFromItem.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -3057,9 +3057,9 @@ enum Operations { } } - struct MethodNotAllowed: Sendable, Hashable { + public struct MethodNotAllowed: Sendable, Hashable { /// Creates a new `MethodNotAllowed`. - init() {} + public init() {} } /// Meta data not editable. @@ -3072,7 +3072,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.methodNotAllowed`. /// - SeeAlso: `.methodNotAllowed`. - var methodNotAllowed: Operations.removeMetadataFromItem.Output.MethodNotAllowed { + public var methodNotAllowed: Operations.removeMetadataFromItem.Output.MethodNotAllowed { get throws { switch self { case let .methodNotAllowed(response): @@ -3097,45 +3097,45 @@ enum Operations { /// /// - Remark: HTTP `PUT /items/{itemname}/tags/{tag}`. /// - Remark: Generated from `#/paths//items/{itemname}/tags/{tag}/put(addTagToItem)`. - enum addTagToItem { - static let id: Swift.String = "addTagToItem" - struct Input: Sendable, Hashable { + public enum addTagToItem { + public static let id: Swift.String = "addTagToItem" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/tags/{tag}/PUT/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// item name /// /// - Remark: Generated from `#/paths/items/{itemname}/tags/{tag}/PUT/path/itemname`. - var itemname: Swift.String + public var itemname: Swift.String /// tag /// /// - Remark: Generated from `#/paths/items/{itemname}/tags/{tag}/PUT/path/tag`. - var tag: Swift.String + public var tag: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - itemname: item name /// - tag: tag - init(itemname: Swift.String, - tag: Swift.String) { + public init(itemname: Swift.String, + tag: Swift.String) { self.itemname = itemname self.tag = tag } } - var path: Operations.addTagToItem.Input.Path + public var path: Operations.addTagToItem.Input.Path /// Creates a new `Input`. /// /// - Parameters: /// - path: - init(path: Operations.addTagToItem.Input.Path) { + public init(path: Operations.addTagToItem.Input.Path) { self.path = path } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// Creates a new `Ok`. - init() {} + public init() {} } /// OK @@ -3148,7 +3148,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.addTagToItem.Output.Ok { + public var ok: Operations.addTagToItem.Output.Ok { get throws { switch self { case let .ok(response): @@ -3162,9 +3162,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Item not found. @@ -3177,7 +3177,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.addTagToItem.Output.NotFound { + public var notFound: Operations.addTagToItem.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -3191,9 +3191,9 @@ enum Operations { } } - struct MethodNotAllowed: Sendable, Hashable { + public struct MethodNotAllowed: Sendable, Hashable { /// Creates a new `MethodNotAllowed`. - init() {} + public init() {} } /// Item not editable. @@ -3206,7 +3206,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.methodNotAllowed`. /// - SeeAlso: `.methodNotAllowed`. - var methodNotAllowed: Operations.addTagToItem.Output.MethodNotAllowed { + public var methodNotAllowed: Operations.addTagToItem.Output.MethodNotAllowed { get throws { switch self { case let .methodNotAllowed(response): @@ -3231,45 +3231,45 @@ enum Operations { /// /// - Remark: HTTP `DELETE /items/{itemname}/tags/{tag}`. /// - Remark: Generated from `#/paths//items/{itemname}/tags/{tag}/delete(removeTagFromItem)`. - enum removeTagFromItem { - static let id: Swift.String = "removeTagFromItem" - struct Input: Sendable, Hashable { + public enum removeTagFromItem { + public static let id: Swift.String = "removeTagFromItem" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/tags/{tag}/DELETE/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// item name /// /// - Remark: Generated from `#/paths/items/{itemname}/tags/{tag}/DELETE/path/itemname`. - var itemname: Swift.String + public var itemname: Swift.String /// tag /// /// - Remark: Generated from `#/paths/items/{itemname}/tags/{tag}/DELETE/path/tag`. - var tag: Swift.String + public var tag: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - itemname: item name /// - tag: tag - init(itemname: Swift.String, - tag: Swift.String) { + public init(itemname: Swift.String, + tag: Swift.String) { self.itemname = itemname self.tag = tag } } - var path: Operations.removeTagFromItem.Input.Path + public var path: Operations.removeTagFromItem.Input.Path /// Creates a new `Input`. /// /// - Parameters: /// - path: - init(path: Operations.removeTagFromItem.Input.Path) { + public init(path: Operations.removeTagFromItem.Input.Path) { self.path = path } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// Creates a new `Ok`. - init() {} + public init() {} } /// OK @@ -3282,7 +3282,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.removeTagFromItem.Output.Ok { + public var ok: Operations.removeTagFromItem.Output.Ok { get throws { switch self { case let .ok(response): @@ -3296,9 +3296,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Item not found. @@ -3311,7 +3311,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.removeTagFromItem.Output.NotFound { + public var notFound: Operations.removeTagFromItem.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -3325,9 +3325,9 @@ enum Operations { } } - struct MethodNotAllowed: Sendable, Hashable { + public struct MethodNotAllowed: Sendable, Hashable { /// Creates a new `MethodNotAllowed`. - init() {} + public init() {} } /// Item not editable. @@ -3340,7 +3340,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.methodNotAllowed`. /// - SeeAlso: `.methodNotAllowed`. - var methodNotAllowed: Operations.removeTagFromItem.Output.MethodNotAllowed { + public var methodNotAllowed: Operations.removeTagFromItem.Output.MethodNotAllowed { get throws { switch self { case let .methodNotAllowed(response): @@ -3365,94 +3365,94 @@ enum Operations { /// /// - Remark: HTTP `GET /items/{itemname}`. /// - Remark: Generated from `#/paths//items/{itemname}/get(getItemByName)`. - enum getItemByName { - static let id: Swift.String = "getItemByName" - struct Input: Sendable, Hashable { + public enum getItemByName { + public static let id: Swift.String = "getItemByName" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/GET/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// item name /// /// - Remark: Generated from `#/paths/items/{itemname}/GET/path/itemname`. - var itemname: Swift.String + public var itemname: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - itemname: item name - init(itemname: Swift.String) { + public init(itemname: Swift.String) { self.itemname = itemname } } - var path: Operations.getItemByName.Input.Path + public var path: Operations.getItemByName.Input.Path /// - Remark: Generated from `#/paths/items/{itemname}/GET/query`. - struct Query: Sendable, Hashable { + public struct Query: Sendable, Hashable { /// metadata selector - a comma separated list or a regular expression (returns all if no value given) /// /// - Remark: Generated from `#/paths/items/{itemname}/GET/query/metadata`. - var metadata: Swift.String? + public var metadata: Swift.String? /// get member items if the item is a group item /// /// - Remark: Generated from `#/paths/items/{itemname}/GET/query/recursive`. - var recursive: Swift.Bool? + public var recursive: Swift.Bool? /// Creates a new `Query`. /// /// - Parameters: /// - metadata: metadata selector - a comma separated list or a regular expression (returns all if no value given) /// - recursive: get member items if the item is a group item - init(metadata: Swift.String? = nil, - recursive: Swift.Bool? = nil) { + public init(metadata: Swift.String? = nil, + recursive: Swift.Bool? = nil) { self.metadata = metadata self.recursive = recursive } } - var query: Operations.getItemByName.Input.Query + public var query: Operations.getItemByName.Input.Query /// - Remark: Generated from `#/paths/items/{itemname}/GET/header`. - struct Headers: Sendable, Hashable { + public struct Headers: Sendable, Hashable { /// language /// /// - Remark: Generated from `#/paths/items/{itemname}/GET/header/Accept-Language`. - var Accept_hyphen_Language: Swift.String? - var accept: [OpenAPIRuntime.AcceptHeaderContentType] + public var Accept_hyphen_Language: Swift.String? + public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: /// - Accept_hyphen_Language: language /// - accept: - init(Accept_hyphen_Language: Swift.String? = nil, - accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + public init(Accept_hyphen_Language: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { self.Accept_hyphen_Language = Accept_hyphen_Language self.accept = accept } } - var headers: Operations.getItemByName.Input.Headers + public var headers: Operations.getItemByName.Input.Headers /// Creates a new `Input`. /// /// - Parameters: /// - path: /// - query: /// - headers: - init(path: Operations.getItemByName.Input.Path, - query: Operations.getItemByName.Input.Query = .init(), - headers: Operations.getItemByName.Input.Headers = .init()) { + public init(path: Operations.getItemByName.Input.Path, + query: Operations.getItemByName.Input.Query = .init(), + headers: Operations.getItemByName.Input.Headers = .init()) { self.path = path self.query = query self.headers = headers } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/GET/responses/200/content`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/GET/responses/200/content/application\/json`. case json(Components.Schemas.EnrichedItemDTO) /// The associated value of the enum case if `self` is `.json`. /// /// - Throws: An error if `self` is not `.json`. /// - SeeAlso: `.json`. - var json: Components.Schemas.EnrichedItemDTO { + public var json: Components.Schemas.EnrichedItemDTO { get throws { switch self { case let .json(body): @@ -3463,12 +3463,12 @@ enum Operations { } /// Received HTTP response body - var body: Operations.getItemByName.Output.Ok.Body + public var body: Operations.getItemByName.Output.Ok.Body /// Creates a new `Ok`. /// /// - Parameters: /// - body: Received HTTP response body - init(body: Operations.getItemByName.Output.Ok.Body) { + public init(body: Operations.getItemByName.Output.Ok.Body) { self.body = body } } @@ -3483,7 +3483,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.getItemByName.Output.Ok { + public var ok: Operations.getItemByName.Output.Ok { get throws { switch self { case let .ok(response): @@ -3497,9 +3497,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Item not found @@ -3512,7 +3512,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.getItemByName.Output.NotFound { + public var notFound: Operations.getItemByName.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -3532,10 +3532,10 @@ enum Operations { case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) } - enum AcceptableContentType: AcceptableProtocol { + @frozen public enum AcceptableContentType: AcceptableProtocol { case json case other(Swift.String) - init?(rawValue: Swift.String) { + public init?(rawValue: Swift.String) { switch rawValue.lowercased() { case "application/json": self = .json @@ -3544,7 +3544,7 @@ enum Operations { } } - var rawValue: Swift.String { + public var rawValue: Swift.String { switch self { case let .other(string): string @@ -3553,7 +3553,7 @@ enum Operations { } } - static var allCases: [Self] { + public static var allCases: [Self] { [ .json ] @@ -3565,48 +3565,48 @@ enum Operations { /// /// - Remark: HTTP `POST /items/{itemname}`. /// - Remark: Generated from `#/paths//items/{itemname}/post(sendItemCommand)`. - enum sendItemCommand { - static let id: Swift.String = "sendItemCommand" - struct Input: Sendable, Hashable { + public enum sendItemCommand { + public static let id: Swift.String = "sendItemCommand" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/POST/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// item name /// /// - Remark: Generated from `#/paths/items/{itemname}/POST/path/itemname`. - var itemname: Swift.String + public var itemname: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - itemname: item name - init(itemname: Swift.String) { + public init(itemname: Swift.String) { self.itemname = itemname } } - var path: Operations.sendItemCommand.Input.Path + public var path: Operations.sendItemCommand.Input.Path /// - Remark: Generated from `#/paths/items/{itemname}/POST/requestBody`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/POST/requestBody/content/text\/plain`. case plainText(OpenAPIRuntime.HTTPBody) } - var body: Operations.sendItemCommand.Input.Body + public var body: Operations.sendItemCommand.Input.Body /// Creates a new `Input`. /// /// - Parameters: /// - path: /// - body: - init(path: Operations.sendItemCommand.Input.Path, - body: Operations.sendItemCommand.Input.Body) { + public init(path: Operations.sendItemCommand.Input.Path, + body: Operations.sendItemCommand.Input.Body) { self.path = path self.body = body } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// Creates a new `Ok`. - init() {} + public init() {} } /// OK @@ -3619,7 +3619,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.sendItemCommand.Output.Ok { + public var ok: Operations.sendItemCommand.Output.Ok { get throws { switch self { case let .ok(response): @@ -3633,9 +3633,9 @@ enum Operations { } } - struct BadRequest: Sendable, Hashable { + public struct BadRequest: Sendable, Hashable { /// Creates a new `BadRequest`. - init() {} + public init() {} } /// Item command null @@ -3648,7 +3648,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.badRequest`. /// - SeeAlso: `.badRequest`. - var badRequest: Operations.sendItemCommand.Output.BadRequest { + public var badRequest: Operations.sendItemCommand.Output.BadRequest { get throws { switch self { case let .badRequest(response): @@ -3662,9 +3662,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Item not found @@ -3677,7 +3677,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.sendItemCommand.Output.NotFound { + public var notFound: Operations.sendItemCommand.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -3702,78 +3702,78 @@ enum Operations { /// /// - Remark: HTTP `PUT /items/{itemname}`. /// - Remark: Generated from `#/paths//items/{itemname}/put(addOrUpdateItemInRegistry)`. - enum addOrUpdateItemInRegistry { - static let id: Swift.String = "addOrUpdateItemInRegistry" - struct Input: Sendable, Hashable { + public enum addOrUpdateItemInRegistry { + public static let id: Swift.String = "addOrUpdateItemInRegistry" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/PUT/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// item name /// /// - Remark: Generated from `#/paths/items/{itemname}/PUT/path/itemname`. - var itemname: Swift.String + public var itemname: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - itemname: item name - init(itemname: Swift.String) { + public init(itemname: Swift.String) { self.itemname = itemname } } - var path: Operations.addOrUpdateItemInRegistry.Input.Path + public var path: Operations.addOrUpdateItemInRegistry.Input.Path /// - Remark: Generated from `#/paths/items/{itemname}/PUT/header`. - struct Headers: Sendable, Hashable { + public struct Headers: Sendable, Hashable { /// language /// /// - Remark: Generated from `#/paths/items/{itemname}/PUT/header/Accept-Language`. - var Accept_hyphen_Language: Swift.String? - var accept: [OpenAPIRuntime.AcceptHeaderContentType] + public var Accept_hyphen_Language: Swift.String? + public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: /// - Accept_hyphen_Language: language /// - accept: - init(Accept_hyphen_Language: Swift.String? = nil, - accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + public init(Accept_hyphen_Language: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { self.Accept_hyphen_Language = Accept_hyphen_Language self.accept = accept } } - var headers: Operations.addOrUpdateItemInRegistry.Input.Headers + public var headers: Operations.addOrUpdateItemInRegistry.Input.Headers /// - Remark: Generated from `#/paths/items/{itemname}/PUT/requestBody`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/PUT/requestBody/content/application\/json`. case json(Components.Schemas.GroupItemDTO) } - var body: Operations.addOrUpdateItemInRegistry.Input.Body + public var body: Operations.addOrUpdateItemInRegistry.Input.Body /// Creates a new `Input`. /// /// - Parameters: /// - path: /// - headers: /// - body: - init(path: Operations.addOrUpdateItemInRegistry.Input.Path, - headers: Operations.addOrUpdateItemInRegistry.Input.Headers = .init(), - body: Operations.addOrUpdateItemInRegistry.Input.Body) { + public init(path: Operations.addOrUpdateItemInRegistry.Input.Path, + headers: Operations.addOrUpdateItemInRegistry.Input.Headers = .init(), + body: Operations.addOrUpdateItemInRegistry.Input.Body) { self.path = path self.headers = headers self.body = body } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/PUT/responses/200/content`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/PUT/responses/200/content/*\/*`. case any(OpenAPIRuntime.HTTPBody) /// The associated value of the enum case if `self` is `.any`. /// /// - Throws: An error if `self` is not `.any`. /// - SeeAlso: `.any`. - var any: OpenAPIRuntime.HTTPBody { + public var any: OpenAPIRuntime.HTTPBody { get throws { switch self { case let .any(body): @@ -3784,12 +3784,12 @@ enum Operations { } /// Received HTTP response body - var body: Operations.addOrUpdateItemInRegistry.Output.Ok.Body + public var body: Operations.addOrUpdateItemInRegistry.Output.Ok.Body /// Creates a new `Ok`. /// /// - Parameters: /// - body: Received HTTP response body - init(body: Operations.addOrUpdateItemInRegistry.Output.Ok.Body) { + public init(body: Operations.addOrUpdateItemInRegistry.Output.Ok.Body) { self.body = body } } @@ -3804,7 +3804,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.addOrUpdateItemInRegistry.Output.Ok { + public var ok: Operations.addOrUpdateItemInRegistry.Output.Ok { get throws { switch self { case let .ok(response): @@ -3818,9 +3818,9 @@ enum Operations { } } - struct Created: Sendable, Hashable { + public struct Created: Sendable, Hashable { /// Creates a new `Created`. - init() {} + public init() {} } /// Item created. @@ -3833,7 +3833,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.created`. /// - SeeAlso: `.created`. - var created: Operations.addOrUpdateItemInRegistry.Output.Created { + public var created: Operations.addOrUpdateItemInRegistry.Output.Created { get throws { switch self { case let .created(response): @@ -3847,9 +3847,9 @@ enum Operations { } } - struct BadRequest: Sendable, Hashable { + public struct BadRequest: Sendable, Hashable { /// Creates a new `BadRequest`. - init() {} + public init() {} } /// Payload invalid. @@ -3862,7 +3862,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.badRequest`. /// - SeeAlso: `.badRequest`. - var badRequest: Operations.addOrUpdateItemInRegistry.Output.BadRequest { + public var badRequest: Operations.addOrUpdateItemInRegistry.Output.BadRequest { get throws { switch self { case let .badRequest(response): @@ -3876,9 +3876,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Item not found or name in path invalid. @@ -3891,7 +3891,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.addOrUpdateItemInRegistry.Output.NotFound { + public var notFound: Operations.addOrUpdateItemInRegistry.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -3905,9 +3905,9 @@ enum Operations { } } - struct MethodNotAllowed: Sendable, Hashable { + public struct MethodNotAllowed: Sendable, Hashable { /// Creates a new `MethodNotAllowed`. - init() {} + public init() {} } /// Item not editable. @@ -3920,7 +3920,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.methodNotAllowed`. /// - SeeAlso: `.methodNotAllowed`. - var methodNotAllowed: Operations.addOrUpdateItemInRegistry.Output.MethodNotAllowed { + public var methodNotAllowed: Operations.addOrUpdateItemInRegistry.Output.MethodNotAllowed { get throws { switch self { case let .methodNotAllowed(response): @@ -3940,10 +3940,10 @@ enum Operations { case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) } - enum AcceptableContentType: AcceptableProtocol { + @frozen public enum AcceptableContentType: AcceptableProtocol { case any case other(Swift.String) - init?(rawValue: Swift.String) { + public init?(rawValue: Swift.String) { switch rawValue.lowercased() { case "*/*": self = .any @@ -3952,7 +3952,7 @@ enum Operations { } } - var rawValue: Swift.String { + public var rawValue: Swift.String { switch self { case let .other(string): string @@ -3961,7 +3961,7 @@ enum Operations { } } - static var allCases: [Self] { + public static var allCases: [Self] { [ .any ] @@ -3973,38 +3973,38 @@ enum Operations { /// /// - Remark: HTTP `DELETE /items/{itemname}`. /// - Remark: Generated from `#/paths//items/{itemname}/delete(removeItemFromRegistry)`. - enum removeItemFromRegistry { - static let id: Swift.String = "removeItemFromRegistry" - struct Input: Sendable, Hashable { + public enum removeItemFromRegistry { + public static let id: Swift.String = "removeItemFromRegistry" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/DELETE/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// item name /// /// - Remark: Generated from `#/paths/items/{itemname}/DELETE/path/itemname`. - var itemname: Swift.String + public var itemname: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - itemname: item name - init(itemname: Swift.String) { + public init(itemname: Swift.String) { self.itemname = itemname } } - var path: Operations.removeItemFromRegistry.Input.Path + public var path: Operations.removeItemFromRegistry.Input.Path /// Creates a new `Input`. /// /// - Parameters: /// - path: - init(path: Operations.removeItemFromRegistry.Input.Path) { + public init(path: Operations.removeItemFromRegistry.Input.Path) { self.path = path } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// Creates a new `Ok`. - init() {} + public init() {} } /// OK @@ -4017,7 +4017,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.removeItemFromRegistry.Output.Ok { + public var ok: Operations.removeItemFromRegistry.Output.Ok { get throws { switch self { case let .ok(response): @@ -4031,9 +4031,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Item not found or item is not editable. @@ -4046,7 +4046,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.removeItemFromRegistry.Output.NotFound { + public var notFound: Operations.removeItemFromRegistry.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -4071,35 +4071,35 @@ enum Operations { /// /// - Remark: HTTP `GET /items`. /// - Remark: Generated from `#/paths//items/get(getItems)`. - enum getItems { - static let id: Swift.String = "getItems" - struct Input: Sendable, Hashable { + public enum getItems { + public static let id: Swift.String = "getItems" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/GET/query`. - struct Query: Sendable, Hashable { + public struct Query: Sendable, Hashable { /// item type filter /// /// - Remark: Generated from `#/paths/items/GET/query/type`. - var _type: Swift.String? + public var _type: Swift.String? /// item tag filter /// /// - Remark: Generated from `#/paths/items/GET/query/tags`. - var tags: Swift.String? + public var tags: Swift.String? /// metadata selector - a comma separated list or a regular expression (returns all if no value given) /// /// - Remark: Generated from `#/paths/items/GET/query/metadata`. - var metadata: Swift.String? + public var metadata: Swift.String? /// get member items recursively /// /// - Remark: Generated from `#/paths/items/GET/query/recursive`. - var recursive: Swift.Bool? + public var recursive: Swift.Bool? /// limit output to the given fields (comma separated) /// /// - Remark: Generated from `#/paths/items/GET/query/fields`. - var fields: Swift.String? + public var fields: Swift.String? /// provides a cacheable list of values not expected to change regularly and checks the If-Modified-Since header, all other parameters are ignored except "metadata" /// /// - Remark: Generated from `#/paths/items/GET/query/staticDataOnly`. - var staticDataOnly: Swift.Bool? + public var staticDataOnly: Swift.Bool? /// Creates a new `Query`. /// /// - Parameters: @@ -4109,12 +4109,12 @@ enum Operations { /// - recursive: get member items recursively /// - fields: limit output to the given fields (comma separated) /// - staticDataOnly: provides a cacheable list of values not expected to change regularly and checks the If-Modified-Since header, all other parameters are ignored except "metadata" - init(_type: Swift.String? = nil, - tags: Swift.String? = nil, - metadata: Swift.String? = nil, - recursive: Swift.Bool? = nil, - fields: Swift.String? = nil, - staticDataOnly: Swift.Bool? = nil) { + public init(_type: Swift.String? = nil, + tags: Swift.String? = nil, + metadata: Swift.String? = nil, + recursive: Swift.Bool? = nil, + fields: Swift.String? = nil, + staticDataOnly: Swift.Bool? = nil) { self._type = _type self.tags = tags self.metadata = metadata @@ -4124,50 +4124,50 @@ enum Operations { } } - var query: Operations.getItems.Input.Query + public var query: Operations.getItems.Input.Query /// - Remark: Generated from `#/paths/items/GET/header`. - struct Headers: Sendable, Hashable { + public struct Headers: Sendable, Hashable { /// language /// /// - Remark: Generated from `#/paths/items/GET/header/Accept-Language`. - var Accept_hyphen_Language: Swift.String? - var accept: [OpenAPIRuntime.AcceptHeaderContentType] + public var Accept_hyphen_Language: Swift.String? + public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: /// - Accept_hyphen_Language: language /// - accept: - init(Accept_hyphen_Language: Swift.String? = nil, - accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + public init(Accept_hyphen_Language: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { self.Accept_hyphen_Language = Accept_hyphen_Language self.accept = accept } } - var headers: Operations.getItems.Input.Headers + public var headers: Operations.getItems.Input.Headers /// Creates a new `Input`. /// /// - Parameters: /// - query: /// - headers: - init(query: Operations.getItems.Input.Query = .init(), - headers: Operations.getItems.Input.Headers = .init()) { + public init(query: Operations.getItems.Input.Query = .init(), + headers: Operations.getItems.Input.Headers = .init()) { self.query = query self.headers = headers } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/GET/responses/200/content`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/GET/responses/200/content/application\/json`. case json([Components.Schemas.EnrichedItemDTO]) /// The associated value of the enum case if `self` is `.json`. /// /// - Throws: An error if `self` is not `.json`. /// - SeeAlso: `.json`. - var json: [Components.Schemas.EnrichedItemDTO] { + public var json: [Components.Schemas.EnrichedItemDTO] { get throws { switch self { case let .json(body): @@ -4178,12 +4178,12 @@ enum Operations { } /// Received HTTP response body - var body: Operations.getItems.Output.Ok.Body + public var body: Operations.getItems.Output.Ok.Body /// Creates a new `Ok`. /// /// - Parameters: /// - body: Received HTTP response body - init(body: Operations.getItems.Output.Ok.Body) { + public init(body: Operations.getItems.Output.Ok.Body) { self.body = body } } @@ -4198,7 +4198,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.getItems.Output.Ok { + public var ok: Operations.getItems.Output.Ok { get throws { switch self { case let .ok(response): @@ -4218,10 +4218,10 @@ enum Operations { case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) } - enum AcceptableContentType: AcceptableProtocol { + @frozen public enum AcceptableContentType: AcceptableProtocol { case json case other(Swift.String) - init?(rawValue: Swift.String) { + public init?(rawValue: Swift.String) { switch rawValue.lowercased() { case "application/json": self = .json @@ -4230,7 +4230,7 @@ enum Operations { } } - var rawValue: Swift.String { + public var rawValue: Swift.String { switch self { case let .other(string): string @@ -4239,7 +4239,7 @@ enum Operations { } } - static var allCases: [Self] { + public static var allCases: [Self] { [ .json ] @@ -4251,52 +4251,52 @@ enum Operations { /// /// - Remark: HTTP `PUT /items`. /// - Remark: Generated from `#/paths//items/put(addOrUpdateItemsInRegistry)`. - enum addOrUpdateItemsInRegistry { - static let id: Swift.String = "addOrUpdateItemsInRegistry" - struct Input: Sendable, Hashable { + public enum addOrUpdateItemsInRegistry { + public static let id: Swift.String = "addOrUpdateItemsInRegistry" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/PUT/header`. - struct Headers: Sendable, Hashable { - var accept: [OpenAPIRuntime.AcceptHeaderContentType] + public struct Headers: Sendable, Hashable { + public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: /// - accept: - init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + public init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { self.accept = accept } } - var headers: Operations.addOrUpdateItemsInRegistry.Input.Headers + public var headers: Operations.addOrUpdateItemsInRegistry.Input.Headers /// - Remark: Generated from `#/paths/items/PUT/requestBody`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/PUT/requestBody/content/application\/json`. case json([Components.Schemas.GroupItemDTO]) } - var body: Operations.addOrUpdateItemsInRegistry.Input.Body + public var body: Operations.addOrUpdateItemsInRegistry.Input.Body /// Creates a new `Input`. /// /// - Parameters: /// - headers: /// - body: - init(headers: Operations.addOrUpdateItemsInRegistry.Input.Headers = .init(), - body: Operations.addOrUpdateItemsInRegistry.Input.Body) { + public init(headers: Operations.addOrUpdateItemsInRegistry.Input.Headers = .init(), + body: Operations.addOrUpdateItemsInRegistry.Input.Body) { self.headers = headers self.body = body } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/PUT/responses/200/content`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/PUT/responses/200/content/*\/*`. case any(OpenAPIRuntime.HTTPBody) /// The associated value of the enum case if `self` is `.any`. /// /// - Throws: An error if `self` is not `.any`. /// - SeeAlso: `.any`. - var any: OpenAPIRuntime.HTTPBody { + public var any: OpenAPIRuntime.HTTPBody { get throws { switch self { case let .any(body): @@ -4307,12 +4307,12 @@ enum Operations { } /// Received HTTP response body - var body: Operations.addOrUpdateItemsInRegistry.Output.Ok.Body + public var body: Operations.addOrUpdateItemsInRegistry.Output.Ok.Body /// Creates a new `Ok`. /// /// - Parameters: /// - body: Received HTTP response body - init(body: Operations.addOrUpdateItemsInRegistry.Output.Ok.Body) { + public init(body: Operations.addOrUpdateItemsInRegistry.Output.Ok.Body) { self.body = body } } @@ -4327,7 +4327,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.addOrUpdateItemsInRegistry.Output.Ok { + public var ok: Operations.addOrUpdateItemsInRegistry.Output.Ok { get throws { switch self { case let .ok(response): @@ -4341,9 +4341,9 @@ enum Operations { } } - struct BadRequest: Sendable, Hashable { + public struct BadRequest: Sendable, Hashable { /// Creates a new `BadRequest`. - init() {} + public init() {} } /// Payload is invalid. @@ -4356,7 +4356,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.badRequest`. /// - SeeAlso: `.badRequest`. - var badRequest: Operations.addOrUpdateItemsInRegistry.Output.BadRequest { + public var badRequest: Operations.addOrUpdateItemsInRegistry.Output.BadRequest { get throws { switch self { case let .badRequest(response): @@ -4376,10 +4376,10 @@ enum Operations { case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) } - enum AcceptableContentType: AcceptableProtocol { + @frozen public enum AcceptableContentType: AcceptableProtocol { case any case other(Swift.String) - init?(rawValue: Swift.String) { + public init?(rawValue: Swift.String) { switch rawValue.lowercased() { case "*/*": self = .any @@ -4388,7 +4388,7 @@ enum Operations { } } - var rawValue: Swift.String { + public var rawValue: Swift.String { switch self { case let .other(string): string @@ -4397,7 +4397,7 @@ enum Operations { } } - static var allCases: [Self] { + public static var allCases: [Self] { [ .any ] @@ -4409,61 +4409,61 @@ enum Operations { /// /// - Remark: HTTP `GET /items/{itemname}/state`. /// - Remark: Generated from `#/paths//items/{itemname}/state/get(getItemState_1)`. - enum getItemState_1 { - static let id: Swift.String = "getItemState_1" - struct Input: Sendable, Hashable { + public enum getItemState_1 { + public static let id: Swift.String = "getItemState_1" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/state/GET/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// item name /// /// - Remark: Generated from `#/paths/items/{itemname}/state/GET/path/itemname`. - var itemname: Swift.String + public var itemname: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - itemname: item name - init(itemname: Swift.String) { + public init(itemname: Swift.String) { self.itemname = itemname } } - var path: Operations.getItemState_1.Input.Path + public var path: Operations.getItemState_1.Input.Path /// - Remark: Generated from `#/paths/items/{itemname}/state/GET/header`. - struct Headers: Sendable, Hashable { - var accept: [OpenAPIRuntime.AcceptHeaderContentType] + public struct Headers: Sendable, Hashable { + public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: /// - accept: - init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + public init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { self.accept = accept } } - var headers: Operations.getItemState_1.Input.Headers + public var headers: Operations.getItemState_1.Input.Headers /// Creates a new `Input`. /// /// - Parameters: /// - path: /// - headers: - init(path: Operations.getItemState_1.Input.Path, - headers: Operations.getItemState_1.Input.Headers = .init()) { + public init(path: Operations.getItemState_1.Input.Path, + headers: Operations.getItemState_1.Input.Headers = .init()) { self.path = path self.headers = headers } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/state/GET/responses/200/content`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/state/GET/responses/200/content/text\/plain`. case plainText(OpenAPIRuntime.HTTPBody) /// The associated value of the enum case if `self` is `.plainText`. /// /// - Throws: An error if `self` is not `.plainText`. /// - SeeAlso: `.plainText`. - var plainText: OpenAPIRuntime.HTTPBody { + public var plainText: OpenAPIRuntime.HTTPBody { get throws { switch self { case let .plainText(body): @@ -4474,12 +4474,12 @@ enum Operations { } /// Received HTTP response body - var body: Operations.getItemState_1.Output.Ok.Body + public var body: Operations.getItemState_1.Output.Ok.Body /// Creates a new `Ok`. /// /// - Parameters: /// - body: Received HTTP response body - init(body: Operations.getItemState_1.Output.Ok.Body) { + public init(body: Operations.getItemState_1.Output.Ok.Body) { self.body = body } } @@ -4494,7 +4494,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.getItemState_1.Output.Ok { + public var ok: Operations.getItemState_1.Output.Ok { get throws { switch self { case let .ok(response): @@ -4508,9 +4508,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Item not found @@ -4523,7 +4523,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.getItemState_1.Output.NotFound { + public var notFound: Operations.getItemState_1.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -4543,10 +4543,10 @@ enum Operations { case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) } - enum AcceptableContentType: AcceptableProtocol { + @frozen public enum AcceptableContentType: AcceptableProtocol { case plainText case other(Swift.String) - init?(rawValue: Swift.String) { + public init?(rawValue: Swift.String) { switch rawValue.lowercased() { case "text/plain": self = .plainText @@ -4555,7 +4555,7 @@ enum Operations { } } - var rawValue: Swift.String { + public var rawValue: Swift.String { switch self { case let .other(string): string @@ -4564,7 +4564,7 @@ enum Operations { } } - static var allCases: [Self] { + public static var allCases: [Self] { [ .plainText ] @@ -4576,67 +4576,67 @@ enum Operations { /// /// - Remark: HTTP `PUT /items/{itemname}/state`. /// - Remark: Generated from `#/paths//items/{itemname}/state/put(updateItemState)`. - enum updateItemState { - static let id: Swift.String = "updateItemState" - struct Input: Sendable, Hashable { + public enum updateItemState { + public static let id: Swift.String = "updateItemState" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/state/PUT/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// item name /// /// - Remark: Generated from `#/paths/items/{itemname}/state/PUT/path/itemname`. - var itemname: Swift.String + public var itemname: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - itemname: item name - init(itemname: Swift.String) { + public init(itemname: Swift.String) { self.itemname = itemname } } - var path: Operations.updateItemState.Input.Path + public var path: Operations.updateItemState.Input.Path /// - Remark: Generated from `#/paths/items/{itemname}/state/PUT/header`. - struct Headers: Sendable, Hashable { + public struct Headers: Sendable, Hashable { /// language /// /// - Remark: Generated from `#/paths/items/{itemname}/state/PUT/header/Accept-Language`. - var Accept_hyphen_Language: Swift.String? + public var Accept_hyphen_Language: Swift.String? /// Creates a new `Headers`. /// /// - Parameters: /// - Accept_hyphen_Language: language - init(Accept_hyphen_Language: Swift.String? = nil) { + public init(Accept_hyphen_Language: Swift.String? = nil) { self.Accept_hyphen_Language = Accept_hyphen_Language } } - var headers: Operations.updateItemState.Input.Headers + public var headers: Operations.updateItemState.Input.Headers /// - Remark: Generated from `#/paths/items/{itemname}/state/PUT/requestBody`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/state/PUT/requestBody/content/text\/plain`. case plainText(OpenAPIRuntime.HTTPBody) } - var body: Operations.updateItemState.Input.Body + public var body: Operations.updateItemState.Input.Body /// Creates a new `Input`. /// /// - Parameters: /// - path: /// - headers: /// - body: - init(path: Operations.updateItemState.Input.Path, - headers: Operations.updateItemState.Input.Headers = .init(), - body: Operations.updateItemState.Input.Body) { + public init(path: Operations.updateItemState.Input.Path, + headers: Operations.updateItemState.Input.Headers = .init(), + body: Operations.updateItemState.Input.Body) { self.path = path self.headers = headers self.body = body } } - enum Output: Sendable, Hashable { - struct Accepted: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Accepted: Sendable, Hashable { /// Creates a new `Accepted`. - init() {} + public init() {} } /// Accepted @@ -4649,7 +4649,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.accepted`. /// - SeeAlso: `.accepted`. - var accepted: Operations.updateItemState.Output.Accepted { + public var accepted: Operations.updateItemState.Output.Accepted { get throws { switch self { case let .accepted(response): @@ -4663,9 +4663,9 @@ enum Operations { } } - struct BadRequest: Sendable, Hashable { + public struct BadRequest: Sendable, Hashable { /// Creates a new `BadRequest`. - init() {} + public init() {} } /// Item state null @@ -4678,7 +4678,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.badRequest`. /// - SeeAlso: `.badRequest`. - var badRequest: Operations.updateItemState.Output.BadRequest { + public var badRequest: Operations.updateItemState.Output.BadRequest { get throws { switch self { case let .badRequest(response): @@ -4692,9 +4692,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Item not found @@ -4707,7 +4707,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.updateItemState.Output.NotFound { + public var notFound: Operations.updateItemState.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -4732,68 +4732,68 @@ enum Operations { /// /// - Remark: HTTP `GET /items/{itemname}/metadata/namespaces`. /// - Remark: Generated from `#/paths//items/{itemname}/metadata/namespaces/get(getItemNamespaces)`. - enum getItemNamespaces { - static let id: Swift.String = "getItemNamespaces" - struct Input: Sendable, Hashable { + public enum getItemNamespaces { + public static let id: Swift.String = "getItemNamespaces" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/metadata/namespaces/GET/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// item name /// /// - Remark: Generated from `#/paths/items/{itemname}/metadata/namespaces/GET/path/itemname`. - var itemname: Swift.String + public var itemname: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - itemname: item name - init(itemname: Swift.String) { + public init(itemname: Swift.String) { self.itemname = itemname } } - var path: Operations.getItemNamespaces.Input.Path + public var path: Operations.getItemNamespaces.Input.Path /// - Remark: Generated from `#/paths/items/{itemname}/metadata/namespaces/GET/header`. - struct Headers: Sendable, Hashable { + public struct Headers: Sendable, Hashable { /// language /// /// - Remark: Generated from `#/paths/items/{itemname}/metadata/namespaces/GET/header/Accept-Language`. - var Accept_hyphen_Language: Swift.String? - var accept: [OpenAPIRuntime.AcceptHeaderContentType] + public var Accept_hyphen_Language: Swift.String? + public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: /// - Accept_hyphen_Language: language /// - accept: - init(Accept_hyphen_Language: Swift.String? = nil, - accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + public init(Accept_hyphen_Language: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { self.Accept_hyphen_Language = Accept_hyphen_Language self.accept = accept } } - var headers: Operations.getItemNamespaces.Input.Headers + public var headers: Operations.getItemNamespaces.Input.Headers /// Creates a new `Input`. /// /// - Parameters: /// - path: /// - headers: - init(path: Operations.getItemNamespaces.Input.Path, - headers: Operations.getItemNamespaces.Input.Headers = .init()) { + public init(path: Operations.getItemNamespaces.Input.Path, + headers: Operations.getItemNamespaces.Input.Headers = .init()) { self.path = path self.headers = headers } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/metadata/namespaces/GET/responses/200/content`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemname}/metadata/namespaces/GET/responses/200/content/application\/json`. case json(Swift.String) /// The associated value of the enum case if `self` is `.json`. /// /// - Throws: An error if `self` is not `.json`. /// - SeeAlso: `.json`. - var json: Swift.String { + public var json: Swift.String { get throws { switch self { case let .json(body): @@ -4804,12 +4804,12 @@ enum Operations { } /// Received HTTP response body - var body: Operations.getItemNamespaces.Output.Ok.Body + public var body: Operations.getItemNamespaces.Output.Ok.Body /// Creates a new `Ok`. /// /// - Parameters: /// - body: Received HTTP response body - init(body: Operations.getItemNamespaces.Output.Ok.Body) { + public init(body: Operations.getItemNamespaces.Output.Ok.Body) { self.body = body } } @@ -4824,7 +4824,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.getItemNamespaces.Output.Ok { + public var ok: Operations.getItemNamespaces.Output.Ok { get throws { switch self { case let .ok(response): @@ -4838,9 +4838,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Item not found @@ -4853,7 +4853,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.getItemNamespaces.Output.NotFound { + public var notFound: Operations.getItemNamespaces.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -4873,10 +4873,10 @@ enum Operations { case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) } - enum AcceptableContentType: AcceptableProtocol { + @frozen public enum AcceptableContentType: AcceptableProtocol { case json case other(Swift.String) - init?(rawValue: Swift.String) { + public init?(rawValue: Swift.String) { switch rawValue.lowercased() { case "application/json": self = .json @@ -4885,7 +4885,7 @@ enum Operations { } } - var rawValue: Swift.String { + public var rawValue: Swift.String { switch self { case let .other(string): string @@ -4894,7 +4894,7 @@ enum Operations { } } - static var allCases: [Self] { + public static var allCases: [Self] { [ .json ] @@ -4906,64 +4906,64 @@ enum Operations { /// /// - Remark: HTTP `GET /items/{itemName}/semantic/{semanticClass}`. /// - Remark: Generated from `#/paths//items/{itemName}/semantic/{semanticClass}/get(getSemanticItem)`. - enum getSemanticItem { - static let id: Swift.String = "getSemanticItem" - struct Input: Sendable, Hashable { + public enum getSemanticItem { + public static let id: Swift.String = "getSemanticItem" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/items/{itemName}/semantic/{semanticClass}/GET/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// item name /// /// - Remark: Generated from `#/paths/items/{itemName}/semantic/{semanticClass}/GET/path/itemName`. - var itemName: Swift.String + public var itemName: Swift.String /// semantic class /// /// - Remark: Generated from `#/paths/items/{itemName}/semantic/{semanticClass}/GET/path/semanticClass`. - var semanticClass: Swift.String + public var semanticClass: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - itemName: item name /// - semanticClass: semantic class - init(itemName: Swift.String, - semanticClass: Swift.String) { + public init(itemName: Swift.String, + semanticClass: Swift.String) { self.itemName = itemName self.semanticClass = semanticClass } } - var path: Operations.getSemanticItem.Input.Path + public var path: Operations.getSemanticItem.Input.Path /// - Remark: Generated from `#/paths/items/{itemName}/semantic/{semanticClass}/GET/header`. - struct Headers: Sendable, Hashable { + public struct Headers: Sendable, Hashable { /// language /// /// - Remark: Generated from `#/paths/items/{itemName}/semantic/{semanticClass}/GET/header/Accept-Language`. - var Accept_hyphen_Language: Swift.String? + public var Accept_hyphen_Language: Swift.String? /// Creates a new `Headers`. /// /// - Parameters: /// - Accept_hyphen_Language: language - init(Accept_hyphen_Language: Swift.String? = nil) { + public init(Accept_hyphen_Language: Swift.String? = nil) { self.Accept_hyphen_Language = Accept_hyphen_Language } } - var headers: Operations.getSemanticItem.Input.Headers + public var headers: Operations.getSemanticItem.Input.Headers /// Creates a new `Input`. /// /// - Parameters: /// - path: /// - headers: - init(path: Operations.getSemanticItem.Input.Path, - headers: Operations.getSemanticItem.Input.Headers = .init()) { + public init(path: Operations.getSemanticItem.Input.Path, + headers: Operations.getSemanticItem.Input.Headers = .init()) { self.path = path self.headers = headers } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// Creates a new `Ok`. - init() {} + public init() {} } /// OK @@ -4976,7 +4976,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.getSemanticItem.Output.Ok { + public var ok: Operations.getSemanticItem.Output.Ok { get throws { switch self { case let .ok(response): @@ -4990,9 +4990,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Item not found @@ -5005,7 +5005,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.getSemanticItem.Output.NotFound { + public var notFound: Operations.getSemanticItem.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -5030,17 +5030,17 @@ enum Operations { /// /// - Remark: HTTP `POST /items/metadata/purge`. /// - Remark: Generated from `#/paths//items/metadata/purge/post(purgeDatabase)`. - enum purgeDatabase { - static let id: Swift.String = "purgeDatabase" - struct Input: Sendable, Hashable { + public enum purgeDatabase { + public static let id: Swift.String = "purgeDatabase" + public struct Input: Sendable, Hashable { /// Creates a new `Input`. - init() {} + public init() {} } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// Creates a new `Ok`. - init() {} + public init() {} } /// OK @@ -5053,7 +5053,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.purgeDatabase.Output.Ok { + public var ok: Operations.purgeDatabase.Output.Ok { get throws { switch self { case let .ok(response): @@ -5078,35 +5078,35 @@ enum Operations { /// /// - Remark: HTTP `POST /sitemaps/events/subscribe`. /// - Remark: Generated from `#/paths//sitemaps/events/subscribe/post(createSitemapEventSubscription)`. - enum createSitemapEventSubscription { - static let id: Swift.String = "createSitemapEventSubscription" - struct Input: Sendable, Hashable { + public enum createSitemapEventSubscription { + public static let id: Swift.String = "createSitemapEventSubscription" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/events/subscribe/POST/header`. - struct Headers: Sendable, Hashable { - var accept: [OpenAPIRuntime.AcceptHeaderContentType] + public struct Headers: Sendable, Hashable { + public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: /// - accept: - init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + public init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { self.accept = accept } } - var headers: Operations.createSitemapEventSubscription.Input.Headers + public var headers: Operations.createSitemapEventSubscription.Input.Headers /// Creates a new `Input`. /// /// - Parameters: /// - headers: - init(headers: Operations.createSitemapEventSubscription.Input.Headers = .init()) { + public init(headers: Operations.createSitemapEventSubscription.Input.Headers = .init()) { self.headers = headers } } - enum Output: Sendable, Hashable { - struct Created: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Created: Sendable, Hashable { /// Creates a new `Created`. - init() {} + public init() {} } /// Subscription created. @@ -5119,7 +5119,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.created`. /// - SeeAlso: `.created`. - var created: Operations.createSitemapEventSubscription.Output.Created { + public var created: Operations.createSitemapEventSubscription.Output.Created { get throws { switch self { case let .created(response): @@ -5133,16 +5133,16 @@ enum Operations { } } - struct Ok: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/events/subscribe/POST/responses/200/content`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/events/subscribe/POST/responses/200/content/application\/json`. case json(Components.Schemas.JerseyResponseBuilderDTO) /// The associated value of the enum case if `self` is `.json`. /// /// - Throws: An error if `self` is not `.json`. /// - SeeAlso: `.json`. - var json: Components.Schemas.JerseyResponseBuilderDTO { + public var json: Components.Schemas.JerseyResponseBuilderDTO { get throws { switch self { case let .json(body): @@ -5153,12 +5153,12 @@ enum Operations { } /// Received HTTP response body - var body: Operations.createSitemapEventSubscription.Output.Ok.Body + public var body: Operations.createSitemapEventSubscription.Output.Ok.Body /// Creates a new `Ok`. /// /// - Parameters: /// - body: Received HTTP response body - init(body: Operations.createSitemapEventSubscription.Output.Ok.Body) { + public init(body: Operations.createSitemapEventSubscription.Output.Ok.Body) { self.body = body } } @@ -5173,7 +5173,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.createSitemapEventSubscription.Output.Ok { + public var ok: Operations.createSitemapEventSubscription.Output.Ok { get throws { switch self { case let .ok(response): @@ -5187,9 +5187,9 @@ enum Operations { } } - struct ServiceUnavailable: Sendable, Hashable { + public struct ServiceUnavailable: Sendable, Hashable { /// Creates a new `ServiceUnavailable`. - init() {} + public init() {} } /// Subscriptions limit reached. @@ -5202,7 +5202,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.serviceUnavailable`. /// - SeeAlso: `.serviceUnavailable`. - var serviceUnavailable: Operations.createSitemapEventSubscription.Output.ServiceUnavailable { + public var serviceUnavailable: Operations.createSitemapEventSubscription.Output.ServiceUnavailable { get throws { switch self { case let .serviceUnavailable(response): @@ -5222,10 +5222,10 @@ enum Operations { case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) } - enum AcceptableContentType: AcceptableProtocol { + @frozen public enum AcceptableContentType: AcceptableProtocol { case json case other(Swift.String) - init?(rawValue: Swift.String) { + public init?(rawValue: Swift.String) { switch rawValue.lowercased() { case "application/json": self = .json @@ -5234,7 +5234,7 @@ enum Operations { } } - var rawValue: Swift.String { + public var rawValue: Swift.String { switch self { case let .other(string): string @@ -5243,7 +5243,7 @@ enum Operations { } } - static var allCases: [Self] { + public static var allCases: [Self] { [ .json ] @@ -5255,108 +5255,108 @@ enum Operations { /// /// - Remark: HTTP `GET /sitemaps/{sitemapname}/{pageid}`. /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/{pageid}/get(pollDataForPage)`. - enum pollDataForPage { - static let id: Swift.String = "pollDataForPage" - struct Input: Sendable, Hashable { + public enum pollDataForPage { + public static let id: Swift.String = "pollDataForPage" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// sitemap name /// /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/path/sitemapname`. - var sitemapname: Swift.String + public var sitemapname: Swift.String /// page id /// /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/path/pageid`. - var pageid: Swift.String + public var pageid: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - sitemapname: sitemap name /// - pageid: page id - init(sitemapname: Swift.String, - pageid: Swift.String) { + public init(sitemapname: Swift.String, + pageid: Swift.String) { self.sitemapname = sitemapname self.pageid = pageid } } - var path: Operations.pollDataForPage.Input.Path + public var path: Operations.pollDataForPage.Input.Path /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/query`. - struct Query: Sendable, Hashable { + public struct Query: Sendable, Hashable { /// subscriptionid /// /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/query/subscriptionid`. - var subscriptionid: Swift.String? + public var subscriptionid: Swift.String? /// include hidden widgets /// /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/query/includeHidden`. - var includeHidden: Swift.Bool? + public var includeHidden: Swift.Bool? /// Creates a new `Query`. /// /// - Parameters: /// - subscriptionid: subscriptionid /// - includeHidden: include hidden widgets - init(subscriptionid: Swift.String? = nil, - includeHidden: Swift.Bool? = nil) { + public init(subscriptionid: Swift.String? = nil, + includeHidden: Swift.Bool? = nil) { self.subscriptionid = subscriptionid self.includeHidden = includeHidden } } - var query: Operations.pollDataForPage.Input.Query + public var query: Operations.pollDataForPage.Input.Query /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/header`. - struct Headers: Sendable, Hashable { + public struct Headers: Sendable, Hashable { /// language /// /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/header/Accept-Language`. - var Accept_hyphen_Language: Swift.String? + public var Accept_hyphen_Language: Swift.String? /// X-Atmosphere-Transport for long polling /// /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/header/X-Atmosphere-Transport`. - var X_hyphen_Atmosphere_hyphen_Transport: Swift.String? - var accept: [OpenAPIRuntime.AcceptHeaderContentType] + public var X_hyphen_Atmosphere_hyphen_Transport: Swift.String? + public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: /// - Accept_hyphen_Language: language /// - X_hyphen_Atmosphere_hyphen_Transport: X-Atmosphere-Transport for long polling /// - accept: - init(Accept_hyphen_Language: Swift.String? = nil, - X_hyphen_Atmosphere_hyphen_Transport: Swift.String? = nil, - accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + public init(Accept_hyphen_Language: Swift.String? = nil, + X_hyphen_Atmosphere_hyphen_Transport: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { self.Accept_hyphen_Language = Accept_hyphen_Language self.X_hyphen_Atmosphere_hyphen_Transport = X_hyphen_Atmosphere_hyphen_Transport self.accept = accept } } - var headers: Operations.pollDataForPage.Input.Headers + public var headers: Operations.pollDataForPage.Input.Headers /// Creates a new `Input`. /// /// - Parameters: /// - path: /// - query: /// - headers: - init(path: Operations.pollDataForPage.Input.Path, - query: Operations.pollDataForPage.Input.Query = .init(), - headers: Operations.pollDataForPage.Input.Headers = .init()) { + public init(path: Operations.pollDataForPage.Input.Path, + query: Operations.pollDataForPage.Input.Query = .init(), + headers: Operations.pollDataForPage.Input.Headers = .init()) { self.path = path self.query = query self.headers = headers } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/responses/200/content`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/{pageid}/GET/responses/200/content/application\/json`. case json(Components.Schemas.PageDTO) /// The associated value of the enum case if `self` is `.json`. /// /// - Throws: An error if `self` is not `.json`. /// - SeeAlso: `.json`. - var json: Components.Schemas.PageDTO { + public var json: Components.Schemas.PageDTO { get throws { switch self { case let .json(body): @@ -5367,12 +5367,12 @@ enum Operations { } /// Received HTTP response body - var body: Operations.pollDataForPage.Output.Ok.Body + public var body: Operations.pollDataForPage.Output.Ok.Body /// Creates a new `Ok`. /// /// - Parameters: /// - body: Received HTTP response body - init(body: Operations.pollDataForPage.Output.Ok.Body) { + public init(body: Operations.pollDataForPage.Output.Ok.Body) { self.body = body } } @@ -5387,7 +5387,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.pollDataForPage.Output.Ok { + public var ok: Operations.pollDataForPage.Output.Ok { get throws { switch self { case let .ok(response): @@ -5401,9 +5401,9 @@ enum Operations { } } - struct BadRequest: Sendable, Hashable { + public struct BadRequest: Sendable, Hashable { /// Creates a new `BadRequest`. - init() {} + public init() {} } /// Invalid subscription id has been provided. @@ -5416,7 +5416,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.badRequest`. /// - SeeAlso: `.badRequest`. - var badRequest: Operations.pollDataForPage.Output.BadRequest { + public var badRequest: Operations.pollDataForPage.Output.BadRequest { get throws { switch self { case let .badRequest(response): @@ -5430,9 +5430,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Sitemap with requested name does not exist or page does not exist, or page refers to a non-linkable widget @@ -5445,7 +5445,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.pollDataForPage.Output.NotFound { + public var notFound: Operations.pollDataForPage.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -5465,10 +5465,10 @@ enum Operations { case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) } - enum AcceptableContentType: AcceptableProtocol { + @frozen public enum AcceptableContentType: AcceptableProtocol { case json case other(Swift.String) - init?(rawValue: Swift.String) { + public init?(rawValue: Swift.String) { switch rawValue.lowercased() { case "application/json": self = .json @@ -5477,7 +5477,7 @@ enum Operations { } } - var rawValue: Swift.String { + public var rawValue: Swift.String { switch self { case let .other(string): string @@ -5486,7 +5486,7 @@ enum Operations { } } - static var allCases: [Self] { + public static var allCases: [Self] { [ .json ] @@ -5498,101 +5498,101 @@ enum Operations { /// /// - Remark: HTTP `GET /sitemaps/{sitemapname}/*`. /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/*/get(pollDataForSitemap)`. - enum pollDataForSitemap { - static let id: Swift.String = "pollDataForSitemap" - struct Input: Sendable, Hashable { + public enum pollDataForSitemap { + public static let id: Swift.String = "pollDataForSitemap" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// sitemap name /// /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/path/sitemapname`. - var sitemapname: Swift.String + public var sitemapname: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - sitemapname: sitemap name - init(sitemapname: Swift.String) { + public init(sitemapname: Swift.String) { self.sitemapname = sitemapname } } - var path: Operations.pollDataForSitemap.Input.Path + public var path: Operations.pollDataForSitemap.Input.Path /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/query`. - struct Query: Sendable, Hashable { + public struct Query: Sendable, Hashable { /// subscriptionid /// /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/query/subscriptionid`. - var subscriptionid: Swift.String? + public var subscriptionid: Swift.String? /// include hidden widgets /// /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/query/includeHidden`. - var includeHidden: Swift.Bool? + public var includeHidden: Swift.Bool? /// Creates a new `Query`. /// /// - Parameters: /// - subscriptionid: subscriptionid /// - includeHidden: include hidden widgets - init(subscriptionid: Swift.String? = nil, - includeHidden: Swift.Bool? = nil) { + public init(subscriptionid: Swift.String? = nil, + includeHidden: Swift.Bool? = nil) { self.subscriptionid = subscriptionid self.includeHidden = includeHidden } } - var query: Operations.pollDataForSitemap.Input.Query + public var query: Operations.pollDataForSitemap.Input.Query /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/header`. - struct Headers: Sendable, Hashable { + public struct Headers: Sendable, Hashable { /// language /// /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/header/Accept-Language`. - var Accept_hyphen_Language: Swift.String? + public var Accept_hyphen_Language: Swift.String? /// X-Atmosphere-Transport for long polling /// /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/header/X-Atmosphere-Transport`. - var X_hyphen_Atmosphere_hyphen_Transport: Swift.String? - var accept: [OpenAPIRuntime.AcceptHeaderContentType] + public var X_hyphen_Atmosphere_hyphen_Transport: Swift.String? + public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: /// - Accept_hyphen_Language: language /// - X_hyphen_Atmosphere_hyphen_Transport: X-Atmosphere-Transport for long polling /// - accept: - init(Accept_hyphen_Language: Swift.String? = nil, - X_hyphen_Atmosphere_hyphen_Transport: Swift.String? = nil, - accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + public init(Accept_hyphen_Language: Swift.String? = nil, + X_hyphen_Atmosphere_hyphen_Transport: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { self.Accept_hyphen_Language = Accept_hyphen_Language self.X_hyphen_Atmosphere_hyphen_Transport = X_hyphen_Atmosphere_hyphen_Transport self.accept = accept } } - var headers: Operations.pollDataForSitemap.Input.Headers + public var headers: Operations.pollDataForSitemap.Input.Headers /// Creates a new `Input`. /// /// - Parameters: /// - path: /// - query: /// - headers: - init(path: Operations.pollDataForSitemap.Input.Path, - query: Operations.pollDataForSitemap.Input.Query = .init(), - headers: Operations.pollDataForSitemap.Input.Headers = .init()) { + public init(path: Operations.pollDataForSitemap.Input.Path, + query: Operations.pollDataForSitemap.Input.Query = .init(), + headers: Operations.pollDataForSitemap.Input.Headers = .init()) { self.path = path self.query = query self.headers = headers } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/responses/200/content`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/*/GET/responses/200/content/application\/json`. case json(Components.Schemas.SitemapDTO) /// The associated value of the enum case if `self` is `.json`. /// /// - Throws: An error if `self` is not `.json`. /// - SeeAlso: `.json`. - var json: Components.Schemas.SitemapDTO { + public var json: Components.Schemas.SitemapDTO { get throws { switch self { case let .json(body): @@ -5603,12 +5603,12 @@ enum Operations { } /// Received HTTP response body - var body: Operations.pollDataForSitemap.Output.Ok.Body + public var body: Operations.pollDataForSitemap.Output.Ok.Body /// Creates a new `Ok`. /// /// - Parameters: /// - body: Received HTTP response body - init(body: Operations.pollDataForSitemap.Output.Ok.Body) { + public init(body: Operations.pollDataForSitemap.Output.Ok.Body) { self.body = body } } @@ -5623,7 +5623,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.pollDataForSitemap.Output.Ok { + public var ok: Operations.pollDataForSitemap.Output.Ok { get throws { switch self { case let .ok(response): @@ -5637,9 +5637,9 @@ enum Operations { } } - struct BadRequest: Sendable, Hashable { + public struct BadRequest: Sendable, Hashable { /// Creates a new `BadRequest`. - init() {} + public init() {} } /// Invalid subscription id has been provided. @@ -5652,7 +5652,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.badRequest`. /// - SeeAlso: `.badRequest`. - var badRequest: Operations.pollDataForSitemap.Output.BadRequest { + public var badRequest: Operations.pollDataForSitemap.Output.BadRequest { get throws { switch self { case let .badRequest(response): @@ -5666,9 +5666,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Sitemap with requested name does not exist @@ -5681,7 +5681,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.pollDataForSitemap.Output.NotFound { + public var notFound: Operations.pollDataForSitemap.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -5701,10 +5701,10 @@ enum Operations { case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) } - enum AcceptableContentType: AcceptableProtocol { + @frozen public enum AcceptableContentType: AcceptableProtocol { case json case other(Swift.String) - init?(rawValue: Swift.String) { + public init?(rawValue: Swift.String) { switch rawValue.lowercased() { case "application/json": self = .json @@ -5713,7 +5713,7 @@ enum Operations { } } - var rawValue: Swift.String { + public var rawValue: Swift.String { switch self { case let .other(string): string @@ -5722,7 +5722,7 @@ enum Operations { } } - static var allCases: [Self] { + public static var allCases: [Self] { [ .json ] @@ -5734,97 +5734,97 @@ enum Operations { /// /// - Remark: HTTP `GET /sitemaps/{sitemapname}`. /// - Remark: Generated from `#/paths//sitemaps/{sitemapname}/get(getSitemapByName)`. - enum getSitemapByName { - static let id: Swift.String = "getSitemapByName" - struct Input: Sendable, Hashable { + public enum getSitemapByName { + public static let id: Swift.String = "getSitemapByName" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// sitemap name /// /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/path/sitemapname`. - var sitemapname: Swift.String + public var sitemapname: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - sitemapname: sitemap name - init(sitemapname: Swift.String) { + public init(sitemapname: Swift.String) { self.sitemapname = sitemapname } } - var path: Operations.getSitemapByName.Input.Path + public var path: Operations.getSitemapByName.Input.Path /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/query`. - struct Query: Sendable, Hashable { + public struct Query: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/query/type`. - var _type: Swift.String? + public var _type: Swift.String? /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/query/jsoncallback`. - var jsoncallback: Swift.String? + public var jsoncallback: Swift.String? /// include hidden widgets /// /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/query/includeHidden`. - var includeHidden: Swift.Bool? + public var includeHidden: Swift.Bool? /// Creates a new `Query`. /// /// - Parameters: /// - _type: /// - jsoncallback: /// - includeHidden: include hidden widgets - init(_type: Swift.String? = nil, - jsoncallback: Swift.String? = nil, - includeHidden: Swift.Bool? = nil) { + public init(_type: Swift.String? = nil, + jsoncallback: Swift.String? = nil, + includeHidden: Swift.Bool? = nil) { self._type = _type self.jsoncallback = jsoncallback self.includeHidden = includeHidden } } - var query: Operations.getSitemapByName.Input.Query + public var query: Operations.getSitemapByName.Input.Query /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/header`. - struct Headers: Sendable, Hashable { + public struct Headers: Sendable, Hashable { /// language /// /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/header/Accept-Language`. - var Accept_hyphen_Language: Swift.String? - var accept: [OpenAPIRuntime.AcceptHeaderContentType] + public var Accept_hyphen_Language: Swift.String? + public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: /// - Accept_hyphen_Language: language /// - accept: - init(Accept_hyphen_Language: Swift.String? = nil, - accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + public init(Accept_hyphen_Language: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { self.Accept_hyphen_Language = Accept_hyphen_Language self.accept = accept } } - var headers: Operations.getSitemapByName.Input.Headers + public var headers: Operations.getSitemapByName.Input.Headers /// Creates a new `Input`. /// /// - Parameters: /// - path: /// - query: /// - headers: - init(path: Operations.getSitemapByName.Input.Path, - query: Operations.getSitemapByName.Input.Query = .init(), - headers: Operations.getSitemapByName.Input.Headers = .init()) { + public init(path: Operations.getSitemapByName.Input.Path, + query: Operations.getSitemapByName.Input.Query = .init(), + headers: Operations.getSitemapByName.Input.Headers = .init()) { self.path = path self.query = query self.headers = headers } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/responses/200/content`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/{sitemapname}/GET/responses/200/content/application\/json`. case json(Components.Schemas.SitemapDTO) /// The associated value of the enum case if `self` is `.json`. /// /// - Throws: An error if `self` is not `.json`. /// - SeeAlso: `.json`. - var json: Components.Schemas.SitemapDTO { + public var json: Components.Schemas.SitemapDTO { get throws { switch self { case let .json(body): @@ -5835,12 +5835,12 @@ enum Operations { } /// Received HTTP response body - var body: Operations.getSitemapByName.Output.Ok.Body + public var body: Operations.getSitemapByName.Output.Ok.Body /// Creates a new `Ok`. /// /// - Parameters: /// - body: Received HTTP response body - init(body: Operations.getSitemapByName.Output.Ok.Body) { + public init(body: Operations.getSitemapByName.Output.Ok.Body) { self.body = body } } @@ -5855,7 +5855,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.getSitemapByName.Output.Ok { + public var ok: Operations.getSitemapByName.Output.Ok { get throws { switch self { case let .ok(response): @@ -5875,10 +5875,10 @@ enum Operations { case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) } - enum AcceptableContentType: AcceptableProtocol { + @frozen public enum AcceptableContentType: AcceptableProtocol { case json case other(Swift.String) - init?(rawValue: Swift.String) { + public init?(rawValue: Swift.String) { switch rawValue.lowercased() { case "application/json": self = .json @@ -5887,7 +5887,7 @@ enum Operations { } } - var rawValue: Swift.String { + public var rawValue: Swift.String { switch self { case let .other(string): string @@ -5896,7 +5896,7 @@ enum Operations { } } - static var allCases: [Self] { + public static var allCases: [Self] { [ .json ] @@ -5908,57 +5908,57 @@ enum Operations { /// /// - Remark: HTTP `GET /sitemaps/events/{subscriptionid}/*`. /// - Remark: Generated from `#/paths//sitemaps/events/{subscriptionid}/*/get(getSitemapEvents)`. - enum getSitemapEvents { - static let id: Swift.String = "getSitemapEvents" - struct Input: Sendable, Hashable { + public enum getSitemapEvents { + public static let id: Swift.String = "getSitemapEvents" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/*/GET/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// subscription id /// /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/*/GET/path/subscriptionid`. - var subscriptionid: Swift.String + public var subscriptionid: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - subscriptionid: subscription id - init(subscriptionid: Swift.String) { + public init(subscriptionid: Swift.String) { self.subscriptionid = subscriptionid } } - var path: Operations.getSitemapEvents.Input.Path + public var path: Operations.getSitemapEvents.Input.Path /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/*/GET/query`. - struct Query: Sendable, Hashable { + public struct Query: Sendable, Hashable { /// sitemap name /// /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/*/GET/query/sitemap`. - var sitemap: Swift.String? + public var sitemap: Swift.String? /// Creates a new `Query`. /// /// - Parameters: /// - sitemap: sitemap name - init(sitemap: Swift.String? = nil) { + public init(sitemap: Swift.String? = nil) { self.sitemap = sitemap } } - var query: Operations.getSitemapEvents.Input.Query + public var query: Operations.getSitemapEvents.Input.Query /// Creates a new `Input`. /// /// - Parameters: /// - path: /// - query: - init(path: Operations.getSitemapEvents.Input.Path, - query: Operations.getSitemapEvents.Input.Query = .init()) { + public init(path: Operations.getSitemapEvents.Input.Path, + query: Operations.getSitemapEvents.Input.Query = .init()) { self.path = path self.query = query } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// Creates a new `Ok`. - init() {} + public init() {} } /// OK @@ -5971,7 +5971,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.getSitemapEvents.Output.Ok { + public var ok: Operations.getSitemapEvents.Output.Ok { get throws { switch self { case let .ok(response): @@ -5985,9 +5985,9 @@ enum Operations { } } - struct BadRequest: Sendable, Hashable { + public struct BadRequest: Sendable, Hashable { /// Creates a new `BadRequest`. - init() {} + public init() {} } /// Missing sitemap parameter, or sitemap not linked successfully to the subscription. @@ -6000,7 +6000,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.badRequest`. /// - SeeAlso: `.badRequest`. - var badRequest: Operations.getSitemapEvents.Output.BadRequest { + public var badRequest: Operations.getSitemapEvents.Output.BadRequest { get throws { switch self { case let .badRequest(response): @@ -6014,9 +6014,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Subscription not found. @@ -6029,7 +6029,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.getSitemapEvents.Output.NotFound { + public var notFound: Operations.getSitemapEvents.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -6054,87 +6054,87 @@ enum Operations { /// /// - Remark: HTTP `GET /sitemaps/events/{subscriptionid}`. /// - Remark: Generated from `#/paths//sitemaps/events/{subscriptionid}/get(getSitemapEvents_1)`. - enum getSitemapEvents_1 { - static let id: Swift.String = "getSitemapEvents_1" - struct Input: Sendable, Hashable { + public enum getSitemapEvents_1 { + public static let id: Swift.String = "getSitemapEvents_1" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/GET/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// subscription id /// /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/GET/path/subscriptionid`. - var subscriptionid: Swift.String + public var subscriptionid: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - subscriptionid: subscription id - init(subscriptionid: Swift.String) { + public init(subscriptionid: Swift.String) { self.subscriptionid = subscriptionid } } - var path: Operations.getSitemapEvents_1.Input.Path + public var path: Operations.getSitemapEvents_1.Input.Path /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/GET/query`. - struct Query: Sendable, Hashable { + public struct Query: Sendable, Hashable { /// sitemap name /// /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/GET/query/sitemap`. - var sitemap: Swift.String? + public var sitemap: Swift.String? /// page id /// /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/GET/query/pageid`. - var pageid: Swift.String? + public var pageid: Swift.String? /// Creates a new `Query`. /// /// - Parameters: /// - sitemap: sitemap name /// - pageid: page id - init(sitemap: Swift.String? = nil, - pageid: Swift.String? = nil) { + public init(sitemap: Swift.String? = nil, + pageid: Swift.String? = nil) { self.sitemap = sitemap self.pageid = pageid } } - var query: Operations.getSitemapEvents_1.Input.Query + public var query: Operations.getSitemapEvents_1.Input.Query /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/GET/header`. - struct Headers: Sendable, Hashable { - var accept: [OpenAPIRuntime.AcceptHeaderContentType] + public struct Headers: Sendable, Hashable { + public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: /// - accept: - init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + public init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { self.accept = accept } } - var headers: Operations.getSitemapEvents_1.Input.Headers + public var headers: Operations.getSitemapEvents_1.Input.Headers /// Creates a new `Input`. /// /// - Parameters: /// - path: /// - query: /// - headers: - init(path: Operations.getSitemapEvents_1.Input.Path, - query: Operations.getSitemapEvents_1.Input.Query = .init(), - headers: Operations.getSitemapEvents_1.Input.Headers = .init()) { + public init(path: Operations.getSitemapEvents_1.Input.Path, + query: Operations.getSitemapEvents_1.Input.Query = .init(), + headers: Operations.getSitemapEvents_1.Input.Headers = .init()) { self.path = path self.query = query self.headers = headers } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/GET/responses/200/content`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/events/{subscriptionid}/GET/responses/200/content/text\/event-stream`. case text_event_hyphen_stream(OpenAPIRuntime.HTTPBody) /// The associated value of the enum case if `self` is `.text_event_hyphen_stream`. /// /// - Throws: An error if `self` is not `.text_event_hyphen_stream`. /// - SeeAlso: `.text_event_hyphen_stream`. - var text_event_hyphen_stream: OpenAPIRuntime.HTTPBody { + public var text_event_hyphen_stream: OpenAPIRuntime.HTTPBody { get throws { switch self { case let .text_event_hyphen_stream(body): @@ -6154,7 +6154,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.json`. /// - SeeAlso: `.json`. - var json: Components.Schemas.SitemapWidgetEvent { + public var json: Components.Schemas.SitemapWidgetEvent { get throws { switch self { case let .json(body): @@ -6170,12 +6170,12 @@ enum Operations { } /// Received HTTP response body - var body: Operations.getSitemapEvents_1.Output.Ok.Body + public var body: Operations.getSitemapEvents_1.Output.Ok.Body /// Creates a new `Ok`. /// /// - Parameters: /// - body: Received HTTP response body - init(body: Operations.getSitemapEvents_1.Output.Ok.Body) { + public init(body: Operations.getSitemapEvents_1.Output.Ok.Body) { self.body = body } } @@ -6190,7 +6190,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.getSitemapEvents_1.Output.Ok { + public var ok: Operations.getSitemapEvents_1.Output.Ok { get throws { switch self { case let .ok(response): @@ -6204,9 +6204,9 @@ enum Operations { } } - struct BadRequest: Sendable, Hashable { + public struct BadRequest: Sendable, Hashable { /// Creates a new `BadRequest`. - init() {} + public init() {} } /// Missing sitemap or page parameter, or page not linked successfully to the subscription. @@ -6219,7 +6219,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.badRequest`. /// - SeeAlso: `.badRequest`. - var badRequest: Operations.getSitemapEvents_1.Output.BadRequest { + public var badRequest: Operations.getSitemapEvents_1.Output.BadRequest { get throws { switch self { case let .badRequest(response): @@ -6233,9 +6233,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Subscription not found. @@ -6248,7 +6248,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.getSitemapEvents_1.Output.NotFound { + public var notFound: Operations.getSitemapEvents_1.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -6268,11 +6268,11 @@ enum Operations { case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) } - enum AcceptableContentType: AcceptableProtocol { + @frozen public enum AcceptableContentType: AcceptableProtocol { case text_event_hyphen_stream case json case other(Swift.String) - init?(rawValue: Swift.String) { + public init?(rawValue: Swift.String) { switch rawValue.lowercased() { case "text/event-stream": self = .text_event_hyphen_stream @@ -6283,7 +6283,7 @@ enum Operations { } } - var rawValue: Swift.String { + public var rawValue: Swift.String { switch self { case let .other(string): string @@ -6294,7 +6294,7 @@ enum Operations { } } - static var allCases: [Self] { + public static var allCases: [Self] { [ .text_event_hyphen_stream, .json @@ -6307,42 +6307,42 @@ enum Operations { /// /// - Remark: HTTP `GET /sitemaps`. /// - Remark: Generated from `#/paths//sitemaps/get(getSitemaps)`. - enum getSitemaps { - static let id: Swift.String = "getSitemaps" - struct Input: Sendable, Hashable { + public enum getSitemaps { + public static let id: Swift.String = "getSitemaps" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/GET/header`. - struct Headers: Sendable, Hashable { - var accept: [OpenAPIRuntime.AcceptHeaderContentType] + public struct Headers: Sendable, Hashable { + public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: /// - accept: - init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + public init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { self.accept = accept } } - var headers: Operations.getSitemaps.Input.Headers + public var headers: Operations.getSitemaps.Input.Headers /// Creates a new `Input`. /// /// - Parameters: /// - headers: - init(headers: Operations.getSitemaps.Input.Headers = .init()) { + public init(headers: Operations.getSitemaps.Input.Headers = .init()) { self.headers = headers } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/GET/responses/200/content`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/sitemaps/GET/responses/200/content/application\/json`. case json([Components.Schemas.SitemapDTO]) /// The associated value of the enum case if `self` is `.json`. /// /// - Throws: An error if `self` is not `.json`. /// - SeeAlso: `.json`. - var json: [Components.Schemas.SitemapDTO] { + public var json: [Components.Schemas.SitemapDTO] { get throws { switch self { case let .json(body): @@ -6353,12 +6353,12 @@ enum Operations { } /// Received HTTP response body - var body: Operations.getSitemaps.Output.Ok.Body + public var body: Operations.getSitemaps.Output.Ok.Body /// Creates a new `Ok`. /// /// - Parameters: /// - body: Received HTTP response body - init(body: Operations.getSitemaps.Output.Ok.Body) { + public init(body: Operations.getSitemaps.Output.Ok.Body) { self.body = body } } @@ -6373,7 +6373,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.getSitemaps.Output.Ok { + public var ok: Operations.getSitemaps.Output.Ok { get throws { switch self { case let .ok(response): @@ -6393,10 +6393,10 @@ enum Operations { case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) } - enum AcceptableContentType: AcceptableProtocol { + @frozen public enum AcceptableContentType: AcceptableProtocol { case json case other(Swift.String) - init?(rawValue: Swift.String) { + public init?(rawValue: Swift.String) { switch rawValue.lowercased() { case "application/json": self = .json @@ -6405,7 +6405,7 @@ enum Operations { } } - var rawValue: Swift.String { + public var rawValue: Swift.String { switch self { case let .other(string): string @@ -6414,7 +6414,7 @@ enum Operations { } } - static var allCases: [Self] { + public static var allCases: [Self] { [ .json ] @@ -6426,78 +6426,78 @@ enum Operations { /// /// - Remark: HTTP `GET /ui/components/{namespace}`. /// - Remark: Generated from `#/paths//ui/components/{namespace}/get(getRegisteredUIComponentsInNamespace)`. - enum getRegisteredUIComponentsInNamespace { - static let id: Swift.String = "getRegisteredUIComponentsInNamespace" - struct Input: Sendable, Hashable { + public enum getRegisteredUIComponentsInNamespace { + public static let id: Swift.String = "getRegisteredUIComponentsInNamespace" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/GET/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/GET/path/namespace`. - var namespace: Swift.String + public var namespace: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - namespace: - init(namespace: Swift.String) { + public init(namespace: Swift.String) { self.namespace = namespace } } - var path: Operations.getRegisteredUIComponentsInNamespace.Input.Path + public var path: Operations.getRegisteredUIComponentsInNamespace.Input.Path /// - Remark: Generated from `#/paths/ui/components/{namespace}/GET/query`. - struct Query: Sendable, Hashable { + public struct Query: Sendable, Hashable { /// summary fields only /// /// - Remark: Generated from `#/paths/ui/components/{namespace}/GET/query/summary`. - var summary: Swift.Bool? + public var summary: Swift.Bool? /// Creates a new `Query`. /// /// - Parameters: /// - summary: summary fields only - init(summary: Swift.Bool? = nil) { + public init(summary: Swift.Bool? = nil) { self.summary = summary } } - var query: Operations.getRegisteredUIComponentsInNamespace.Input.Query + public var query: Operations.getRegisteredUIComponentsInNamespace.Input.Query /// - Remark: Generated from `#/paths/ui/components/{namespace}/GET/header`. - struct Headers: Sendable, Hashable { - var accept: [OpenAPIRuntime.AcceptHeaderContentType] + public struct Headers: Sendable, Hashable { + public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: /// - accept: - init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + public init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { self.accept = accept } } - var headers: Operations.getRegisteredUIComponentsInNamespace.Input.Headers + public var headers: Operations.getRegisteredUIComponentsInNamespace.Input.Headers /// Creates a new `Input`. /// /// - Parameters: /// - path: /// - query: /// - headers: - init(path: Operations.getRegisteredUIComponentsInNamespace.Input.Path, - query: Operations.getRegisteredUIComponentsInNamespace.Input.Query = .init(), - headers: Operations.getRegisteredUIComponentsInNamespace.Input.Headers = .init()) { + public init(path: Operations.getRegisteredUIComponentsInNamespace.Input.Path, + query: Operations.getRegisteredUIComponentsInNamespace.Input.Query = .init(), + headers: Operations.getRegisteredUIComponentsInNamespace.Input.Headers = .init()) { self.path = path self.query = query self.headers = headers } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/GET/responses/200/content`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/GET/responses/200/content/application\/json`. case json([Components.Schemas.RootUIComponent]) /// The associated value of the enum case if `self` is `.json`. /// /// - Throws: An error if `self` is not `.json`. /// - SeeAlso: `.json`. - var json: [Components.Schemas.RootUIComponent] { + public var json: [Components.Schemas.RootUIComponent] { get throws { switch self { case let .json(body): @@ -6508,12 +6508,12 @@ enum Operations { } /// Received HTTP response body - var body: Operations.getRegisteredUIComponentsInNamespace.Output.Ok.Body + public var body: Operations.getRegisteredUIComponentsInNamespace.Output.Ok.Body /// Creates a new `Ok`. /// /// - Parameters: /// - body: Received HTTP response body - init(body: Operations.getRegisteredUIComponentsInNamespace.Output.Ok.Body) { + public init(body: Operations.getRegisteredUIComponentsInNamespace.Output.Ok.Body) { self.body = body } } @@ -6528,7 +6528,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.getRegisteredUIComponentsInNamespace.Output.Ok { + public var ok: Operations.getRegisteredUIComponentsInNamespace.Output.Ok { get throws { switch self { case let .ok(response): @@ -6548,10 +6548,10 @@ enum Operations { case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) } - enum AcceptableContentType: AcceptableProtocol { + @frozen public enum AcceptableContentType: AcceptableProtocol { case json case other(Swift.String) - init?(rawValue: Swift.String) { + public init?(rawValue: Swift.String) { switch rawValue.lowercased() { case "application/json": self = .json @@ -6560,7 +6560,7 @@ enum Operations { } } - var rawValue: Swift.String { + public var rawValue: Swift.String { switch self { case let .other(string): string @@ -6569,7 +6569,7 @@ enum Operations { } } - static var allCases: [Self] { + public static var allCases: [Self] { [ .json ] @@ -6581,69 +6581,69 @@ enum Operations { /// /// - Remark: HTTP `POST /ui/components/{namespace}`. /// - Remark: Generated from `#/paths//ui/components/{namespace}/post(addUIComponentToNamespace)`. - enum addUIComponentToNamespace { - static let id: Swift.String = "addUIComponentToNamespace" - struct Input: Sendable, Hashable { + public enum addUIComponentToNamespace { + public static let id: Swift.String = "addUIComponentToNamespace" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/POST/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/POST/path/namespace`. - var namespace: Swift.String + public var namespace: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - namespace: - init(namespace: Swift.String) { + public init(namespace: Swift.String) { self.namespace = namespace } } - var path: Operations.addUIComponentToNamespace.Input.Path + public var path: Operations.addUIComponentToNamespace.Input.Path /// - Remark: Generated from `#/paths/ui/components/{namespace}/POST/header`. - struct Headers: Sendable, Hashable { - var accept: [OpenAPIRuntime.AcceptHeaderContentType] + public struct Headers: Sendable, Hashable { + public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: /// - accept: - init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + public init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { self.accept = accept } } - var headers: Operations.addUIComponentToNamespace.Input.Headers + public var headers: Operations.addUIComponentToNamespace.Input.Headers /// - Remark: Generated from `#/paths/ui/components/{namespace}/POST/requestBody`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/POST/requestBody/content/application\/json`. case json(Components.Schemas.RootUIComponent) } - var body: Operations.addUIComponentToNamespace.Input.Body? + public var body: Operations.addUIComponentToNamespace.Input.Body? /// Creates a new `Input`. /// /// - Parameters: /// - path: /// - headers: /// - body: - init(path: Operations.addUIComponentToNamespace.Input.Path, - headers: Operations.addUIComponentToNamespace.Input.Headers = .init(), - body: Operations.addUIComponentToNamespace.Input.Body? = nil) { + public init(path: Operations.addUIComponentToNamespace.Input.Path, + headers: Operations.addUIComponentToNamespace.Input.Headers = .init(), + body: Operations.addUIComponentToNamespace.Input.Body? = nil) { self.path = path self.headers = headers self.body = body } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/POST/responses/200/content`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/POST/responses/200/content/application\/json`. case json(Components.Schemas.RootUIComponent) /// The associated value of the enum case if `self` is `.json`. /// /// - Throws: An error if `self` is not `.json`. /// - SeeAlso: `.json`. - var json: Components.Schemas.RootUIComponent { + public var json: Components.Schemas.RootUIComponent { get throws { switch self { case let .json(body): @@ -6654,12 +6654,12 @@ enum Operations { } /// Received HTTP response body - var body: Operations.addUIComponentToNamespace.Output.Ok.Body + public var body: Operations.addUIComponentToNamespace.Output.Ok.Body /// Creates a new `Ok`. /// /// - Parameters: /// - body: Received HTTP response body - init(body: Operations.addUIComponentToNamespace.Output.Ok.Body) { + public init(body: Operations.addUIComponentToNamespace.Output.Ok.Body) { self.body = body } } @@ -6674,7 +6674,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.addUIComponentToNamespace.Output.Ok { + public var ok: Operations.addUIComponentToNamespace.Output.Ok { get throws { switch self { case let .ok(response): @@ -6694,10 +6694,10 @@ enum Operations { case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) } - enum AcceptableContentType: AcceptableProtocol { + @frozen public enum AcceptableContentType: AcceptableProtocol { case json case other(Swift.String) - init?(rawValue: Swift.String) { + public init?(rawValue: Swift.String) { switch rawValue.lowercased() { case "application/json": self = .json @@ -6706,7 +6706,7 @@ enum Operations { } } - var rawValue: Swift.String { + public var rawValue: Swift.String { switch self { case let .other(string): string @@ -6715,7 +6715,7 @@ enum Operations { } } - static var allCases: [Self] { + public static var allCases: [Self] { [ .json ] @@ -6727,64 +6727,64 @@ enum Operations { /// /// - Remark: HTTP `GET /ui/components/{namespace}/{componentUID}`. /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/get(getUIComponentInNamespace)`. - enum getUIComponentInNamespace { - static let id: Swift.String = "getUIComponentInNamespace" - struct Input: Sendable, Hashable { + public enum getUIComponentInNamespace { + public static let id: Swift.String = "getUIComponentInNamespace" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/GET/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/GET/path/namespace`. - var namespace: Swift.String + public var namespace: Swift.String /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/GET/path/componentUID`. - var componentUID: Swift.String + public var componentUID: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - namespace: /// - componentUID: - init(namespace: Swift.String, - componentUID: Swift.String) { + public init(namespace: Swift.String, + componentUID: Swift.String) { self.namespace = namespace self.componentUID = componentUID } } - var path: Operations.getUIComponentInNamespace.Input.Path + public var path: Operations.getUIComponentInNamespace.Input.Path /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/GET/header`. - struct Headers: Sendable, Hashable { - var accept: [OpenAPIRuntime.AcceptHeaderContentType] + public struct Headers: Sendable, Hashable { + public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: /// - accept: - init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + public init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { self.accept = accept } } - var headers: Operations.getUIComponentInNamespace.Input.Headers + public var headers: Operations.getUIComponentInNamespace.Input.Headers /// Creates a new `Input`. /// /// - Parameters: /// - path: /// - headers: - init(path: Operations.getUIComponentInNamespace.Input.Path, - headers: Operations.getUIComponentInNamespace.Input.Headers = .init()) { + public init(path: Operations.getUIComponentInNamespace.Input.Path, + headers: Operations.getUIComponentInNamespace.Input.Headers = .init()) { self.path = path self.headers = headers } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/GET/responses/200/content`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/GET/responses/200/content/application\/json`. case json(Components.Schemas.RootUIComponent) /// The associated value of the enum case if `self` is `.json`. /// /// - Throws: An error if `self` is not `.json`. /// - SeeAlso: `.json`. - var json: Components.Schemas.RootUIComponent { + public var json: Components.Schemas.RootUIComponent { get throws { switch self { case let .json(body): @@ -6795,12 +6795,12 @@ enum Operations { } /// Received HTTP response body - var body: Operations.getUIComponentInNamespace.Output.Ok.Body + public var body: Operations.getUIComponentInNamespace.Output.Ok.Body /// Creates a new `Ok`. /// /// - Parameters: /// - body: Received HTTP response body - init(body: Operations.getUIComponentInNamespace.Output.Ok.Body) { + public init(body: Operations.getUIComponentInNamespace.Output.Ok.Body) { self.body = body } } @@ -6815,7 +6815,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.getUIComponentInNamespace.Output.Ok { + public var ok: Operations.getUIComponentInNamespace.Output.Ok { get throws { switch self { case let .ok(response): @@ -6829,9 +6829,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Component not found @@ -6844,7 +6844,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.getUIComponentInNamespace.Output.NotFound { + public var notFound: Operations.getUIComponentInNamespace.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -6864,10 +6864,10 @@ enum Operations { case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) } - enum AcceptableContentType: AcceptableProtocol { + @frozen public enum AcceptableContentType: AcceptableProtocol { case json case other(Swift.String) - init?(rawValue: Swift.String) { + public init?(rawValue: Swift.String) { switch rawValue.lowercased() { case "application/json": self = .json @@ -6876,7 +6876,7 @@ enum Operations { } } - var rawValue: Swift.String { + public var rawValue: Swift.String { switch self { case let .other(string): string @@ -6885,7 +6885,7 @@ enum Operations { } } - static var allCases: [Self] { + public static var allCases: [Self] { [ .json ] @@ -6897,74 +6897,74 @@ enum Operations { /// /// - Remark: HTTP `PUT /ui/components/{namespace}/{componentUID}`. /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/put(updateUIComponentInNamespace)`. - enum updateUIComponentInNamespace { - static let id: Swift.String = "updateUIComponentInNamespace" - struct Input: Sendable, Hashable { + public enum updateUIComponentInNamespace { + public static let id: Swift.String = "updateUIComponentInNamespace" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/PUT/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/PUT/path/namespace`. - var namespace: Swift.String + public var namespace: Swift.String /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/PUT/path/componentUID`. - var componentUID: Swift.String + public var componentUID: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - namespace: /// - componentUID: - init(namespace: Swift.String, - componentUID: Swift.String) { + public init(namespace: Swift.String, + componentUID: Swift.String) { self.namespace = namespace self.componentUID = componentUID } } - var path: Operations.updateUIComponentInNamespace.Input.Path + public var path: Operations.updateUIComponentInNamespace.Input.Path /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/PUT/header`. - struct Headers: Sendable, Hashable { - var accept: [OpenAPIRuntime.AcceptHeaderContentType] + public struct Headers: Sendable, Hashable { + public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: /// - accept: - init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + public init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { self.accept = accept } } - var headers: Operations.updateUIComponentInNamespace.Input.Headers + public var headers: Operations.updateUIComponentInNamespace.Input.Headers /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/PUT/requestBody`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/PUT/requestBody/content/application\/json`. case json(Components.Schemas.RootUIComponent) } - var body: Operations.updateUIComponentInNamespace.Input.Body? + public var body: Operations.updateUIComponentInNamespace.Input.Body? /// Creates a new `Input`. /// /// - Parameters: /// - path: /// - headers: /// - body: - init(path: Operations.updateUIComponentInNamespace.Input.Path, - headers: Operations.updateUIComponentInNamespace.Input.Headers = .init(), - body: Operations.updateUIComponentInNamespace.Input.Body? = nil) { + public init(path: Operations.updateUIComponentInNamespace.Input.Path, + headers: Operations.updateUIComponentInNamespace.Input.Headers = .init(), + body: Operations.updateUIComponentInNamespace.Input.Body? = nil) { self.path = path self.headers = headers self.body = body } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/PUT/responses/200/content`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/PUT/responses/200/content/application\/json`. case json(Components.Schemas.RootUIComponent) /// The associated value of the enum case if `self` is `.json`. /// /// - Throws: An error if `self` is not `.json`. /// - SeeAlso: `.json`. - var json: Components.Schemas.RootUIComponent { + public var json: Components.Schemas.RootUIComponent { get throws { switch self { case let .json(body): @@ -6975,12 +6975,12 @@ enum Operations { } /// Received HTTP response body - var body: Operations.updateUIComponentInNamespace.Output.Ok.Body + public var body: Operations.updateUIComponentInNamespace.Output.Ok.Body /// Creates a new `Ok`. /// /// - Parameters: /// - body: Received HTTP response body - init(body: Operations.updateUIComponentInNamespace.Output.Ok.Body) { + public init(body: Operations.updateUIComponentInNamespace.Output.Ok.Body) { self.body = body } } @@ -6995,7 +6995,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.updateUIComponentInNamespace.Output.Ok { + public var ok: Operations.updateUIComponentInNamespace.Output.Ok { get throws { switch self { case let .ok(response): @@ -7009,9 +7009,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Component not found @@ -7024,7 +7024,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.updateUIComponentInNamespace.Output.NotFound { + public var notFound: Operations.updateUIComponentInNamespace.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -7044,10 +7044,10 @@ enum Operations { case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) } - enum AcceptableContentType: AcceptableProtocol { + @frozen public enum AcceptableContentType: AcceptableProtocol { case json case other(Swift.String) - init?(rawValue: Swift.String) { + public init?(rawValue: Swift.String) { switch rawValue.lowercased() { case "application/json": self = .json @@ -7056,7 +7056,7 @@ enum Operations { } } - var rawValue: Swift.String { + public var rawValue: Swift.String { switch self { case let .other(string): string @@ -7065,7 +7065,7 @@ enum Operations { } } - static var allCases: [Self] { + public static var allCases: [Self] { [ .json ] @@ -7077,41 +7077,41 @@ enum Operations { /// /// - Remark: HTTP `DELETE /ui/components/{namespace}/{componentUID}`. /// - Remark: Generated from `#/paths//ui/components/{namespace}/{componentUID}/delete(removeUIComponentFromNamespace)`. - enum removeUIComponentFromNamespace { - static let id: Swift.String = "removeUIComponentFromNamespace" - struct Input: Sendable, Hashable { + public enum removeUIComponentFromNamespace { + public static let id: Swift.String = "removeUIComponentFromNamespace" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/DELETE/path`. - struct Path: Sendable, Hashable { + public struct Path: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/DELETE/path/namespace`. - var namespace: Swift.String + public var namespace: Swift.String /// - Remark: Generated from `#/paths/ui/components/{namespace}/{componentUID}/DELETE/path/componentUID`. - var componentUID: Swift.String + public var componentUID: Swift.String /// Creates a new `Path`. /// /// - Parameters: /// - namespace: /// - componentUID: - init(namespace: Swift.String, - componentUID: Swift.String) { + public init(namespace: Swift.String, + componentUID: Swift.String) { self.namespace = namespace self.componentUID = componentUID } } - var path: Operations.removeUIComponentFromNamespace.Input.Path + public var path: Operations.removeUIComponentFromNamespace.Input.Path /// Creates a new `Input`. /// /// - Parameters: /// - path: - init(path: Operations.removeUIComponentFromNamespace.Input.Path) { + public init(path: Operations.removeUIComponentFromNamespace.Input.Path) { self.path = path } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// Creates a new `Ok`. - init() {} + public init() {} } /// OK @@ -7124,7 +7124,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.removeUIComponentFromNamespace.Output.Ok { + public var ok: Operations.removeUIComponentFromNamespace.Output.Ok { get throws { switch self { case let .ok(response): @@ -7138,9 +7138,9 @@ enum Operations { } } - struct NotFound: Sendable, Hashable { + public struct NotFound: Sendable, Hashable { /// Creates a new `NotFound`. - init() {} + public init() {} } /// Component not found @@ -7153,7 +7153,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.notFound`. /// - SeeAlso: `.notFound`. - var notFound: Operations.removeUIComponentFromNamespace.Output.NotFound { + public var notFound: Operations.removeUIComponentFromNamespace.Output.NotFound { get throws { switch self { case let .notFound(response): @@ -7178,42 +7178,42 @@ enum Operations { /// /// - Remark: HTTP `GET /ui/tiles`. /// - Remark: Generated from `#/paths//ui/tiles/get(getUITiles)`. - enum getUITiles { - static let id: Swift.String = "getUITiles" - struct Input: Sendable, Hashable { + public enum getUITiles { + public static let id: Swift.String = "getUITiles" + public struct Input: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/tiles/GET/header`. - struct Headers: Sendable, Hashable { - var accept: [OpenAPIRuntime.AcceptHeaderContentType] + public struct Headers: Sendable, Hashable { + public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: /// - accept: - init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + public init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { self.accept = accept } } - var headers: Operations.getUITiles.Input.Headers + public var headers: Operations.getUITiles.Input.Headers /// Creates a new `Input`. /// /// - Parameters: /// - headers: - init(headers: Operations.getUITiles.Input.Headers = .init()) { + public init(headers: Operations.getUITiles.Input.Headers = .init()) { self.headers = headers } } - enum Output: Sendable, Hashable { - struct Ok: Sendable, Hashable { + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/tiles/GET/responses/200/content`. - enum Body: Sendable, Hashable { + @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/ui/tiles/GET/responses/200/content/application\/json`. case json([Components.Schemas.TileDTO]) /// The associated value of the enum case if `self` is `.json`. /// /// - Throws: An error if `self` is not `.json`. /// - SeeAlso: `.json`. - var json: [Components.Schemas.TileDTO] { + public var json: [Components.Schemas.TileDTO] { get throws { switch self { case let .json(body): @@ -7224,12 +7224,12 @@ enum Operations { } /// Received HTTP response body - var body: Operations.getUITiles.Output.Ok.Body + public var body: Operations.getUITiles.Output.Ok.Body /// Creates a new `Ok`. /// /// - Parameters: /// - body: Received HTTP response body - init(body: Operations.getUITiles.Output.Ok.Body) { + public init(body: Operations.getUITiles.Output.Ok.Body) { self.body = body } } @@ -7244,7 +7244,7 @@ enum Operations { /// /// - Throws: An error if `self` is not `.ok`. /// - SeeAlso: `.ok`. - var ok: Operations.getUITiles.Output.Ok { + public var ok: Operations.getUITiles.Output.Ok { get throws { switch self { case let .ok(response): @@ -7264,10 +7264,10 @@ enum Operations { case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) } - enum AcceptableContentType: AcceptableProtocol { + @frozen public enum AcceptableContentType: AcceptableProtocol { case json case other(Swift.String) - init?(rawValue: Swift.String) { + public init?(rawValue: Swift.String) { switch rawValue.lowercased() { case "application/json": self = .json @@ -7276,7 +7276,7 @@ enum Operations { } } - var rawValue: Swift.String { + public var rawValue: Swift.String { switch self { case let .other(string): string @@ -7285,7 +7285,7 @@ enum Operations { } } - static var allCases: [Self] { + public static var allCases: [Self] { [ .json ] diff --git a/OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift b/OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift index 0083c97b..d292058a 100644 --- a/OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift +++ b/OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift @@ -130,16 +130,14 @@ public extension APIActor { return URL(string: urlString)?.lastPathComponent } - func openHABSitemapWidgetEvents(subscriptionid: String, sitemap: String) async throws -> AsyncThrowingCompactMapSequence>, OpenHABSitemapWidgetEvent> { + // Will need swift 6.0 SE-0421 to return an opaque sequence + func openHABSitemapWidgetEvents(subscriptionid: String, sitemap: String) async throws -> AsyncCompactMapSequence>, ServerSentEventWithJSONData>, OpenHABSitemapWidgetEvent> { let path = Operations.getSitemapEvents_1.Input.Path(subscriptionid: subscriptionid) let query = Operations.getSitemapEvents_1.Input.Query(sitemap: sitemap, pageid: sitemap) - let decodedSequence = try await api.getSitemapEvents_1(path: path, query: query).ok.body.text_event_hyphen_stream.asDecodedServerSentEvents() - let opaqueSequence = decodedSequence.compactMap { (event) in - if let data = event.data { - try JSONDecoder().decode(OpenHABSitemapWidgetEvent.CodingData.self, from: Data(data.utf8)).openHABSitemapWidgetEvent - } else { nil } - } - return opaqueSequence + let decodedSequence = try await api.getSitemapEvents_1(path: path, query: query) + .ok.body.text_event_hyphen_stream + .asDecodedServerSentEventsWithJSONData(of: Components.Schemas.SitemapWidgetEvent.self) + return decodedSequence.compactMap { OpenHABSitemapWidgetEvent($0.data) } } } diff --git a/OpenHABCore/Sources/OpenHABCore/openapi/openapi-generator-config.yml b/OpenHABCore/Sources/OpenHABCore/openapi/openapi-generator-config.yml index 3a3188b2..4d0407ff 100644 --- a/OpenHABCore/Sources/OpenHABCore/openapi/openapi-generator-config.yml +++ b/OpenHABCore/Sources/OpenHABCore/openapi/openapi-generator-config.yml @@ -1,7 +1,7 @@ generate: - types - client -accessModifier: internal +accessModifier: public filter: tags: - sitemaps diff --git a/openHAB/OpenHABSitemapViewController.swift b/openHAB/OpenHABSitemapViewController.swift index 0056255a..10ad666c 100644 --- a/openHAB/OpenHABSitemapViewController.swift +++ b/openHAB/OpenHABSitemapViewController.swift @@ -338,6 +338,7 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel if let subscriptionid = try await apiactor.openHABcreateSubscription() { logger.log("Got subscriptionid: \(subscriptionid)") let sitemap = try await apiactor.openHABpollSitemap(sitemapname: defaultSitemap, longPolling: longPolling, subscriptionId: subscriptionid) + currentPage = sitemap?.page let events = try await apiactor.openHABSitemapWidgetEvents(subscriptionid: subscriptionid, sitemap: defaultSitemap) for try await event in events { print(event) From c07b57e395f83d78661af6311dc5dcf6765bee4a Mon Sep 17 00:00:00 2001 From: Tim Bert <5411131+timbms@users.noreply.github.com> Date: Sun, 15 Sep 2024 15:53:08 +0200 Subject: [PATCH 08/13] Move extensions for models from APIActor.swift to respective files Port api load to DrawerView --- .../OpenHABCore/Model/CGFloatExtension.swift | 24 ++ .../Model/OpenHABCommandDescription.swift | 10 + .../Model/OpenHABCommandOptions.swift | 10 + .../OpenHABCore/Model/OpenHABItem.swift | 13 +- .../OpenHABCore/Model/OpenHABOptions.swift | 10 + .../OpenHABCore/Model/OpenHABPage.swift | 17 + .../OpenHABCore/Model/OpenHABSitemap.swift | 44 +-- .../Model/OpenHABSitemapWidgetEvent.swift | 93 ++++++ .../Model/OpenHABStateDescription.swift | 10 + .../OpenHABCore/Model/OpenHABUiTile.swift | 10 +- .../OpenHABCore/Model/OpenHABWidget.swift | 53 +++ .../Model/OpenHABWidgetMapping.swift | 6 + .../Sources/OpenHABCore/Util/APIActor.swift | 301 +----------------- .../OpenHABCore/Util/APIActorDelegate.swift | 76 +++++ openHAB/DrawerView.swift | 98 ++---- 15 files changed, 353 insertions(+), 422 deletions(-) create mode 100644 OpenHABCore/Sources/OpenHABCore/Model/CGFloatExtension.swift create mode 100644 OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemapWidgetEvent.swift create mode 100644 OpenHABCore/Sources/OpenHABCore/Util/APIActorDelegate.swift diff --git a/OpenHABCore/Sources/OpenHABCore/Model/CGFloatExtension.swift b/OpenHABCore/Sources/OpenHABCore/Model/CGFloatExtension.swift new file mode 100644 index 00000000..97d44787 --- /dev/null +++ b/OpenHABCore/Sources/OpenHABCore/Model/CGFloatExtension.swift @@ -0,0 +1,24 @@ +// Copyright (c) 2010-2024 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation + +extension CGFloat { + init(state string: String, divisor: Float) { + let numberFormatter = NumberFormatter() + numberFormatter.locale = Locale(identifier: "US") + if let number = numberFormatter.number(from: string) { + self.init(number.floatValue / divisor) + } else { + self.init(0) + } + } +} diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABCommandDescription.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABCommandDescription.swift index ce8eff96..1b96cb5f 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABCommandDescription.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABCommandDescription.swift @@ -30,3 +30,13 @@ extension OpenHABCommandDescription.CodingData { OpenHABCommandDescription(commandOptions: commandOptions) } } + +extension OpenHABCommandDescription { + convenience init?(_ commands: Components.Schemas.CommandDescription?) { + if let commands { + self.init(commandOptions: commands.commandOptions?.compactMap { OpenHABCommandOptions($0) }) + } else { + return nil + } + } +} diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABCommandOptions.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABCommandOptions.swift index 3ace621a..383a1a75 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABCommandOptions.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABCommandOptions.swift @@ -20,3 +20,13 @@ public class OpenHABCommandOptions: Decodable { self.label = label } } + +extension OpenHABCommandOptions { + convenience init?(_ options: Components.Schemas.CommandOption?) { + if let options { + self.init(command: options.command.orEmpty, label: options.label.orEmpty) + } else { + return nil + } + } +} diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABItem.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABItem.swift index 175f4ef6..7da0e102 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABItem.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABItem.swift @@ -148,14 +148,13 @@ public extension OpenHABItem.CodingData { } } -extension CGFloat { - init(state string: String, divisor: Float) { - let numberFormatter = NumberFormatter() - numberFormatter.locale = Locale(identifier: "US") - if let number = numberFormatter.number(from: string) { - self.init(number.floatValue / divisor) +extension OpenHABItem { + convenience init?(_ item: Components.Schemas.EnrichedItemDTO?) { + if let item { + // swiftlint:disable:next line_length + self.init(name: item.name.orEmpty, type: item._type.orEmpty, state: item.state.orEmpty, link: item.link.orEmpty, label: item.label.orEmpty, groupType: nil, stateDescription: OpenHABStateDescription(item.stateDescription), commandDescription: OpenHABCommandDescription(item.commandDescription), members: [], category: item.category, options: []) } else { - self.init(0) + return nil } } } diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABOptions.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABOptions.swift index d9a9983e..620a8458 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABOptions.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABOptions.swift @@ -20,3 +20,13 @@ public class OpenHABOptions: Decodable { self.label = label } } + +extension OpenHABOptions { + convenience init?(_ options: Components.Schemas.StateOption?) { + if let options { + self.init(value: options.value.orEmpty, label: options.label.orEmpty) + } else { + return nil + } + } +} diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABPage.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABPage.swift index 0c9632df..27b2c8fd 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABPage.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABPage.swift @@ -86,3 +86,20 @@ public extension OpenHABPage.CodingData { return OpenHABPage(pageId: pageId.orEmpty, title: title.orEmpty, link: link.orEmpty, leaf: leaf ?? false, widgets: mappedWidgets, icon: icon.orEmpty) } } + +extension OpenHABPage { + convenience init?(_ page: Components.Schemas.PageDTO?) { + if let page { + self.init( + pageId: page.id.orEmpty, + title: page.title.orEmpty, + link: page.link.orEmpty, + leaf: page.leaf ?? false, + widgets: page.widgets?.compactMap { OpenHABWidget($0) } ?? [], + icon: page.icon.orEmpty + ) + } else { + return nil + } + } +} diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemap.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemap.swift index 00a03e86..8f654bcd 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemap.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemap.swift @@ -51,42 +51,14 @@ public final class OpenHABSitemap: NSObject { } } -public extension OpenHABSitemap { - struct CodingData: Decodable { - public let name: String - public let label: String - public let page: OpenHABPage.CodingData? - public let link: String - public let icon: String? - - private enum CodingKeys: String, CodingKey { - case page = "homepage" - case name - case label - case link - case icon - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - - name = try container.decode(forKey: .name) - label = try container.decode(forKey: .label, default: name) - page = try container.decode(forKey: .page) - link = try container.decode(forKey: .link) - icon = try container.decodeIfPresent(forKey: .icon) - } - } -} - -public extension OpenHABSitemap.CodingData { - var openHABSitemap: OpenHABSitemap { - OpenHABSitemap( - name: name, - icon: icon.orEmpty, - label: label, - link: link, - page: page?.openHABSitemapPage +extension OpenHABSitemap { + convenience init(_ sitemap: Components.Schemas.SitemapDTO) { + self.init( + name: sitemap.name.orEmpty, + icon: sitemap.icon.orEmpty, + label: sitemap.label.orEmpty, + link: sitemap.link.orEmpty, + page: OpenHABPage(sitemap.homepage) ) } } diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemapWidgetEvent.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemapWidgetEvent.swift new file mode 100644 index 00000000..22447103 --- /dev/null +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABSitemapWidgetEvent.swift @@ -0,0 +1,93 @@ +// Copyright (c) 2010-2024 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation + +public class OpenHABSitemapWidgetEvent { + var sitemapName: String? + var pageId: String? + var widgetId: String? + var label: String? + var labelSource: String? + var icon: String? + var reloadIcon: Bool? + var labelcolor: String? + var valuecolor: String? + var iconcolor: String? + var visibility: Bool? + var state: String? + var enrichedItem: OpenHABItem? + var descriptionChanged: Bool? + + init(sitemapName: String? = nil, pageId: String? = nil, widgetId: String? = nil, label: String? = nil, labelSource: String? = nil, icon: String? = nil, reloadIcon: Bool? = nil, labelcolor: String? = nil, valuecolor: String? = nil, iconcolor: String? = nil, visibility: Bool? = nil, state: String? = nil, enrichedItem: OpenHABItem? = nil, descriptionChanged: Bool? = nil) { + self.sitemapName = sitemapName + self.pageId = pageId + self.widgetId = widgetId + self.label = label + self.labelSource = labelSource + self.icon = icon + self.reloadIcon = reloadIcon + self.labelcolor = labelcolor + self.valuecolor = valuecolor + self.iconcolor = iconcolor + self.visibility = visibility + self.state = state + self.enrichedItem = enrichedItem + self.descriptionChanged = descriptionChanged + } + + convenience init?(_ event: Components.Schemas.SitemapWidgetEvent?) { + guard let event else { return nil } + // swiftlint:disable:next line_length + self.init(sitemapName: event.sitemapName, pageId: event.pageId, widgetId: event.widgetId, label: event.label, labelSource: event.labelSource, icon: event.icon, reloadIcon: event.reloadIcon, labelcolor: event.labelcolor, valuecolor: event.valuecolor, iconcolor: event.iconcolor, visibility: event.visibility, state: event.state, enrichedItem: OpenHABItem(event.item), descriptionChanged: event.descriptionChanged) + } +} + +extension OpenHABSitemapWidgetEvent: CustomStringConvertible { + public var description: String { + "\(widgetId ?? "") \(label ?? "") \(enrichedItem?.state ?? "")" + } +} + +public extension OpenHABSitemapWidgetEvent { + struct CodingData: Decodable, Hashable, Equatable { + public static func == (lhs: OpenHABSitemapWidgetEvent.CodingData, rhs: OpenHABSitemapWidgetEvent.CodingData) -> Bool { + lhs.widgetId == rhs.widgetId + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(widgetId) + } + + var sitemapName: String? + var pageId: String? + var widgetId: String? + var label: String? + var labelSource: String? + var icon: String? + var reloadIcon: Bool? + var labelcolor: String? + var valuecolor: String? + var iconcolor: String? + var visibility: Bool? +// var state: String? + var item: OpenHABItem.CodingData? + var descriptionChanged: Bool? + var link: String? + } +} + +extension OpenHABSitemapWidgetEvent.CodingData { + var openHABSitemapWidgetEvent: OpenHABSitemapWidgetEvent { + // swiftlint:disable:next line_length + OpenHABSitemapWidgetEvent(sitemapName: sitemapName, pageId: pageId, widgetId: widgetId, label: label, labelSource: labelSource, icon: icon, reloadIcon: reloadIcon, labelcolor: labelcolor, valuecolor: valuecolor, iconcolor: iconcolor, visibility: visibility, enrichedItem: item?.openHABItem, descriptionChanged: descriptionChanged) + } +} diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABStateDescription.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABStateDescription.swift index 439812c8..9e17b3c9 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABStateDescription.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABStateDescription.swift @@ -59,3 +59,13 @@ extension OpenHABStateDescription.CodingData { OpenHABStateDescription(minimum: minimum, maximum: maximum, step: step, readOnly: readOnly, options: options, pattern: pattern) } } + +extension OpenHABStateDescription { + convenience init?(_ state: Components.Schemas.StateDescription?) { + if let state { + self.init(minimum: state.minimum, maximum: state.maximum, step: state.step, readOnly: state.readOnly, options: state.options?.compactMap { OpenHABOptions($0) }, pattern: state.pattern) + } else { + return nil + } + } +} diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABUiTile.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABUiTile.swift index ffac41ee..06705597 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABUiTile.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABUiTile.swift @@ -11,7 +11,7 @@ import Foundation -public class OpenHABUiTile: Decodable { +public class OpenHABUiTile { public var name = "" public var url = "" public var imageUrl = "" @@ -23,10 +23,8 @@ public class OpenHABUiTile: Decodable { } } -public extension OpenHABUiTile { - struct CodingData: Decodable { - public let name: String - public let url: String - public let imageUrl: String +extension OpenHABUiTile { + convenience init(_ tile: Components.Schemas.TileDTO) { + self.init(name: tile.name.orEmpty, url: tile.url.orEmpty, imageUrl: tile.imageUrl.orEmpty) } } diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidget.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidget.swift index a7c4dc84..8e5afd05 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidget.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidget.swift @@ -305,3 +305,56 @@ extension [OpenHABWidget] { } } } + +extension OpenHABWidget { + convenience init(_ widget: Components.Schemas.WidgetDTO) { + self.init( + widgetId: widget.widgetId.orEmpty, + label: widget.label.orEmpty, + icon: widget.icon.orEmpty, + type: OpenHABWidget.WidgetType(rawValue: widget._type!), + url: widget.url, + period: widget.period, + minValue: widget.minValue, + maxValue: widget.maxValue, + step: widget.step, + refresh: widget.refresh.map(Int.init), + height: 50, // TODO: + isLeaf: true, + iconColor: widget.iconcolor, + labelColor: widget.labelcolor, + valueColor: widget.valuecolor, + service: widget.service, + state: widget.state, + text: "", + legend: widget.legend, + encoding: widget.encoding, + item: OpenHABItem(widget.item), + linkedPage: OpenHABPage(widget.linkedPage), + mappings: widget.mappings?.compactMap(OpenHABWidgetMapping.init) ?? [], + widgets: widget.widgets?.compactMap { OpenHABWidget($0) } ?? [], + visibility: widget.visibility, + switchSupport: widget.switchSupport, + forceAsItem: widget.forceAsItem + ) + } +} + +extension OpenHABWidget { + func update(with event: OpenHABSitemapWidgetEvent) { + state = event.state ?? state + icon = event.icon ?? icon + label = event.label ?? label + iconColor = event.iconcolor ?? "" + labelcolor = event.labelcolor ?? "" + valuecolor = event.valuecolor ?? "" + visibility = event.visibility ?? visibility + + if let enrichedItem = event.enrichedItem { + if let link = item?.link { + enrichedItem.link = link + } + item = enrichedItem + } + } +} diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidgetMapping.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidgetMapping.swift index 6d2d1499..81775c25 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidgetMapping.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidgetMapping.swift @@ -20,3 +20,9 @@ public class OpenHABWidgetMapping: NSObject, Decodable { self.label = label.orEmpty } } + +extension OpenHABWidgetMapping { + convenience init(_ mapping: Components.Schemas.MappingDTO) { + self.init(command: mapping.command, label: mapping.label) + } +} diff --git a/OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift b/OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift index 84134177..e2d1b4ea 100644 --- a/OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift +++ b/OpenHABCore/Sources/OpenHABCore/Util/APIActor.swift @@ -23,7 +23,9 @@ public protocol OpenHABUiTileService { func openHABTiles() async throws -> [OpenHABUiTile] } -// swiftlint:disable file_types_order +public enum APIActorError: Error { + case undocumented +} public actor APIActor { var api: APIProtocol @@ -99,10 +101,6 @@ public actor APIActor { } } -public enum APIActorError: Error { - case undocumented -} - extension APIActor: OpenHABSitemapsService { public func openHABSitemaps() async throws -> [OpenHABSitemap] { // swiftformat:disable:next redundantSelf @@ -209,296 +207,3 @@ public extension APIActor { _ = try response.ok } } - -// MARK: - URLSessionDelegate for Client Certificates and Basic Auth - -class APIActorDelegate: NSObject, URLSessionDelegate, URLSessionTaskDelegate { - private let username: String - private let password: String - - init(username: String, password: String) { - self.username = username - self.password = password - } - - public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { - await urlSessionInternal(session, task: nil, didReceive: challenge) - } - - public func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { - await urlSessionInternal(session, task: task, didReceive: challenge) - } - - private func urlSessionInternal(_ session: URLSession, task: URLSessionTask?, didReceive challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { - os_log("URLAuthenticationChallenge: %{public}@", log: .networking, type: .info, challenge.protectionSpace.authenticationMethod) - let authenticationMethod = challenge.protectionSpace.authenticationMethod - switch authenticationMethod { - case NSURLAuthenticationMethodServerTrust: - return await handleServerTrust(challenge: challenge) - case NSURLAuthenticationMethodDefault, NSURLAuthenticationMethodHTTPBasic: - if let task { - task.authAttemptCount += 1 - if task.authAttemptCount > 1 { - return (.cancelAuthenticationChallenge, nil) - } else { - return await handleBasicAuth(challenge: challenge) - } - } else { - return await handleBasicAuth(challenge: challenge) - } - case NSURLAuthenticationMethodClientCertificate: - return await handleClientCertificateAuth(challenge: challenge) - default: - return (.performDefaultHandling, nil) - } - } - - private func handleServerTrust(challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { - guard let serverTrust = challenge.protectionSpace.serverTrust else { - return (.performDefaultHandling, nil) - } - let credential = URLCredential(trust: serverTrust) - return (.useCredential, credential) - } - - private func handleBasicAuth(challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { - let credential = URLCredential(user: username, password: password, persistence: .forSession) - return (.useCredential, credential) - } - - private func handleClientCertificateAuth(challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { - let certificateManager = ClientCertificateManager() - let (disposition, credential) = certificateManager.evaluateTrust(with: challenge) - return (disposition, credential) - } -} - -extension OpenHABWidget { - func update(with event: OpenHABSitemapWidgetEvent) { - state = event.state ?? state - icon = event.icon ?? icon - label = event.label ?? label - iconColor = event.iconcolor ?? "" - labelcolor = event.labelcolor ?? "" - valuecolor = event.valuecolor ?? "" - visibility = event.visibility ?? visibility - - if let enrichedItem = event.enrichedItem { - if let link = item?.link { - enrichedItem.link = link - } - item = enrichedItem - } - } -} - -public class OpenHABSitemapWidgetEvent { - var sitemapName: String? - var pageId: String? - var widgetId: String? - var label: String? - var labelSource: String? - var icon: String? - var reloadIcon: Bool? - var labelcolor: String? - var valuecolor: String? - var iconcolor: String? - var visibility: Bool? - var state: String? - var enrichedItem: OpenHABItem? - var descriptionChanged: Bool? - - init(sitemapName: String? = nil, pageId: String? = nil, widgetId: String? = nil, label: String? = nil, labelSource: String? = nil, icon: String? = nil, reloadIcon: Bool? = nil, labelcolor: String? = nil, valuecolor: String? = nil, iconcolor: String? = nil, visibility: Bool? = nil, state: String? = nil, enrichedItem: OpenHABItem? = nil, descriptionChanged: Bool? = nil) { - self.sitemapName = sitemapName - self.pageId = pageId - self.widgetId = widgetId - self.label = label - self.labelSource = labelSource - self.icon = icon - self.reloadIcon = reloadIcon - self.labelcolor = labelcolor - self.valuecolor = valuecolor - self.iconcolor = iconcolor - self.visibility = visibility - self.state = state - self.enrichedItem = enrichedItem - self.descriptionChanged = descriptionChanged - } - - convenience init?(_ event: Components.Schemas.SitemapWidgetEvent?) { - guard let event else { return nil } - // swiftlint:disable:next line_length - self.init(sitemapName: event.sitemapName, pageId: event.pageId, widgetId: event.widgetId, label: event.label, labelSource: event.labelSource, icon: event.icon, reloadIcon: event.reloadIcon, labelcolor: event.labelcolor, valuecolor: event.valuecolor, iconcolor: event.iconcolor, visibility: event.visibility, state: event.state, enrichedItem: OpenHABItem(event.item), descriptionChanged: event.descriptionChanged) - } -} - -extension OpenHABSitemapWidgetEvent: CustomStringConvertible { - public var description: String { - "\(widgetId ?? "") \(label ?? "") \(enrichedItem?.state ?? "")" - } -} - -public extension OpenHABSitemapWidgetEvent { - struct CodingData: Decodable, Hashable, Equatable { - public static func == (lhs: OpenHABSitemapWidgetEvent.CodingData, rhs: OpenHABSitemapWidgetEvent.CodingData) -> Bool { - lhs.widgetId == rhs.widgetId - } - - public func hash(into hasher: inout Hasher) { - hasher.combine(widgetId) - } - - var sitemapName: String? - var pageId: String? - var widgetId: String? - var label: String? - var labelSource: String? - var icon: String? - var reloadIcon: Bool? - var labelcolor: String? - var valuecolor: String? - var iconcolor: String? - var visibility: Bool? -// var state: String? - var item: OpenHABItem.CodingData? - var descriptionChanged: Bool? - var link: String? - } -} - -extension OpenHABSitemapWidgetEvent.CodingData { - var openHABSitemapWidgetEvent: OpenHABSitemapWidgetEvent { - // swiftlint:disable:next line_length - OpenHABSitemapWidgetEvent(sitemapName: sitemapName, pageId: pageId, widgetId: widgetId, label: label, labelSource: labelSource, icon: icon, reloadIcon: reloadIcon, labelcolor: labelcolor, valuecolor: valuecolor, iconcolor: iconcolor, visibility: visibility, enrichedItem: item?.openHABItem, descriptionChanged: descriptionChanged) - } -} - -extension OpenHABUiTile { - convenience init(_ tile: Components.Schemas.TileDTO) { - self.init(name: tile.name.orEmpty, url: tile.url.orEmpty, imageUrl: tile.imageUrl.orEmpty) - } -} - -extension OpenHABSitemap { - convenience init(_ sitemap: Components.Schemas.SitemapDTO) { - self.init( - name: sitemap.name.orEmpty, - icon: sitemap.icon.orEmpty, - label: sitemap.label.orEmpty, - link: sitemap.link.orEmpty, - page: OpenHABPage(sitemap.homepage) - ) - } -} - -extension OpenHABPage { - convenience init?(_ page: Components.Schemas.PageDTO?) { - if let page { - self.init( - pageId: page.id.orEmpty, - title: page.title.orEmpty, - link: page.link.orEmpty, - leaf: page.leaf ?? false, - widgets: page.widgets?.compactMap { OpenHABWidget($0) } ?? [], - icon: page.icon.orEmpty - ) - } else { - return nil - } - } -} - -extension OpenHABWidgetMapping { - convenience init(_ mapping: Components.Schemas.MappingDTO) { - self.init(command: mapping.command, label: mapping.label) - } -} - -extension OpenHABCommandOptions { - convenience init?(_ options: Components.Schemas.CommandOption?) { - if let options { - self.init(command: options.command.orEmpty, label: options.label.orEmpty) - } else { - return nil - } - } -} - -extension OpenHABOptions { - convenience init?(_ options: Components.Schemas.StateOption?) { - if let options { - self.init(value: options.value.orEmpty, label: options.label.orEmpty) - } else { - return nil - } - } -} - -extension OpenHABStateDescription { - convenience init?(_ state: Components.Schemas.StateDescription?) { - if let state { - self.init(minimum: state.minimum, maximum: state.maximum, step: state.step, readOnly: state.readOnly, options: state.options?.compactMap { OpenHABOptions($0) }, pattern: state.pattern) - } else { - return nil - } - } -} - -extension OpenHABCommandDescription { - convenience init?(_ commands: Components.Schemas.CommandDescription?) { - if let commands { - self.init(commandOptions: commands.commandOptions?.compactMap { OpenHABCommandOptions($0) }) - } else { - return nil - } - } -} - -// swiftlint:disable line_length -extension OpenHABItem { - convenience init?(_ item: Components.Schemas.EnrichedItemDTO?) { - if let item { - self.init(name: item.name.orEmpty, type: item._type.orEmpty, state: item.state.orEmpty, link: item.link.orEmpty, label: item.label.orEmpty, groupType: nil, stateDescription: OpenHABStateDescription(item.stateDescription), commandDescription: OpenHABCommandDescription(item.commandDescription), members: [], category: item.category, options: []) - } else { - return nil - } - } -} - -// swiftlint:enable line_length - -extension OpenHABWidget { - convenience init(_ widget: Components.Schemas.WidgetDTO) { - self.init( - widgetId: widget.widgetId.orEmpty, - label: widget.label.orEmpty, - icon: widget.icon.orEmpty, - type: OpenHABWidget.WidgetType(rawValue: widget._type!), - url: widget.url, - period: widget.period, - minValue: widget.minValue, - maxValue: widget.maxValue, - step: widget.step, - refresh: widget.refresh.map(Int.init), - height: 50, // TODO: - isLeaf: true, - iconColor: widget.iconcolor, - labelColor: widget.labelcolor, - valueColor: widget.valuecolor, - service: widget.service, - state: widget.state, - text: "", - legend: widget.legend, - encoding: widget.encoding, - item: OpenHABItem(widget.item), - linkedPage: OpenHABPage(widget.linkedPage), - mappings: widget.mappings?.compactMap(OpenHABWidgetMapping.init) ?? [], - widgets: widget.widgets?.compactMap { OpenHABWidget($0) } ?? [], - visibility: widget.visibility, - switchSupport: widget.switchSupport, - forceAsItem: widget.forceAsItem - ) - } -} - -// swiftlint:enable file_types_order diff --git a/OpenHABCore/Sources/OpenHABCore/Util/APIActorDelegate.swift b/OpenHABCore/Sources/OpenHABCore/Util/APIActorDelegate.swift new file mode 100644 index 00000000..f5648225 --- /dev/null +++ b/OpenHABCore/Sources/OpenHABCore/Util/APIActorDelegate.swift @@ -0,0 +1,76 @@ +// Copyright (c) 2010-2024 Contributors to the openHAB project +// +// See the NOTICE file(s) distributed with this work for additional +// information. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0 +// +// SPDX-License-Identifier: EPL-2.0 + +import Foundation +import os + +// MARK: - URLSessionDelegate for Client Certificates and Basic Auth + +class APIActorDelegate: NSObject, URLSessionDelegate, URLSessionTaskDelegate { + private let username: String + private let password: String + + init(username: String, password: String) { + self.username = username + self.password = password + } + + public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { + await urlSessionInternal(session, task: nil, didReceive: challenge) + } + + public func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { + await urlSessionInternal(session, task: task, didReceive: challenge) + } + + private func urlSessionInternal(_ session: URLSession, task: URLSessionTask?, didReceive challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { + os_log("URLAuthenticationChallenge: %{public}@", log: .networking, type: .info, challenge.protectionSpace.authenticationMethod) + let authenticationMethod = challenge.protectionSpace.authenticationMethod + switch authenticationMethod { + case NSURLAuthenticationMethodServerTrust: + return await handleServerTrust(challenge: challenge) + case NSURLAuthenticationMethodDefault, NSURLAuthenticationMethodHTTPBasic: + if let task { + task.authAttemptCount += 1 + if task.authAttemptCount > 1 { + return (.cancelAuthenticationChallenge, nil) + } else { + return await handleBasicAuth(challenge: challenge) + } + } else { + return await handleBasicAuth(challenge: challenge) + } + case NSURLAuthenticationMethodClientCertificate: + return await handleClientCertificateAuth(challenge: challenge) + default: + return (.performDefaultHandling, nil) + } + } + + private func handleServerTrust(challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { + guard let serverTrust = challenge.protectionSpace.serverTrust else { + return (.performDefaultHandling, nil) + } + let credential = URLCredential(trust: serverTrust) + return (.useCredential, credential) + } + + private func handleBasicAuth(challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { + let credential = URLCredential(user: username, password: password, persistence: .forSession) + return (.useCredential, credential) + } + + private func handleClientCertificateAuth(challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { + let certificateManager = ClientCertificateManager() + let (disposition, credential) = certificateManager.evaluateTrust(with: challenge) + return (disposition, credential) + } +} diff --git a/openHAB/DrawerView.swift b/openHAB/DrawerView.swift index 291428a1..2faf8440 100644 --- a/openHAB/DrawerView.swift +++ b/openHAB/DrawerView.swift @@ -16,31 +16,6 @@ import SafariServices import SFSafeSymbols import SwiftUI -func deriveSitemaps(_ response: Data?) -> [OpenHABSitemap] { - var sitemaps = [OpenHABSitemap]() - - if let response { - do { - os_log("Response will be decoded by JSON", log: .remoteAccess, type: .info) - let sitemapsCodingData = try response.decoded(as: [OpenHABSitemap.CodingData].self) - for sitemapCodingDatum in sitemapsCodingData { - os_log("Sitemap %{PUBLIC}@", log: .remoteAccess, type: .info, sitemapCodingDatum.label) - sitemaps.append(sitemapCodingDatum.openHABSitemap) - } - } catch { - os_log("Should not throw %{PUBLIC}@", log: .notifications, type: .error, error.localizedDescription) - } - } - - return sitemaps -} - -struct UiTile: Decodable { - var name: String - var url: String - var imageUrl: String -} - struct ImageView: View { let url: String @@ -167,67 +142,40 @@ struct DrawerView: View { } } .listStyle(.inset) - .onAppear(perform: loadData) - } - - private func loadData() { - // TODO: Replace network calls with appropriate @EnvironmentObject or other state management - loadSitemaps() - loadUiTiles() - } - - private func loadSitemaps() { - // Perform network call to load sitemaps and decode - // Update the sitemaps state - - NetworkConnection.sitemaps(openHABRootUrl: appData?.openHABRootUrl ?? "") { response in - switch response.result { - case let .success(data): - os_log("Sitemap response", log: .viewCycle, type: .info) - - sitemaps = deriveSitemaps(data) + .task { + let apiactor = await APIActor() + Task { + do { + await apiactor.updateBaseURL(with: URL(string: appData?.openHABRootUrl ?? "")!) - if sitemaps.last?.name == "_default", sitemaps.count > 1 { - sitemaps = Array(sitemaps.dropLast()) - } + sitemaps = try await apiactor.openHABSitemaps() + if sitemaps.last?.name == "_default", sitemaps.count > 1 { + sitemaps = Array(sitemaps.dropLast()) + } + // Sort the sitemaps according to Settings selection. + switch SortSitemapsOrder(rawValue: Preferences.sortSitemapsby) ?? .label { + case .label: sitemaps.sort { $0.label < $1.label } + case .name: sitemaps.sort { $0.name < $1.name } + } - // Sort the sitemaps according to Settings selection. - switch SortSitemapsOrder(rawValue: Preferences.sortSitemapsby) ?? .label { - case .label: sitemaps.sort { $0.label < $1.label } - case .name: sitemaps.sort { $0.name < $1.name } + } catch { + os_log("%{PUBLIC}@", log: .default, type: .error, error.localizedDescription) + sitemaps = [] } - case let .failure(error): - os_log("%{PUBLIC}@", log: .default, type: .error, error.localizedDescription) } - } - } - private func loadUiTiles() { - // Perform network call to load UI Tiles and decode - // Update the uiTiles state - NetworkConnection.uiTiles(openHABRootUrl: appData?.openHABRootUrl ?? "") { response in - switch response.result { - case .success: - os_log("ui tiles response", log: .viewCycle, type: .info) - guard let responseData = response.data else { - os_log("Error: did not receive data", log: OSLog.remoteAccess, type: .info) - return - } + Task { do { - uiTiles = try JSONDecoder().decode([OpenHABUiTile].self, from: responseData) + await apiactor.updateBaseURL(with: URL(string: appData?.openHABRootUrl ?? "")!) + uiTiles = try await apiactor.openHABTiles() + os_log("ui tiles response", log: .viewCycle, type: .info) } catch { - os_log("Error: did not receive data %{PUBLIC}@", log: OSLog.remoteAccess, type: .info, error.localizedDescription) + os_log("%{PUBLIC}@", log: .default, type: .error, error.localizedDescription) + uiTiles = [] } - case let .failure(error): - os_log("%{PUBLIC}@", log: .default, type: .error, error.localizedDescription) } } } - - mutating func loadSettings() { - openHABUsername = Preferences.username - openHABPassword = Preferences.password - } } #Preview { From 4ec2b7e0de5522c4746b70d55c2a1d3f8890e541 Mon Sep 17 00:00:00 2001 From: Tim Bert <5411131+timbms@users.noreply.github.com> Date: Sun, 15 Sep 2024 20:38:37 +0200 Subject: [PATCH 09/13] Reusing OpenHABWidget for Watch. Allows to remove complexity. --- .../OpenHABCore/Model/OpenHABWidget.swift | 119 ++++++++++++------ openHAB/OpenHABSitemapViewController.swift | 2 +- .../Views/ContentView.swift | 2 +- .../Views/Rows/ColorPickerRow.swift | 3 +- .../Views/Rows/FrameRow.swift | 3 +- .../Views/Rows/GenericRow.swift | 3 +- .../Views/Rows/ImageRawRow.swift | 2 +- .../Views/Rows/MapViewRow.swift | 3 +- .../Views/Rows/RollershutterRow.swift | 3 +- .../Views/Rows/SegmentRow.swift | 2 +- .../Views/Rows/SetpointRow.swift | 3 +- .../Views/Rows/SliderRow.swift | 2 +- .../Rows/SliderWithSwitchSupportRow.swift | 2 +- .../Views/Rows/SwitchRow.swift | 2 +- .../Views/Utils/DetailTextLabelView.swift | 3 +- .../Views/Utils/IconView.swift | 2 +- .../Views/Utils/MapView.swift | 6 +- .../Views/Utils/TextLabelView.swift | 3 +- .../Model/ObservableOpenHABSitemapPage.swift | 12 +- .../Model/ObservableOpenHABWidget.swift | 26 +--- .../ObservableOpenHABWidgetExtension.swift | 3 +- .../openHABWatch Extension/UserData.swift | 2 +- 22 files changed, 120 insertions(+), 88 deletions(-) diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidget.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidget.swift index 8e5afd05..b1ae4b5a 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidget.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABWidget.swift @@ -14,41 +14,29 @@ import Foundation import MapKit import os.log -protocol Widget: AnyObject { - // Recursive constraints possible as of Swift 4.1 - associatedtype ChildWidget: Widget - - var sendCommand: ((_ item: OpenHABItem, _ command: String?) -> Void)? { get set } - var widgetId: String { get set } - var label: String { get set } - var icon: String { get set } - var type: String { get set } - var url: String { get set } - var period: String { get set } - var minValue: Double { get set } - var maxValue: Double { get set } - var step: Double { get set } - var refresh: Int { get set } - var height: Double { get set } - var isLeaf: Bool { get set } - var iconColor: String { get set } - var labelcolor: String { get set } - var valuecolor: String { get set } - var service: String { get set } - var state: String { get set } - var text: String { get set } - var legend: Bool { get set } - var encoding: String { get set } - var item: OpenHABItem? { get set } - var linkedPage: OpenHABPage? { get set } - var mappings: [OpenHABWidgetMapping] { get set } - var image: UIImage? { get set } - var widgets: [ChildWidget] { get set } - - func flatten(_: [ChildWidget]) +public enum WidgetTypeEnum { + case switcher(Bool) + case slider // + case segmented(Int) + case unassigned + case rollershutter + case frame + case setpoint + case selection + case colorpicker + case chart + case image + case video + case webview + case mapview + + public var boolState: Bool { + guard case let .switcher(value) = self else { return false } + return value + } } -public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { +public class OpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableObject { public enum WidgetType: String { case chart = "Chart" case colorpicker = "Colorpicker" @@ -71,7 +59,7 @@ public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { public var sendCommand: ((_ item: OpenHABItem, _ command: String?) -> Void)? public var widgetId = "" - public var label = "" + @Published public var label = "" public var icon = "" public var type: WidgetType? public var url = "" @@ -86,12 +74,12 @@ public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { public var labelcolor = "" public var valuecolor = "" public var service = "" - public var state = "" + @Published public var state = "" public var text = "" public var legend: Bool? public var encoding = "" public var forceAsItem: Bool? - public var item: OpenHABItem? + @Published public var item: OpenHABItem? public var linkedPage: OpenHABPage? public var mappings: [OpenHABWidgetMapping] = [] public var image: UIImage? @@ -99,6 +87,8 @@ public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { public var visibility = true public var switchSupport = false + @Published public var stateEnumBinding: WidgetTypeEnum = .unassigned + // Text prior to "[" public var labelText: String? { let array = label.components(separatedBy: "[") @@ -142,6 +132,54 @@ public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { item?.state?.parseAsNumber(format: item?.stateDescription?.numberPattern) } + public var adjustedValue: Double { + if let item { + adj(item.stateAsDouble()) + } else { + minValue + } + } + + public var stateEnum: WidgetTypeEnum { + switch type { + case .frame: + .frame + case .switchWidget: + // Reflecting the discussion held in https://github.com/openhab/openhab-core/issues/952 + if !mappings.isEmpty { + .segmented(Int(mappingIndex(byCommand: item?.state) ?? -1)) + } else if item?.isOfTypeOrGroupType(.switchItem) ?? false { + .switcher(item?.state == "ON" ? true : false) + } else if item?.isOfTypeOrGroupType(.rollershutter) ?? false { + .rollershutter + } else if !mappingsOrItemOptions.isEmpty { + .segmented(Int(mappingIndex(byCommand: item?.state) ?? -1)) + } else { + .switcher(item?.state == "ON" ? true : false) + } + case .setpoint: + .setpoint + case .slider: + .slider + case .selection: + .selection + case .colorpicker: + .colorpicker + case .chart: + .chart + case .image: + .image + case .video: + .video + case .webview: + .webview + case .mapview: + .mapview + default: + .unassigned + } + } + public func sendItemUpdate(state: NumberState?) { guard let item, let state else { os_log("ItemUpdate for Item or State = nil", log: .default, type: .info) @@ -202,6 +240,12 @@ public class OpenHABWidget: NSObject, MKAnnotation, Identifiable { } return iconState } + + private func adj(_ raw: Double) -> Double { + var valueAdjustedToStep = floor((raw - minValue) / step) * step + valueAdjustedToStep += minValue + return valueAdjustedToStep.clamped(to: minValue ... maxValue) + } } extension OpenHABWidget.WidgetType: Decodable {} @@ -252,6 +296,7 @@ public extension OpenHABWidget { self.switchSupport = switchSupport ?? false self.forceAsItem = forceAsItem + stateEnumBinding = stateEnum } } @@ -288,7 +333,7 @@ public extension OpenHABWidget { } } -extension OpenHABWidget.CodingData { +public extension OpenHABWidget.CodingData { var openHABWidget: OpenHABWidget { let mappedWidgets = widgets.map(\.openHABWidget) // swiftlint:disable:next line_length diff --git a/openHAB/OpenHABSitemapViewController.swift b/openHAB/OpenHABSitemapViewController.swift index 6402917f..0cb1a136 100644 --- a/openHAB/OpenHABSitemapViewController.swift +++ b/openHAB/OpenHABSitemapViewController.swift @@ -419,7 +419,7 @@ class OpenHABSitemapViewController: OpenHABViewController, GenericUITableViewCel default: break } widgetTableView.reloadData() - } catch let error as APIActorError { + } catch _ as APIActorError { logger.debug("APIActorError on OpenHABSitemapViewController") } catch { os_log("%{PUBLIC}@", log: .default, type: .error, error.localizedDescription) diff --git a/openHABWatch Extension/Views/ContentView.swift b/openHABWatch Extension/Views/ContentView.swift index 893b78c8..984ba4ee 100644 --- a/openHABWatch Extension/Views/ContentView.swift +++ b/openHABWatch Extension/Views/ContentView.swift @@ -58,7 +58,7 @@ struct ContentView: View { } // https://www.swiftbysundell.com/tips/adding-swiftui-viewbuilder-to-functions/ - @ViewBuilder func rowWidget(widget: ObservableOpenHABWidget) -> some View { + @ViewBuilder func rowWidget(widget: OpenHABWidget) -> some View { switch widget.stateEnum { case .switcher: SwitchRow(widget: widget) diff --git a/openHABWatch Extension/Views/Rows/ColorPickerRow.swift b/openHABWatch Extension/Views/Rows/ColorPickerRow.swift index 86ded113..48cf9b73 100644 --- a/openHABWatch Extension/Views/Rows/ColorPickerRow.swift +++ b/openHABWatch Extension/Views/Rows/ColorPickerRow.swift @@ -9,11 +9,12 @@ // // SPDX-License-Identifier: EPL-2.0 +import OpenHABCore import os.log import SwiftUI struct ColorPickerRow: View { - @ObservedObject var widget: ObservableOpenHABWidget + @ObservedObject var widget: OpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared var body: some View { let uiColor = widget.item?.stateAsUIColor() diff --git a/openHABWatch Extension/Views/Rows/FrameRow.swift b/openHABWatch Extension/Views/Rows/FrameRow.swift index 1048b6c9..fe8d7611 100644 --- a/openHABWatch Extension/Views/Rows/FrameRow.swift +++ b/openHABWatch Extension/Views/Rows/FrameRow.swift @@ -9,10 +9,11 @@ // // SPDX-License-Identifier: EPL-2.0 +import OpenHABCore import SwiftUI struct FrameRow: View { - @ObservedObject var widget: ObservableOpenHABWidget + @ObservedObject var widget: OpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared var body: some View { let gray = Color(UIColor.darkGray) diff --git a/openHABWatch Extension/Views/Rows/GenericRow.swift b/openHABWatch Extension/Views/Rows/GenericRow.swift index e8bf6c46..46c66773 100644 --- a/openHABWatch Extension/Views/Rows/GenericRow.swift +++ b/openHABWatch Extension/Views/Rows/GenericRow.swift @@ -9,11 +9,12 @@ // // SPDX-License-Identifier: EPL-2.0 +import OpenHABCore import os.log import SwiftUI struct GenericRow: View { - @ObservedObject var widget: ObservableOpenHABWidget + @ObservedObject var widget: OpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared var body: some View { diff --git a/openHABWatch Extension/Views/Rows/ImageRawRow.swift b/openHABWatch Extension/Views/Rows/ImageRawRow.swift index 77869aba..43dd82c3 100644 --- a/openHABWatch Extension/Views/Rows/ImageRawRow.swift +++ b/openHABWatch Extension/Views/Rows/ImageRawRow.swift @@ -15,7 +15,7 @@ import os.log import SwiftUI struct ImageRawRow: View { - @ObservedObject var widget: ObservableOpenHABWidget + @ObservedObject var widget: OpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared var body: some View { diff --git a/openHABWatch Extension/Views/Rows/MapViewRow.swift b/openHABWatch Extension/Views/Rows/MapViewRow.swift index dfb178b8..ddbba15a 100644 --- a/openHABWatch Extension/Views/Rows/MapViewRow.swift +++ b/openHABWatch Extension/Views/Rows/MapViewRow.swift @@ -9,10 +9,11 @@ // // SPDX-License-Identifier: EPL-2.0 +import OpenHABCore import SwiftUI struct MapViewRow: View { - @ObservedObject var widget: ObservableOpenHABWidget + @ObservedObject var widget: OpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared var body: some View { diff --git a/openHABWatch Extension/Views/Rows/RollershutterRow.swift b/openHABWatch Extension/Views/Rows/RollershutterRow.swift index f68974e0..45f5e49a 100644 --- a/openHABWatch Extension/Views/Rows/RollershutterRow.swift +++ b/openHABWatch Extension/Views/Rows/RollershutterRow.swift @@ -9,10 +9,11 @@ // // SPDX-License-Identifier: EPL-2.0 +import OpenHABCore import SwiftUI struct RollershutterRow: View { - @ObservedObject var widget: ObservableOpenHABWidget + @ObservedObject var widget: OpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared var body: some View { diff --git a/openHABWatch Extension/Views/Rows/SegmentRow.swift b/openHABWatch Extension/Views/Rows/SegmentRow.swift index 3ec61e2a..e38ded4c 100644 --- a/openHABWatch Extension/Views/Rows/SegmentRow.swift +++ b/openHABWatch Extension/Views/Rows/SegmentRow.swift @@ -14,7 +14,7 @@ import os.log import SwiftUI struct SegmentRow: View { - @ObservedObject var widget: ObservableOpenHABWidget + @ObservedObject var widget: OpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared @State private var favoriteColor = 0 diff --git a/openHABWatch Extension/Views/Rows/SetpointRow.swift b/openHABWatch Extension/Views/Rows/SetpointRow.swift index a63cda59..c2fd6fd3 100644 --- a/openHABWatch Extension/Views/Rows/SetpointRow.swift +++ b/openHABWatch Extension/Views/Rows/SetpointRow.swift @@ -9,11 +9,12 @@ // // SPDX-License-Identifier: EPL-2.0 +import OpenHABCore import os.log import SwiftUI struct SetpointRow: View { - @ObservedObject var widget: ObservableOpenHABWidget + @ObservedObject var widget: OpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared private var isIntStep: Bool { diff --git a/openHABWatch Extension/Views/Rows/SliderRow.swift b/openHABWatch Extension/Views/Rows/SliderRow.swift index 44cb1ae1..261908c3 100644 --- a/openHABWatch Extension/Views/Rows/SliderRow.swift +++ b/openHABWatch Extension/Views/Rows/SliderRow.swift @@ -14,7 +14,7 @@ import os.log import SwiftUI struct SliderRow: View { - @ObservedObject var widget: ObservableOpenHABWidget + @ObservedObject var widget: OpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared var body: some View { diff --git a/openHABWatch Extension/Views/Rows/SliderWithSwitchSupportRow.swift b/openHABWatch Extension/Views/Rows/SliderWithSwitchSupportRow.swift index af0fea02..63b5abc0 100644 --- a/openHABWatch Extension/Views/Rows/SliderWithSwitchSupportRow.swift +++ b/openHABWatch Extension/Views/Rows/SliderWithSwitchSupportRow.swift @@ -14,7 +14,7 @@ import os.log import SwiftUI struct SliderWithSwitchSupportRow: View { - @ObservedObject var widget: ObservableOpenHABWidget + @ObservedObject var widget: OpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared var body: some View { diff --git a/openHABWatch Extension/Views/Rows/SwitchRow.swift b/openHABWatch Extension/Views/Rows/SwitchRow.swift index a593a42e..f3f39340 100644 --- a/openHABWatch Extension/Views/Rows/SwitchRow.swift +++ b/openHABWatch Extension/Views/Rows/SwitchRow.swift @@ -15,7 +15,7 @@ import os.log import SwiftUI struct SwitchRow: View { - @ObservedObject var widget: ObservableOpenHABWidget + @ObservedObject var widget: OpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared var body: some View { diff --git a/openHABWatch Extension/Views/Utils/DetailTextLabelView.swift b/openHABWatch Extension/Views/Utils/DetailTextLabelView.swift index a6a0d84a..65f10ce5 100644 --- a/openHABWatch Extension/Views/Utils/DetailTextLabelView.swift +++ b/openHABWatch Extension/Views/Utils/DetailTextLabelView.swift @@ -9,10 +9,11 @@ // // SPDX-License-Identifier: EPL-2.0 +import OpenHABCore import SwiftUI struct DetailTextLabelView: View { - @ObservedObject var widget: ObservableOpenHABWidget + @ObservedObject var widget: OpenHABWidget var body: some View { Unwrap(widget.labelValue) { diff --git a/openHABWatch Extension/Views/Utils/IconView.swift b/openHABWatch Extension/Views/Utils/IconView.swift index 55dd1ca8..6b053d1a 100644 --- a/openHABWatch Extension/Views/Utils/IconView.swift +++ b/openHABWatch Extension/Views/Utils/IconView.swift @@ -15,7 +15,7 @@ import os.log import SwiftUI struct IconView: View { - @ObservedObject var widget: ObservableOpenHABWidget + @ObservedObject var widget: OpenHABWidget @ObservedObject var settings = ObservableOpenHABDataObject.shared var iconURL: URL? { diff --git a/openHABWatch Extension/Views/Utils/MapView.swift b/openHABWatch Extension/Views/Utils/MapView.swift index a57e7c0a..4d8966a7 100644 --- a/openHABWatch Extension/Views/Utils/MapView.swift +++ b/openHABWatch Extension/Views/Utils/MapView.swift @@ -14,7 +14,7 @@ import OpenHABCore import SwiftUI struct MapView: View { - @ObservedObject var widget: ObservableOpenHABWidget + @ObservedObject var widget: OpenHABWidget @State private var region = MKCoordinateRegion( center: CLLocationCoordinate2D( latitude: 40, @@ -38,10 +38,10 @@ struct MapView: View { } } -struct MapView_Previews: PreviewProvider { + struct MapView_Previews: PreviewProvider { static var previews: some View { let widget = UserData().widgets[9] return MapView(widget: widget) .previewDevice("Apple Watch Series 5 - 44mm") } -} + } diff --git a/openHABWatch Extension/Views/Utils/TextLabelView.swift b/openHABWatch Extension/Views/Utils/TextLabelView.swift index d4cdc2ae..b4aef5b4 100644 --- a/openHABWatch Extension/Views/Utils/TextLabelView.swift +++ b/openHABWatch Extension/Views/Utils/TextLabelView.swift @@ -9,10 +9,11 @@ // // SPDX-License-Identifier: EPL-2.0 +import OpenHABCore import SwiftUI struct TextLabelView: View { - @ObservedObject var widget: ObservableOpenHABWidget + @ObservedObject var widget: OpenHABWidget var body: some View { Text(widget.labelText ?? "") diff --git a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABSitemapPage.swift b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABSitemapPage.swift index 3d94657b..39c09267 100644 --- a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABSitemapPage.swift +++ b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABSitemapPage.swift @@ -15,19 +15,19 @@ import os.log class ObservableOpenHABSitemapPage: NSObject { var sendCommand: ((_ item: OpenHABItem, _ command: String?) -> Void)? - var widgets: [ObservableOpenHABWidget] = [] + var widgets: [OpenHABWidget] = [] var pageId = "" var title = "" var link = "" var leaf = false - init(pageId: String, title: String, link: String, leaf: Bool, widgets: [ObservableOpenHABWidget]) { + init(pageId: String, title: String, link: String, leaf: Bool, widgets: [OpenHABWidget]) { super.init() self.pageId = pageId self.title = title self.link = link self.leaf = leaf - var tempWidgets = [ObservableOpenHABWidget]() + var tempWidgets = [OpenHABWidget]() tempWidgets.flatten(widgets) self.widgets = tempWidgets for widget in self.widgets { @@ -37,7 +37,7 @@ class ObservableOpenHABSitemapPage: NSObject { } } - init(pageId: String, title: String, link: String, leaf: Bool, expandedWidgets: [ObservableOpenHABWidget]) { + init(pageId: String, title: String, link: String, leaf: Bool, expandedWidgets: [OpenHABWidget]) { super.init() self.pageId = pageId self.title = title @@ -65,7 +65,7 @@ extension ObservableOpenHABSitemapPage { let title: String? let link: String? let leaf: Bool? - let widgets: [ObservableOpenHABWidget.CodingData]? + let widgets: [OpenHABWidget.CodingData]? private enum CodingKeys: String, CodingKey { case pageId = "id" @@ -85,7 +85,7 @@ extension ObservableOpenHABSitemapPage.CodingData { } extension ObservableOpenHABSitemapPage { - func filter(_ isIncluded: (ObservableOpenHABWidget) throws -> Bool) rethrows -> ObservableOpenHABSitemapPage { + func filter(_ isIncluded: (OpenHABWidget) throws -> Bool) rethrows -> ObservableOpenHABSitemapPage { let filteredOpenHABSitemapPage = try ObservableOpenHABSitemapPage( pageId: pageId, title: title, diff --git a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift index 6de6d960..9adf56fe 100644 --- a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift +++ b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift @@ -18,28 +18,6 @@ import MapKit import OpenHABCore import os.log -enum WidgetTypeEnum { - case switcher(Bool) - case slider // - case segmented(Int) - case unassigned - case rollershutter - case frame - case setpoint - case selection - case colorpicker - case chart - case image - case video - case webview - case mapview - - var boolState: Bool { - guard case let .switcher(value) = self else { return false } - return value - } -} - @available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *) class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableObject { var id: String = "" @@ -74,7 +52,7 @@ class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableO public var switchSupport = false public var forceAsItem: Bool? - @Published var stateEnumBinding: WidgetTypeEnum = .unassigned + @Published public var stateEnumBinding: WidgetTypeEnum = .unassigned // Text prior to "[" var labelText: String? { @@ -295,7 +273,7 @@ extension ObservableOpenHABWidget.CodingData { } // Recursive parsing of nested widget structure -extension [ObservableOpenHABWidget] { +extension [OpenHABWidget] { mutating func flatten(_ widgets: [Element]) { for widget in widgets { append(widget) diff --git a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidgetExtension.swift b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidgetExtension.swift index d9402387..3ab2cff6 100644 --- a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidgetExtension.swift +++ b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidgetExtension.swift @@ -10,10 +10,11 @@ // SPDX-License-Identifier: EPL-2.0 import Foundation +import OpenHABCore import os.log import SwiftUI -extension ObservableOpenHABWidget { +extension OpenHABWidget { @ViewBuilder func makeView(settings: ObservableOpenHABDataObject) -> some View { if let linkedPage { let title = linkedPage.title.components(separatedBy: "[")[0] diff --git a/openHABWatch Extension/openHABWatch Extension/UserData.swift b/openHABWatch Extension/openHABWatch Extension/UserData.swift index 6923ab3a..10a64430 100644 --- a/openHABWatch Extension/openHABWatch Extension/UserData.swift +++ b/openHABWatch Extension/openHABWatch Extension/UserData.swift @@ -17,7 +17,7 @@ import os.log import SwiftUI final class UserData: ObservableObject { - @Published var widgets: [ObservableOpenHABWidget] = [] + @Published var widgets: [OpenHABWidget] = [] @Published var showAlert = false @Published var errorDescription = "" @Published var showCertificateAlert = false From 52fb51d390eab409a136cfab1c4f4d63b6e12ee6 Mon Sep 17 00:00:00 2001 From: Tim Bert <5411131+timbms@users.noreply.github.com> Date: Sun, 15 Sep 2024 20:47:09 +0200 Subject: [PATCH 10/13] Getting rid of ObservableOpenHABSitemapPage for watch --- openHAB.xcodeproj/project.pbxproj | 18 +- .../Views/Utils/MapView.swift | 4 +- .../Model/ObservableOpenHABSitemapPage.swift | 98 ------ .../Model/ObservableOpenHABWidget.swift | 283 ------------------ ...ion.swift => OpenHABWidgetExtension.swift} | 0 .../openHABWatch Extension/UserData.swift | 6 +- 6 files changed, 9 insertions(+), 400 deletions(-) delete mode 100644 openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABSitemapPage.swift delete mode 100644 openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift rename openHABWatch Extension/openHABWatch Extension/Model/{ObservableOpenHABWidgetExtension.swift => OpenHABWidgetExtension.swift} (100%) diff --git a/openHAB.xcodeproj/project.pbxproj b/openHAB.xcodeproj/project.pbxproj index 390b7423..bfe15fd3 100644 --- a/openHAB.xcodeproj/project.pbxproj +++ b/openHAB.xcodeproj/project.pbxproj @@ -27,8 +27,6 @@ 934E592728F16EBA00162004 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 934E592628F16EBA00162004 /* Kingfisher */; }; 934E592928F16EBA00162004 /* DeviceKit in Frameworks */ = {isa = PBXBuildFile; productRef = 934E592828F16EBA00162004 /* DeviceKit */; }; 934E592B28F16EBA00162004 /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = 934E592A28F16EBA00162004 /* Alamofire */; }; - 9350F17923814FAC00054BA8 /* ObservableOpenHABWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9350F17723814FAC00054BA8 /* ObservableOpenHABWidget.swift */; }; - 9350F17A23814FAC00054BA8 /* ObservableOpenHABSitemapPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9350F17823814FAC00054BA8 /* ObservableOpenHABSitemapPage.swift */; }; 935B484625342B8E00E44CF0 /* URL+Static.swift in Sources */ = {isa = PBXBuildFile; fileRef = 935B484525342B8E00E44CF0 /* URL+Static.swift */; }; 93685A7A2ADE755C0077A9A6 /* openHABTests.xctestplan in Resources */ = {isa = PBXBuildFile; fileRef = 93685A792ADE755C0077A9A6 /* openHABTests.xctestplan */; }; 937C8B0C2800A738009C055E /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 935D340A257B7DC00020A404 /* Intents.intentdefinition */; }; @@ -121,13 +119,12 @@ DAC6608D236F771600F4501E /* PreferencesSwiftUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC6608C236F771600F4501E /* PreferencesSwiftUIView.swift */; }; DAC6608F236F80BA00F4501E /* PreferencesRowUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC6608E236F80BA00F4501E /* PreferencesRowUIView.swift */; }; DAC9395522B00E7600C5F423 /* XCTestCaseExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC9395422B00E7600C5F423 /* XCTestCaseExtension.swift */; }; - DAC9AF4724F9669F006DAE93 /* ObservableOpenHABWidgetExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC9AF4624F9669F006DAE93 /* ObservableOpenHABWidgetExtension.swift */; }; + DAC9AF4724F9669F006DAE93 /* OpenHABWidgetExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC9AF4624F9669F006DAE93 /* OpenHABWidgetExtension.swift */; }; DAC9AF4924F966FA006DAE93 /* LazyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC9AF4824F966FA006DAE93 /* LazyView.swift */; }; DACB636227D3FC6500041931 /* error.png in Resources */ = {isa = PBXBuildFile; fileRef = DACB636127D3FC6500041931 /* error.png */; }; DACB636327D3FC6500041931 /* error.png in Resources */ = {isa = PBXBuildFile; fileRef = DACB636127D3FC6500041931 /* error.png */; }; DACE664A2C63B0760069E514 /* OpenAPIURLSession in Frameworks */ = {isa = PBXBuildFile; productRef = DACE66492C63B0760069E514 /* OpenAPIURLSession */; }; DACE664D2C63B0840069E514 /* OpenAPIRuntime in Frameworks */ = {isa = PBXBuildFile; productRef = DACE664C2C63B0840069E514 /* OpenAPIRuntime */; }; - DAEAA89B21E2611000267EA3 /* OpenHABNotificationsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAEAA89A21E2611000267EA3 /* OpenHABNotificationsViewController.swift */; }; DAEAA89D21E6B06400267EA3 /* ReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAEAA89C21E6B06300267EA3 /* ReusableView.swift */; }; DAEAA89F21E6B16600267EA3 /* UITableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAEAA89E21E6B16600267EA3 /* UITableView.swift */; }; DAF0A28B2C56E3A300A14A6A /* RollershutterCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAF0A28A2C56E3A300A14A6A /* RollershutterCell.swift */; }; @@ -295,8 +292,6 @@ 933D7F0822E7015100621A03 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 933D7F0E22E7030600621A03 /* SnapshotHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SnapshotHelper.swift; path = fastlane/SnapshotHelper.swift; sourceTree = SOURCE_ROOT; }; 934B610B2348D2F9009112D5 /* Color+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Color+Extension.swift"; sourceTree = ""; }; - 9350F17723814FAC00054BA8 /* ObservableOpenHABWidget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObservableOpenHABWidget.swift; sourceTree = ""; }; - 9350F17823814FAC00054BA8 /* ObservableOpenHABSitemapPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObservableOpenHABSitemapPage.swift; sourceTree = ""; }; 935B484525342B8E00E44CF0 /* URL+Static.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+Static.swift"; sourceTree = ""; }; 935D3412257B7E2F0020A404 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = Resources/nl.lproj/Intents.strings; sourceTree = ""; }; 935D3419257B7E820020A404 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; name = Base; path = Resources/Base.lproj/Intents.intentdefinition; sourceTree = ""; }; @@ -415,7 +410,7 @@ DAC6608E236F80BA00F4501E /* PreferencesRowUIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesRowUIView.swift; sourceTree = ""; }; DAC9394322AD4A7A00C5F423 /* OpenHABWatchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenHABWatchTests.swift; sourceTree = ""; }; DAC9395422B00E7600C5F423 /* XCTestCaseExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTestCaseExtension.swift; sourceTree = ""; }; - DAC9AF4624F9669F006DAE93 /* ObservableOpenHABWidgetExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObservableOpenHABWidgetExtension.swift; sourceTree = ""; }; + DAC9AF4624F9669F006DAE93 /* OpenHABWidgetExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenHABWidgetExtension.swift; sourceTree = ""; }; DAC9AF4824F966FA006DAE93 /* LazyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LazyView.swift; sourceTree = ""; }; DACB636127D3FC6500041931 /* error.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = error.png; sourceTree = ""; }; DAD488B2287DDDFE00414693 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Interface.strings; sourceTree = ""; }; @@ -444,7 +439,6 @@ DAF4581D23DC60020018B495 /* ImageRawRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageRawRow.swift; sourceTree = ""; }; DAF4F6BF222734D200C24876 /* NewImageUITableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewImageUITableViewCell.swift; sourceTree = ""; }; DAF6F4112C67E83B0083883E /* openapiCorrected.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = openapiCorrected.json; sourceTree = ""; }; - DF05EF111D00696200DD646D /* DrawerUITableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DrawerUITableViewCell.swift; sourceTree = ""; }; DF05FF221896BD2D00FF2F9B /* SelectionUITableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectionUITableViewCell.swift; sourceTree = ""; }; DF06F1FB18FEC2020011E7B9 /* ColorPickerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorPickerViewController.swift; sourceTree = ""; }; DF1B302C1CF5C667009C921C /* OpenHABNotification.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpenHABNotification.swift; sourceTree = ""; }; @@ -641,10 +635,8 @@ isa = PBXGroup; children = ( DA15BFBC23C6726400BD8ADA /* ObservableOpenHABDataObject.swift */, - 9350F17823814FAC00054BA8 /* ObservableOpenHABSitemapPage.swift */, - 9350F17723814FAC00054BA8 /* ObservableOpenHABWidget.swift */, DA9721C224E29A8F0092CCFD /* UserDefaultsBacked.swift */, - DAC9AF4624F9669F006DAE93 /* ObservableOpenHABWidgetExtension.swift */, + DAC9AF4624F9669F006DAE93 /* OpenHABWidgetExtension.swift */, DAC9AF4824F966FA006DAE93 /* LazyView.swift */, ); name = Model; @@ -1399,7 +1391,7 @@ buildActionMask = 2147483647; files = ( DA7649DE23FC81A20085CE46 /* Unwrap.swift in Sources */, - DAC9AF4724F9669F006DAE93 /* ObservableOpenHABWidgetExtension.swift in Sources */, + DAC9AF4724F9669F006DAE93 /* OpenHABWidgetExtension.swift in Sources */, DAF4581423DC1F5D0018B495 /* AppState.swift in Sources */, DA2E0B0E23DCC153009B0A99 /* MapView.swift in Sources */, DA2E0B1023DCC439009B0A99 /* MapViewRow.swift in Sources */, @@ -1422,7 +1414,6 @@ DA07752B2346705F0086C685 /* ExtensionDelegate.swift in Sources */, DAF4581623DC48400018B495 /* GenericRow.swift in Sources */, DAC6608F236F80BA00F4501E /* PreferencesRowUIView.swift in Sources */, - 9350F17A23814FAC00054BA8 /* ObservableOpenHABSitemapPage.swift in Sources */, DAF457A023DA3E1C0018B495 /* SegmentRow.swift in Sources */, DAF4578923D79AA50018B495 /* DetailTextLabelView.swift in Sources */, DA15BFBD23C6726400BD8ADA /* ObservableOpenHABDataObject.swift in Sources */, @@ -1433,7 +1424,6 @@ DA50C7BD2B0A51BD0009F716 /* SliderWithSwitchSupportRow.swift in Sources */, DAF457A623DB9CE00018B495 /* SetpointRow.swift in Sources */, DAF4581823DC4A050018B495 /* ImageRow.swift in Sources */, - 9350F17923814FAC00054BA8 /* ObservableOpenHABWidget.swift in Sources */, DA07752F2346705F0086C685 /* NotificationView.swift in Sources */, DA0775312346705F0086C685 /* ComplicationController.swift in Sources */, DAF4578523D7807A0018B495 /* Color+Extension.swift in Sources */, diff --git a/openHABWatch Extension/Views/Utils/MapView.swift b/openHABWatch Extension/Views/Utils/MapView.swift index 4d8966a7..12fba262 100644 --- a/openHABWatch Extension/Views/Utils/MapView.swift +++ b/openHABWatch Extension/Views/Utils/MapView.swift @@ -38,10 +38,10 @@ struct MapView: View { } } - struct MapView_Previews: PreviewProvider { +struct MapView_Previews: PreviewProvider { static var previews: some View { let widget = UserData().widgets[9] return MapView(widget: widget) .previewDevice("Apple Watch Series 5 - 44mm") } - } +} diff --git a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABSitemapPage.swift b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABSitemapPage.swift deleted file mode 100644 index 39c09267..00000000 --- a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABSitemapPage.swift +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2010-2024 Contributors to the openHAB project -// -// See the NOTICE file(s) distributed with this work for additional -// information. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0 -// -// SPDX-License-Identifier: EPL-2.0 - -import Foundation -import OpenHABCore -import os.log - -class ObservableOpenHABSitemapPage: NSObject { - var sendCommand: ((_ item: OpenHABItem, _ command: String?) -> Void)? - var widgets: [OpenHABWidget] = [] - var pageId = "" - var title = "" - var link = "" - var leaf = false - - init(pageId: String, title: String, link: String, leaf: Bool, widgets: [OpenHABWidget]) { - super.init() - self.pageId = pageId - self.title = title - self.link = link - self.leaf = leaf - var tempWidgets = [OpenHABWidget]() - tempWidgets.flatten(widgets) - self.widgets = tempWidgets - for widget in self.widgets { - widget.sendCommand = { [weak self] item, command in - self?.sendCommand(item, commandToSend: command) - } - } - } - - init(pageId: String, title: String, link: String, leaf: Bool, expandedWidgets: [OpenHABWidget]) { - super.init() - self.pageId = pageId - self.title = title - self.link = link - self.leaf = leaf - widgets = expandedWidgets - for widget in widgets { - widget.sendCommand = { [weak self] item, command in - self?.sendCommand(item, commandToSend: command) - } - } - } - - private func sendCommand(_ item: OpenHABItem?, commandToSend command: String?) { - guard let item else { return } - - os_log("SitemapPage sending command %{PUBLIC}@ to %{PUBLIC}@", log: OSLog.remoteAccess, type: .info, command ?? "", item.name) - sendCommand?(item, command) - } -} - -extension ObservableOpenHABSitemapPage { - struct CodingData: Decodable { - let pageId: String? - let title: String? - let link: String? - let leaf: Bool? - let widgets: [OpenHABWidget.CodingData]? - - private enum CodingKeys: String, CodingKey { - case pageId = "id" - case title - case link - case leaf - case widgets - } - } -} - -extension ObservableOpenHABSitemapPage.CodingData { - var openHABSitemapPage: ObservableOpenHABSitemapPage { - let mappedWidgets = widgets?.map(\.openHABWidget) ?? [] - return ObservableOpenHABSitemapPage(pageId: pageId ?? "", title: title ?? "", link: link ?? "", leaf: leaf ?? false, widgets: mappedWidgets) - } -} - -extension ObservableOpenHABSitemapPage { - func filter(_ isIncluded: (OpenHABWidget) throws -> Bool) rethrows -> ObservableOpenHABSitemapPage { - let filteredOpenHABSitemapPage = try ObservableOpenHABSitemapPage( - pageId: pageId, - title: title, - link: link, - leaf: leaf, - expandedWidgets: widgets.filter(isIncluded) - ) - return filteredOpenHABSitemapPage - } -} diff --git a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift b/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift deleted file mode 100644 index 9adf56fe..00000000 --- a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidget.swift +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright (c) 2010-2024 Contributors to the openHAB project -// -// See the NOTICE file(s) distributed with this work for additional -// information. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0 -// -// SPDX-License-Identifier: EPL-2.0 - -import Alamofire -#if canImport(Combine) -import Combine -#endif -import Foundation -import MapKit -import OpenHABCore -import os.log - -@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *) -class ObservableOpenHABWidget: NSObject, MKAnnotation, Identifiable, ObservableObject { - var id: String = "" - - var sendCommand: ((_ item: OpenHABItem, _ command: String?) -> Void)? - var widgetId = "" - @Published var label = "" - var icon = "" - var type = "" - var url = "" - var period = "" - var minValue = 0.0 - var maxValue = 100.0 - var step = 1.0 - var refresh = 0 - var height = 44.0 - var isLeaf = false - var iconColor = "" - var labelcolor = "" - var valuecolor = "" - var service = "" - @Published var state = "" - var text = "" - var legend: Bool? - var encoding = "" - @Published var item: OpenHABItem? - var linkedPage: OpenHABPage? - var mappings: [OpenHABWidgetMapping] = [] - var image: UIImage? - var widgets: [ObservableOpenHABWidget] = [] - public var visibility = true - public var switchSupport = false - public var forceAsItem: Bool? - - @Published public var stateEnumBinding: WidgetTypeEnum = .unassigned - - // Text prior to "[" - var labelText: String? { - let array = label.components(separatedBy: "[") - return array[0].trimmingCharacters(in: .whitespaces) - } - - // Text between square brackets - public var labelValue: String? { - let pattern = /\[(.*?)\]/.dotMatchesNewlines() - guard let firstMatch = label.firstMatch(of: pattern) else { return nil } - return String(firstMatch.1) - } - - var coordinate: CLLocationCoordinate2D { - item?.stateAsLocation()?.coordinate ?? kCLLocationCoordinate2DInvalid - } - - var mappingsOrItemOptions: [OpenHABWidgetMapping] { - if mappings.isEmpty, let commandOptions = item?.commandDescription?.commandOptions { - commandOptions.map { OpenHABWidgetMapping(command: $0.command, label: $0.label ?? "") } - } else if mappings.isEmpty, let stateOptions = item?.stateDescription?.options { - stateOptions.map { OpenHABWidgetMapping(command: $0.value, label: $0.label) } - } else { - mappings - } - } - - public var stateValueAsBool: Bool? { - item?.state?.parseAsBool() - } - - public var stateValueAsBrightness: Int? { - item?.state?.parseAsBrightness() - } - - public var stateValueAsUIColor: UIColor? { - item?.state?.parseAsUIColor() - } - - public var stateValueAsNumberState: NumberState? { - item?.state?.parseAsNumber(format: item?.stateDescription?.numberPattern) - } - - var adjustedValue: Double { - if let item { - adj(item.stateAsDouble()) - } else { - minValue - } - } - - var stateEnum: WidgetTypeEnum { - switch type { - case "Frame": - .frame - case "Switch": - // Reflecting the discussion held in https://github.com/openhab/openhab-core/issues/952 - if !mappings.isEmpty { - .segmented(Int(mappingIndex(byCommand: item?.state) ?? -1)) - } else if item?.isOfTypeOrGroupType(.switchItem) ?? false { - .switcher(item?.state == "ON" ? true : false) - } else if item?.isOfTypeOrGroupType(.rollershutter) ?? false { - .rollershutter - } else if !mappingsOrItemOptions.isEmpty { - .segmented(Int(mappingIndex(byCommand: item?.state) ?? -1)) - } else { - .switcher(item?.state == "ON" ? true : false) - } - case "Setpoint": - .setpoint - case "Slider": - .slider // (adjustedValue) - case "Selection": - .selection - case "Colorpicker": - .colorpicker - case "Chart": - .chart - case "Image": - .image - case "Video": - .video - case "Webview": - .webview - case "Mapview": - .mapview - default: - .unassigned - } - } - - public func sendItemUpdate(state: NumberState?) { - guard let item, let state else { - os_log("ItemUpdate for Item or State = nil", log: .default, type: .info) - return - } - if item.isOfTypeOrGroupType(.numberWithDimension) { - // For number items, include unit (if present) in command - sendCommand(state.toString(locale: Locale(identifier: "US"))) - } else { - // For all other items, send the plain value - sendCommand(state.stringValue) - } - } - - func sendCommandDouble(_ command: Double) { - sendCommand(String(command)) - } - - func sendCommand(_ command: String?) { - guard let item else { - os_log("Command for Item = nil", log: .default, type: .info) - return - } - guard let sendCommand else { - os_log("sendCommand closure not set", log: .default, type: .info) - return - } - sendCommand(item, command) - } - - func mappingIndex(byCommand command: String?) -> Int? { - mappingsOrItemOptions.firstIndex { $0.command == command } - } - - private func adj(_ raw: Double) -> Double { - var valueAdjustedToStep = floor((raw - minValue) / step) * step - valueAdjustedToStep += minValue - return valueAdjustedToStep.clamped(to: minValue ... maxValue) - } -} - -extension ObservableOpenHABWidget { - // This is an ugly initializer - convenience init(widgetId: String, label: String, icon: String, type: String, url: String?, period: String?, minValue: Double?, maxValue: Double?, step: Double?, refresh: Int?, height: Double?, isLeaf: Bool?, iconColor: String?, labelColor: String?, valueColor: String?, service: String?, state: String?, text: String?, legend: Bool?, encoding: String?, item: OpenHABItem?, linkedPage: OpenHABPage?, mappings: [OpenHABWidgetMapping], widgets: [ObservableOpenHABWidget], forceAsItem: Bool?) { - self.init() - - id = widgetId - - self.widgetId = widgetId - self.label = label - self.type = type - self.icon = icon - self.url = url ?? "" - self.period = period ?? "" - self.minValue = minValue ?? 0.0 - self.maxValue = maxValue ?? 100.0 - self.step = step ?? 1.0 - // Consider a minimal refresh rate of 100 ms, but 0 is special and means 'no refresh' - if let refreshVal = refresh, refreshVal > 0 { - self.refresh = max(100, refreshVal) - } else { - self.refresh = 0 - } - self.height = height ?? 44.0 - self.isLeaf = isLeaf ?? false - self.iconColor = iconColor ?? "" - labelcolor = labelColor ?? "" - valuecolor = valueColor ?? "" - self.service = service ?? "" - self.state = state ?? "" - self.text = text ?? "" - self.legend = legend - self.encoding = encoding ?? "" - self.item = item - self.linkedPage = linkedPage - self.mappings = mappings - self.widgets = widgets - - // Sanitize minValue, maxValue and step: min <= max, step >= 0 - self.maxValue = max(self.minValue, self.maxValue) - self.step = abs(self.step) - - self.forceAsItem = forceAsItem - - stateEnumBinding = stateEnum - } -} - -extension ObservableOpenHABWidget { - public struct CodingData: Decodable { - let widgetId: String - let label: String - let type: String - let icon: String - let url: String? - let period: String? - let minValue: Double? - let maxValue: Double? - let step: Double? - let refresh: Int? - let height: Double? - let isLeaf: Bool? - let iconColor: String? - let labelcolor: String? - let valuecolor: String? - let service: String? - let state: String? - let text: String? - let legend: Bool? - let encoding: String? - let groupType: String? - let item: OpenHABItem.CodingData? - let linkedPage: OpenHABPage.CodingData? - let mappings: [OpenHABWidgetMapping] - let widgets: [ObservableOpenHABWidget.CodingData] - let forceAsItem: Bool? - } -} - -extension ObservableOpenHABWidget.CodingData { - var openHABWidget: ObservableOpenHABWidget { - let mappedWidgets = widgets.map(\.openHABWidget) - // swiftlint:disable:next line_length - return ObservableOpenHABWidget(widgetId: widgetId, label: label, icon: icon, type: type, url: url, period: period, minValue: minValue, maxValue: maxValue, step: step, refresh: refresh, height: height, isLeaf: isLeaf, iconColor: iconColor, labelColor: labelcolor, valueColor: valuecolor, service: service, state: state, text: text, legend: legend, encoding: encoding, item: item?.openHABItem, linkedPage: linkedPage?.openHABSitemapPage, mappings: mappings, widgets: mappedWidgets, forceAsItem: forceAsItem) - } -} - -// Recursive parsing of nested widget structure -extension [OpenHABWidget] { - mutating func flatten(_ widgets: [Element]) { - for widget in widgets { - append(widget) - flatten(widget.widgets) - } - } -} diff --git a/openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidgetExtension.swift b/openHABWatch Extension/openHABWatch Extension/Model/OpenHABWidgetExtension.swift similarity index 100% rename from openHABWatch Extension/openHABWatch Extension/Model/ObservableOpenHABWidgetExtension.swift rename to openHABWatch Extension/openHABWatch Extension/Model/OpenHABWidgetExtension.swift diff --git a/openHABWatch Extension/openHABWatch Extension/UserData.swift b/openHABWatch Extension/openHABWatch Extension/UserData.swift index 10a64430..78c2d8a5 100644 --- a/openHABWatch Extension/openHABWatch Extension/UserData.swift +++ b/openHABWatch Extension/openHABWatch Extension/UserData.swift @@ -25,7 +25,7 @@ final class UserData: ObservableObject { let decoder = JSONDecoder() - var openHABSitemapPage: ObservableOpenHABSitemapPage? + var openHABSitemapPage: OpenHABPage? private var commandOperation: Alamofire.Request? private var currentPageOperation: Alamofire.Request? @@ -42,7 +42,7 @@ final class UserData: ObservableObject { // Self-executing closure // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift openHABSitemapPage = try { - let sitemapPageCodingData = try data.decoded(as: ObservableOpenHABSitemapPage.CodingData.self) + let sitemapPageCodingData = try data.decoded(as: OpenHABPage.CodingData.self) return sitemapPageCodingData.openHABSitemapPage }() } catch { @@ -111,7 +111,7 @@ final class UserData: ObservableObject { // Self-executing closure // Inspired by https://www.swiftbysundell.com/posts/inline-types-and-functions-in-swift openHABSitemapPage = try { - let sitemapPageCodingData = try data.decoded(as: ObservableOpenHABSitemapPage.CodingData.self) + let sitemapPageCodingData = try data.decoded(as: OpenHABPage.CodingData.self) return sitemapPageCodingData.openHABSitemapPage }() } catch { From 9d3c3a6b15fe9ed13fdf335812a1709fcbc9a5f8 Mon Sep 17 00:00:00 2001 From: Tim Bert <5411131+timbms@users.noreply.github.com> Date: Sun, 15 Sep 2024 20:51:32 +0200 Subject: [PATCH 11/13] Merge result --- .../xcshareddata/swiftpm/Package.resolved | 83 +------------------ 1 file changed, 1 insertion(+), 82 deletions(-) diff --git a/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved b/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved index 329446df..38af9155 100644 --- a/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "a0e070693d4bd70bdbabd8b73137d27ca8a0eee3a6c62258b0bf76ccac438c62", + "originHash" : "45c4b21381af160597cca953a315d1e460c404f7c9224de5f8844679c017063b", "pins" : [ { "identity" : "alamofire", @@ -19,60 +19,6 @@ "version" : "7.11.0" } }, - { - "identity" : "leveldb", - "kind" : "remoteSourceControl", - "location" : "https://github.com/firebase/leveldb.git", - "state" : { - "revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1", - "version" : "1.22.5" - } - }, - { - "identity" : "nanopb", - "kind" : "remoteSourceControl", - "location" : "https://github.com/firebase/nanopb.git", - "state" : { - "revision" : "b7e1104502eca3a213b46303391ca4d3bc8ddec1", - "version" : "2.30910.0" - } - }, - { - "identity" : "promises", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/promises.git", - "state" : { - "revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac", - "version" : "2.4.0" - } - }, - { - "identity" : "sfsafesymbols", - "kind" : "remoteSourceControl", - "location" : "https://github.com/SFSafeSymbols/SFSafeSymbols", - "state" : { - "revision" : "e2e28f4e56e1769c2ec3c61c9355fc64eb7a535a", - "version" : "5.3.0" - } - }, - { - "identity" : "sidemenu", - "kind" : "remoteSourceControl", - "location" : "https://github.com/jonkykong/SideMenu.git", - "state" : { - "revision" : "8bd4fd128923cf5494fa726839af8afe12908ad9", - "version" : "6.5.0" - } - }, - { - "identity" : "svgkit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/SVGKit/SVGKit.git", - "state" : { - "branch" : "3.x", - "revision" : "cf4dca96801dbbbdb2f37dc8c8571bfaf05c9d41" - } - }, { "identity" : "swift-collections", "kind" : "remoteSourceControl", @@ -91,15 +37,6 @@ "version" : "1.3.0" } }, - { - "identity" : "swift-log", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-log", - "state" : { - "revision" : "9cb486020ebf03bfa5b5df985387a14a98744537", - "version" : "1.6.1" - } - }, { "identity" : "swift-openapi-runtime", "kind" : "remoteSourceControl", @@ -117,24 +54,6 @@ "revision" : "9bf4c712ad7989d6a91dbe68748b8829a50837e4", "version" : "1.0.2" } - }, - { - "identity" : "swift-protobuf", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-protobuf.git", - "state" : { - "revision" : "edb6ed4919f7756157fe02f2552b7e3850a538e5", - "version" : "1.28.1" - } - }, - { - "identity" : "swiftmessages", - "kind" : "remoteSourceControl", - "location" : "https://github.com/SwiftKickMobile/SwiftMessages.git", - "state" : { - "revision" : "62e12e138fc3eedf88c7553dd5d98712aa119f40", - "version" : "9.0.9" - } } ], "version" : 3 From b6db98b23f56b878c733c125ef0931461be7d11c Mon Sep 17 00:00:00 2001 From: Tim Bert <5411131+timbms@users.noreply.github.com> Date: Mon, 16 Sep 2024 09:57:14 +0200 Subject: [PATCH 12/13] Properly testing decoding with swift-openapi-generator --- .../OpenHABCoreTests/JSONParserTests.swift | 22 +- .../xcshareddata/swiftpm/Package.resolved | 200 +++++++++++++++++- 2 files changed, 210 insertions(+), 12 deletions(-) diff --git a/OpenHABCore/Tests/OpenHABCoreTests/JSONParserTests.swift b/OpenHABCore/Tests/OpenHABCoreTests/JSONParserTests.swift index dca4e4b7..7b24f661 100644 --- a/OpenHABCore/Tests/OpenHABCoreTests/JSONParserTests.swift +++ b/OpenHABCore/Tests/OpenHABCoreTests/JSONParserTests.swift @@ -32,8 +32,8 @@ final class JSONParserTests: XCTestCase { func testJSONSitemapDecoder() { let data = Data(jsonSitemap3.utf8) do { - let codingData = try decoder.decode([OpenHABSitemap.CodingData].self, from: data) - XCTAssertEqual(codingData[0].openHABSitemap.homepageLink, "https://192.168.2.63:8444/rest/sitemaps/myHome/myHome", "Sitemap properly parsed") + let codingData = try decoder.decode([Components.Schemas.SitemapDTO].self, from: data) + XCTAssertEqual(codingData[0].homepage?.link, "https://192.168.2.63:8444/rest/sitemaps/myHome/myHome", "Sitemap properly parsed") } catch { XCTFail("Whoops, an error occured: \(error)") } @@ -47,8 +47,8 @@ final class JSONParserTests: XCTestCase { """ let data = Data(json.utf8) do { - let codingData = try decoder.decode([OpenHABSitemap.CodingData].self, from: data) - XCTAssertEqual(codingData[0].openHABSitemap.homepageLink, "http://192.xxx:8080/rest/sitemaps/Haus/Haus", "Sitemap properly parsed") + let codingData = try decoder.decode([Components.Schemas.SitemapDTO].self, from: data) + XCTAssertEqual(codingData[0].homepage?.link, "http://192.xxx:8080/rest/sitemaps/Haus/Haus", "Sitemap properly parsed") } catch { XCTFail("Whoops, an error occured: \(error)") } @@ -384,8 +384,8 @@ final class JSONParserTests: XCTestCase { {"name":"watch","label":"watch","link":"https://192.168.2.15:8444/rest/sitemaps/watch","homepage":{"id":"watch","title":"watch","link":"https://192.168.2.15:8444/rest/sitemaps/watch/watch","leaf":false,"timeout":false,"widgets":[{"widgetId":"00","type":"Frame","label":"Ground floor","icon":"frame","mappings":[],"widgets":[{"widgetId":"0000","type":"Switch","label":"Licht Oberlicht","icon":"switch","mappings":[],"item":{"link":"https://192.168.2.15:8444/rest/items/lcnLightSwitch14_1","state":"OFF","editable":false,"type":"Switch","name":"lcnLightSwitch14_1","label":"Licht Oberlicht","tags":["Lighting"],"groupNames":["G_PresenceSimulation","gLcn"]},"widgets":[]},{"widgetId":"0001","type":"Switch","label":"Licht Keller WC Decke","icon":"colorpicker","mappings":[],"item":{"link":"https://192.168.2.15:8444/rest/items/lcnLightSwitch6_1","state":"OFF","editable":false,"type":"Switch","name":"lcnLightSwitch6_1","label":"Licht Keller WC Decke","category":"colorpicker","tags":["Lighting"],"groupNames":["gKellerLicht","gLcn"]},"widgets":[]}]}]}} """.data(using: .utf8)! do { - let codingData = try decoder.decode(OpenHABSitemap.CodingData.self, from: json) - XCTAssertEqual(codingData.page?.link, "https://192.168.2.15:8444/rest/sitemaps/watch/watch", "OpenHABSitemapPage properly parsed") + let codingData = try decoder.decode(Components.Schemas.SitemapDTO.self, from: json) + XCTAssertEqual(codingData.homepage?.link, "https://192.168.2.15:8444/rest/sitemaps/watch/watch", "OpenHABSitemapPage properly parsed") // XCTAssert(codingData.openHABSitemapPage. widgets[0].type == "Frame", "") // XCTAssert(.widgets[0].linkedPage?.pageId == "0000", "widget properly parsed") } catch { @@ -481,7 +481,7 @@ final class JSONParserTests: XCTestCase { signpostID: signpostID, "Begin" ) - let codingData = try decoder.decode(OpenHABSitemap.CodingData.self, from: contents) + let codingData = try decoder.decode(Components.Schemas.SitemapDTO.self, from: contents) os_signpost( .end, log: log, @@ -490,13 +490,13 @@ final class JSONParserTests: XCTestCase { "End" ) - let widgets: [OpenHABWidget.CodingData] = try XCTUnwrap(codingData.page?.widgets) + let widgets = try XCTUnwrap(codingData.homepage?.widgets) let widget = widgets[0] XCTAssertEqual(widget.label, "Flat Scenes") - XCTAssertEqual(widget.widgets[0].label, "Scenes") - XCTAssertEqual(codingData.page?.link, "https://192.168.0.9:8443/rest/sitemaps/default/default") + XCTAssertEqual(widget.widgets?[0].label, "Scenes") + XCTAssertEqual(codingData.homepage?.link, "https://192.168.0.9:8443/rest/sitemaps/default/default") let widget2 = widgets[10] - XCTAssertEqual(widget2.widgets[0].label, "Admin Items") + XCTAssertEqual(widget2.widgets?[0].label, "Admin Items") } } diff --git a/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved b/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved index 38af9155..ef5149f8 100644 --- a/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/openHAB.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,6 +1,15 @@ { - "originHash" : "45c4b21381af160597cca953a315d1e460c404f7c9224de5f8844679c017063b", + "originHash" : "a0e070693d4bd70bdbabd8b73137d27ca8a0eee3a6c62258b0bf76ccac438c62", "pins" : [ + { + "identity" : "abseil-cpp-binary", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/abseil-cpp-binary.git", + "state" : { + "revision" : "194a6706acbd25e4ef639bcaddea16e8758a3e27", + "version" : "1.2024011602.0" + } + }, { "identity" : "alamofire", "kind" : "remoteSourceControl", @@ -10,6 +19,114 @@ "version" : "5.9.1" } }, + { + "identity" : "alamofirenetworkactivityindicator", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Alamofire/AlamofireNetworkActivityIndicator.git", + "state" : { + "revision" : "392bed083e8d193aca16bfa684ee24e4bcff0510", + "version" : "3.1.0" + } + }, + { + "identity" : "app-check", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/app-check.git", + "state" : { + "revision" : "3b62f154d00019ae29a71e9738800bb6f18b236d", + "version" : "10.19.2" + } + }, + { + "identity" : "cocoalumberjack", + "kind" : "remoteSourceControl", + "location" : "https://github.com/CocoaLumberjack/CocoaLumberjack.git", + "state" : { + "revision" : "4b8714a7fb84d42393314ce897127b3939885ec3", + "version" : "3.8.5" + } + }, + { + "identity" : "devicekit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/devicekit/DeviceKit.git", + "state" : { + "revision" : "d37e70cb2646666dcf276d7d3d4a9760a41ff8a6", + "version" : "4.9.0" + } + }, + { + "identity" : "firebase-ios-sdk", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/firebase-ios-sdk.git", + "state" : { + "revision" : "eca84fd638116dd6adb633b5a3f31cc7befcbb7d", + "version" : "10.29.0" + } + }, + { + "identity" : "flexcolorpicker", + "kind" : "remoteSourceControl", + "location" : "https://github.com/RastislavMirek/FlexColorPicker.git", + "state" : { + "revision" : "72a5c2c5e28074e6c5f13efe3c98eb780ae2f906", + "version" : "1.4.4" + } + }, + { + "identity" : "googleappmeasurement", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleAppMeasurement.git", + "state" : { + "revision" : "fe727587518729046fc1465625b9afd80b5ab361", + "version" : "10.28.0" + } + }, + { + "identity" : "googledatatransport", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleDataTransport.git", + "state" : { + "revision" : "a637d318ae7ae246b02d7305121275bc75ed5565", + "version" : "9.4.0" + } + }, + { + "identity" : "googleutilities", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleUtilities.git", + "state" : { + "revision" : "57a1d307f42df690fdef2637f3e5b776da02aad6", + "version" : "7.13.3" + } + }, + { + "identity" : "grpc-binary", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/grpc-binary.git", + "state" : { + "revision" : "e9fad491d0673bdda7063a0341fb6b47a30c5359", + "version" : "1.62.2" + } + }, + { + "identity" : "gtm-session-fetcher", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/gtm-session-fetcher.git", + "state" : { + "revision" : "a2ab612cb980066ee56d90d60d8462992c07f24b", + "version" : "3.5.0" + } + }, + { + "identity" : "interop-ios-for-google-sdks", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/interop-ios-for-google-sdks.git", + "state" : { + "revision" : "2d12673670417654f08f5f90fdd62926dc3a2648", + "version" : "100.0.0" + } + }, { "identity" : "kingfisher", "kind" : "remoteSourceControl", @@ -19,6 +136,60 @@ "version" : "7.11.0" } }, + { + "identity" : "leveldb", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/leveldb.git", + "state" : { + "revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1", + "version" : "1.22.5" + } + }, + { + "identity" : "nanopb", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/nanopb.git", + "state" : { + "revision" : "b7e1104502eca3a213b46303391ca4d3bc8ddec1", + "version" : "2.30910.0" + } + }, + { + "identity" : "promises", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/promises.git", + "state" : { + "revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac", + "version" : "2.4.0" + } + }, + { + "identity" : "sfsafesymbols", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SFSafeSymbols/SFSafeSymbols", + "state" : { + "revision" : "e2e28f4e56e1769c2ec3c61c9355fc64eb7a535a", + "version" : "5.3.0" + } + }, + { + "identity" : "sidemenu", + "kind" : "remoteSourceControl", + "location" : "https://github.com/jonkykong/SideMenu.git", + "state" : { + "revision" : "8bd4fd128923cf5494fa726839af8afe12908ad9", + "version" : "6.5.0" + } + }, + { + "identity" : "svgkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SVGKit/SVGKit.git", + "state" : { + "branch" : "3.x", + "revision" : "cf4dca96801dbbbdb2f37dc8c8571bfaf05c9d41" + } + }, { "identity" : "swift-collections", "kind" : "remoteSourceControl", @@ -37,6 +208,15 @@ "version" : "1.3.0" } }, + { + "identity" : "swift-log", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-log", + "state" : { + "revision" : "9cb486020ebf03bfa5b5df985387a14a98744537", + "version" : "1.6.1" + } + }, { "identity" : "swift-openapi-runtime", "kind" : "remoteSourceControl", @@ -54,6 +234,24 @@ "revision" : "9bf4c712ad7989d6a91dbe68748b8829a50837e4", "version" : "1.0.2" } + }, + { + "identity" : "swift-protobuf", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-protobuf.git", + "state" : { + "revision" : "edb6ed4919f7756157fe02f2552b7e3850a538e5", + "version" : "1.28.1" + } + }, + { + "identity" : "swiftmessages", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SwiftKickMobile/SwiftMessages.git", + "state" : { + "revision" : "62e12e138fc3eedf88c7553dd5d98712aa119f40", + "version" : "9.0.9" + } } ], "version" : 3 From 4514c569202d8f783a1711bc202548dafed94bec Mon Sep 17 00:00:00 2001 From: Tim Bert <5411131+timbms@users.noreply.github.com> Date: Mon, 16 Sep 2024 18:14:07 +0200 Subject: [PATCH 13/13] Properly showing selected state in SelectionView --- openHAB/OpenHABSitemapViewController.swift | 9 +++------ openHAB/SelectionView.swift | 19 +++++++++++-------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/openHAB/OpenHABSitemapViewController.swift b/openHAB/OpenHABSitemapViewController.swift index c0fb4599..15e3a217 100644 --- a/openHAB/OpenHABSitemapViewController.swift +++ b/openHAB/OpenHABSitemapViewController.swift @@ -776,16 +776,13 @@ extension OpenHABSitemapViewController: UITableViewDelegate, UITableViewDataSour newViewController.openHABRootUrl = openHABRootUrl navigationController?.pushViewController(newViewController, animated: true) } else if widget?.type == .selection { - os_log("Selected selection widget", log: .viewCycle, type: .info) selectedWidgetRow = indexPath.row let selectedWidget: OpenHABWidget? = relevantWidget(indexPath: indexPath) + let selectionItemState = selectedWidget?.item?.state + logger.info("Selected selection widget in status: \(selectionItemState ?? "unknown")") let hostingController = UIHostingController(rootView: SelectionView( mappings: selectedWidget?.mappingsOrItemOptions ?? [], - selectionItem: - Binding( - get: { selectedWidget?.item }, - set: { selectedWidget?.item = $0 } - ), + selectionItemState: selectionItemState, onSelection: { selectedMappingIndex in let selectedWidget: OpenHABWidget? = self.relevantPage?.widgets[self.selectedWidgetRow] let selectedMapping: OpenHABWidgetMapping? = selectedWidget?.mappingsOrItemOptions[selectedMappingIndex] diff --git a/openHAB/SelectionView.swift b/openHAB/SelectionView.swift index cd8c2d38..ad31af6d 100644 --- a/openHAB/SelectionView.swift +++ b/openHAB/SelectionView.swift @@ -15,39 +15,42 @@ import SwiftUI struct SelectionView: View { var mappings: [OpenHABWidgetMapping] // List of mappings (instead of AnyHashable, we use a concrete type) - @Binding var selectionItem: OpenHABItem? // Binding to track the selected item state + @State var selectionItemState: String? // To track the selected item state var onSelection: (Int) -> Void // Closure to handle selection + private let logger = Logger(subsystem: "org.openhab.app", category: "SelectionView") + var body: some View { List(0 ..< mappings.count, id: \.self) { index in let mapping = mappings[index] HStack { Text(mapping.label) Spacer() - if selectionItem?.state == mapping.command { + if selectionItemState == mapping.command { Image(systemSymbol: .checkmark) .foregroundColor(.blue) } } - .contentShape(Rectangle()) // Ensures entire row is tappable + .contentShape(.interaction, Rectangle()) // Ensures entire row is tappable .onTapGesture { - os_log("Selected mapping %d", log: .viewCycle, type: .info, index) + selectionItemState = mappings[index].command + logger.info("Selected mapping \(index)") onSelection(index) } + .accessibilityElement(children: .combine) + .accessibilityAddTraits(.isButton) } .navigationTitle("Select Mapping") // Navigation title } } #Preview { - let selectedItem: OpenHABItem? = OpenHABItem(name: "", type: "", state: "command2", link: "", label: nil, groupType: nil, stateDescription: nil, commandDescription: nil, members: [], category: nil, options: nil) - - return SelectionView( + SelectionView( mappings: [ OpenHABWidgetMapping(command: "command1", label: "Option 1"), OpenHABWidgetMapping(command: "command2", label: "Option 2") ], - selectionItem: .constant(selectedItem) + selectionItemState: "command2" ) { selectedMappingIndex in print("Selected mapping at index \(selectedMappingIndex)") }