From f4ac53e75f6e3378cbcca82ca539b6c8cf6eb686 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 2 Feb 2026 12:03:37 +0000 Subject: [PATCH 1/2] Add array-based enum parameters --- CHANGELOG.md | 4 + LICENSE | 2 +- README.md | 6 +- Sources/Appwrite/Channel.swift | 250 ++++++++++++++++++ Sources/Appwrite/Client.swift | 4 +- Sources/Appwrite/Query.swift | 58 ++++ Sources/Appwrite/Services/Account.swift | 7 +- Sources/Appwrite/Services/Avatars.swift | 8 +- Sources/Appwrite/Services/Databases.swift | 8 +- Sources/Appwrite/Services/Realtime.swift | 34 ++- Sources/Appwrite/Services/Teams.swift | 8 +- .../Appwrite/WebSockets/WebSocketClient.swift | 21 +- .../WebSockets/WebSocketClientDelegate.swift | 8 +- Sources/AppwriteEnums/BrowserPermission.swift | 28 ++ Sources/AppwriteEnums/OAuthProvider.swift | 1 - Sources/AppwriteEnums/Output.swift | 15 -- Sources/AppwriteEnums/Roles.swift | 11 + Sources/AppwriteModels/AlgoArgon2.swift | 4 - Sources/AppwriteModels/AlgoBcrypt.swift | 1 - Sources/AppwriteModels/AlgoMd5.swift | 1 - Sources/AppwriteModels/AlgoPhpass.swift | 1 - Sources/AppwriteModels/AlgoScrypt.swift | 5 - .../AppwriteModels/AlgoScryptModified.swift | 4 - Sources/AppwriteModels/AlgoSha.swift | 1 - Sources/AppwriteModels/Continent.swift | 2 - Sources/AppwriteModels/ContinentList.swift | 2 - Sources/AppwriteModels/Country.swift | 2 - Sources/AppwriteModels/CountryList.swift | 2 - Sources/AppwriteModels/Currency.swift | 7 - Sources/AppwriteModels/CurrencyList.swift | 2 - Sources/AppwriteModels/Document.swift | 7 - Sources/AppwriteModels/DocumentList.swift | 2 - Sources/AppwriteModels/Execution.swift | 18 -- Sources/AppwriteModels/ExecutionList.swift | 2 - Sources/AppwriteModels/File.swift | 35 ++- Sources/AppwriteModels/FileList.swift | 2 - Sources/AppwriteModels/Headers.swift | 2 - Sources/AppwriteModels/Identity.swift | 10 - Sources/AppwriteModels/IdentityList.swift | 2 - Sources/AppwriteModels/Jwt.swift | 1 - Sources/AppwriteModels/Language.swift | 3 - Sources/AppwriteModels/LanguageList.swift | 2 - Sources/AppwriteModels/Locale.swift | 7 - Sources/AppwriteModels/LocaleCode.swift | 2 - Sources/AppwriteModels/LocaleCodeList.swift | 2 - Sources/AppwriteModels/Log.swift | 21 -- Sources/AppwriteModels/LogList.swift | 2 - Sources/AppwriteModels/Membership.swift | 13 - Sources/AppwriteModels/MembershipList.swift | 2 - Sources/AppwriteModels/MfaChallenge.swift | 4 - Sources/AppwriteModels/MfaFactors.swift | 4 - Sources/AppwriteModels/MfaRecoveryCodes.swift | 1 - Sources/AppwriteModels/MfaType.swift | 2 - Sources/AppwriteModels/Phone.swift | 3 - Sources/AppwriteModels/PhoneList.swift | 2 - Sources/AppwriteModels/Row.swift | 7 - Sources/AppwriteModels/RowList.swift | 2 - Sources/AppwriteModels/Session.swift | 29 -- Sources/AppwriteModels/SessionList.swift | 2 - Sources/AppwriteModels/Subscriber.swift | 9 - Sources/AppwriteModels/Target.swift | 9 - Sources/AppwriteModels/Team.swift | 6 - Sources/AppwriteModels/TeamList.swift | 2 - Sources/AppwriteModels/Token.swift | 6 - Sources/AppwriteModels/Transaction.swift | 6 - Sources/AppwriteModels/TransactionList.swift | 2 - Sources/AppwriteModels/User.swift | 19 -- Sources/JSONCodable/Codable+JSON.swift | 1 - docs/examples/account/create-jwt.md | 4 +- docs/examples/avatars/get-screenshot.md | 8 +- docs/examples/databases/update-document.md | 8 +- docs/examples/databases/upsert-document.md | 8 +- docs/examples/tablesdb/update-row.md | 8 +- docs/examples/tablesdb/upsert-row.md | 8 +- docs/examples/teams/create-membership.md | 3 +- docs/examples/teams/update-membership.md | 3 +- 76 files changed, 475 insertions(+), 333 deletions(-) create mode 100644 Sources/Appwrite/Channel.swift create mode 100644 Sources/AppwriteEnums/BrowserPermission.swift delete mode 100644 Sources/AppwriteEnums/Output.swift create mode 100644 Sources/AppwriteEnums/Roles.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f4141c..22a5519 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## 14.0.0 + +* Add array-based enum parameters (e.g., `permissions: [BrowserPermission]`). + ## 13.5.0 * Add `getScreenshot` method to `Avatars` service diff --git a/LICENSE b/LICENSE index c1602fc..6f8702b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2025 Appwrite (https://appwrite.io) and individual contributors. +Copyright (c) 2026 Appwrite (https://appwrite.io) and individual contributors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/README.md b/README.md index a48b205..a0efa90 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,14 @@ ![Swift Package Manager](https://img.shields.io/github/v/release/appwrite/sdk-for-apple.svg?color=green&style=flat-square) ![License](https://img.shields.io/github/license/appwrite/sdk-for-apple.svg?style=flat-square) -![Version](https://img.shields.io/badge/api%20version-1.8.0-blue.svg?style=flat-square) +![Version](https://img.shields.io/badge/api%20version-1.8.1-blue.svg?style=flat-square) [![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator) [![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite) [![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord) **This SDK is compatible with Appwrite server version 1.8.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-apple/releases).** -Appwrite is an open-source backend as a service server that abstract and simplify complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Apple SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs) +Appwrite is an open-source backend as a service server that abstracts and simplifies complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Apple SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs) ![Appwrite](https://github.com/appwrite/appwrite/raw/main/public/images/github.png) @@ -31,7 +31,7 @@ Add the package to your `Package.swift` dependencies: ```swift dependencies: [ - .package(url: "git@github.com:appwrite/sdk-for-apple.git", from: "13.5.0"), + .package(url: "git@github.com:appwrite/sdk-for-apple.git", from: "14.0.0"), ], ``` diff --git a/Sources/Appwrite/Channel.swift b/Sources/Appwrite/Channel.swift new file mode 100644 index 0000000..49f02c2 --- /dev/null +++ b/Sources/Appwrite/Channel.swift @@ -0,0 +1,250 @@ +import Foundation + +// Marker structs for type safety (structs work with == constraints in extensions) +public struct _Root {} +public struct _Database {} +public struct _Collection {} +public struct _Document {} +public struct _TablesDB {} +public struct _Table {} +public struct _Row {} +public struct _Bucket {} +public struct _File {} +public struct _Func {} +public struct _Execution {} +public struct _Team {} +public struct _Membership {} +public struct _Resolved {} + +// Helper for normalizing IDs +private func normalize(_ id: String) -> String { + let trimmed = id.trimmingCharacters(in: .whitespacesAndNewlines) + return trimmed.isEmpty ? "*" : trimmed +} + +/// Channel class with generic type parameter for type-safe method chaining +public class RealtimeChannel { + private let segments: [String] + + internal init(_ segments: [String]) { + self.segments = segments + } + + /// Internal helper to transition to next state with segment and ID + internal func next(_ segment: String, _ id: String = "*") -> RealtimeChannel { + return RealtimeChannel(segments + [segment, normalize(id)]) + } + + /// Internal helper for terminal actions (no ID segment) + internal func resolve(_ action: String) -> RealtimeChannel<_Resolved> { + return RealtimeChannel<_Resolved>(segments + [action]) + } + + /// Convert channel to string representation + public func toString() -> String { + return segments.joined(separator: ".") + } +} + +/// Non-generic Channel enum for static factory methods +public enum Channel { + + // MARK: - Root Factories + + public static func database(_ id: String = "*") -> RealtimeChannel<_Database> { + return RealtimeChannel<_Database>(["databases", normalize(id)]) + } + + public static func tablesdb(_ id: String = "*") -> RealtimeChannel<_TablesDB> { + return RealtimeChannel<_TablesDB>(["tablesdb", normalize(id)]) + } + + public static func bucket(_ id: String = "*") -> RealtimeChannel<_Bucket> { + return RealtimeChannel<_Bucket>(["buckets", normalize(id)]) + } + + public static func function(_ id: String = "*") -> RealtimeChannel<_Func> { + return RealtimeChannel<_Func>(["functions", normalize(id)]) + } + + public static func team(_ id: String = "*") -> RealtimeChannel<_Team> { + return RealtimeChannel<_Team>(["teams", normalize(id)]) + } + + public static func membership(_ id: String = "*") -> RealtimeChannel<_Membership> { + return RealtimeChannel<_Membership>(["memberships", normalize(id)]) + } + + public static func account(_ userId: String = "") -> String { + let id = normalize(userId) + return id == "*" ? "account" : "account.\(id)" + } + + // Global events + public static func documents() -> String { "documents" } + public static func rows() -> String { "rows" } + public static func files() -> String { "files" } + public static func executions() -> String { "executions" } + public static func teams() -> String { "teams" } +} + +// MARK: - DATABASE ROUTE +// Protocol extensions restricted by receiver type + +/// Only available on RealtimeChannel<_Database> +extension RealtimeChannel where T == _Database { + public func collection(_ id: String = "*") -> RealtimeChannel<_Collection> { + return self.next("collections", id) + } +} + +/// Only available on RealtimeChannel<_Collection> +extension RealtimeChannel where T == _Collection { + public func document(_ id: String = "*") -> RealtimeChannel<_Document> { + return self.next("documents", id) + } +} + +// MARK: - TABLESDB ROUTE + +/// Only available on RealtimeChannel<_TablesDB> +extension RealtimeChannel where T == _TablesDB { + public func table(_ id: String = "*") -> RealtimeChannel<_Table> { + return self.next("tables", id) + } +} + +/// Only available on RealtimeChannel<_Table> +extension RealtimeChannel where T == _Table { + public func row(_ id: String = "*") -> RealtimeChannel<_Row> { + return self.next("rows", id) + } +} + +// MARK: - BUCKET ROUTE + +/// Only available on RealtimeChannel<_Bucket> +extension RealtimeChannel where T == _Bucket { + public func file(_ id: String = "*") -> RealtimeChannel<_File> { + return self.next("files", id) + } +} + +// MARK: - FUNCTION ROUTE + +/// Only available on RealtimeChannel<_Func> +extension RealtimeChannel where T == _Func { + public func execution(_ id: String = "*") -> RealtimeChannel<_Execution> { + return self.next("executions", id) + } +} + +// MARK: - TERMINAL ACTIONS +// Restricted to actionable types (_Document, _Row, _File, _Execution, _Team, _Membership) + +/// Only available on RealtimeChannel<_Document> +extension RealtimeChannel where T == _Document { + public func create() -> RealtimeChannel<_Resolved> { + return self.resolve("create") + } + + public func update() -> RealtimeChannel<_Resolved> { + return self.resolve("update") + } + + public func delete() -> RealtimeChannel<_Resolved> { + return self.resolve("delete") + } +} + +/// Only available on RealtimeChannel<_Row> +extension RealtimeChannel where T == _Row { + public func create() -> RealtimeChannel<_Resolved> { + return self.resolve("create") + } + + public func update() -> RealtimeChannel<_Resolved> { + return self.resolve("update") + } + + public func delete() -> RealtimeChannel<_Resolved> { + return self.resolve("delete") + } +} + +/// Only available on RealtimeChannel<_File> +extension RealtimeChannel where T == _File { + public func create() -> RealtimeChannel<_Resolved> { + return self.resolve("create") + } + + public func update() -> RealtimeChannel<_Resolved> { + return self.resolve("update") + } + + public func delete() -> RealtimeChannel<_Resolved> { + return self.resolve("delete") + } +} + +/// Only available on RealtimeChannel<_Execution> +extension RealtimeChannel where T == _Execution { + public func create() -> RealtimeChannel<_Resolved> { + return self.resolve("create") + } + + public func update() -> RealtimeChannel<_Resolved> { + return self.resolve("update") + } + + public func delete() -> RealtimeChannel<_Resolved> { + return self.resolve("delete") + } +} + +/// Only available on RealtimeChannel<_Team> +extension RealtimeChannel where T == _Team { + public func create() -> RealtimeChannel<_Resolved> { + return self.resolve("create") + } + + public func update() -> RealtimeChannel<_Resolved> { + return self.resolve("update") + } + + public func delete() -> RealtimeChannel<_Resolved> { + return self.resolve("delete") + } +} + +/// Only available on RealtimeChannel<_Membership> +extension RealtimeChannel where T == _Membership { + public func create() -> RealtimeChannel<_Resolved> { + return self.resolve("create") + } + + public func update() -> RealtimeChannel<_Resolved> { + return self.resolve("update") + } + + public func delete() -> RealtimeChannel<_Resolved> { + return self.resolve("delete") + } +} + +// MARK: - Protocol for backward compatibility + +/// Protocol for channel values that can be converted to strings +public protocol ChannelValue { + func toString() -> String +} + +// Make String conform to ChannelValue +extension String: ChannelValue { + public func toString() -> String { + return self + } +} + +// Make RealtimeChannel conform to ChannelValue +extension RealtimeChannel: ChannelValue {} diff --git a/Sources/Appwrite/Client.swift b/Sources/Appwrite/Client.swift index 26ae339..495c0ad 100644 --- a/Sources/Appwrite/Client.swift +++ b/Sources/Appwrite/Client.swift @@ -24,7 +24,7 @@ open class Client { "x-sdk-name": "Apple", "x-sdk-platform": "client", "x-sdk-language": "apple", - "x-sdk-version": "13.5.0", + "x-sdk-version": "14.0.0", "x-appwrite-response-format": "1.8.0" ] @@ -34,7 +34,6 @@ open class Client { internal var http: HTTPClient - private static let boundaryChars = "abcdefghijklmnopqrstuvwxyz1234567890" private static let boundary = randomBoundary() @@ -316,7 +315,6 @@ open class Client { var request = HTTPClientRequest(url: endPoint + path + queryParameters) request.method = .RAW(value: method) - for (key, value) in self.headers.merging(headers, uniquingKeysWith: { $1 }) { request.headers.add(name: key, value: value) } diff --git a/Sources/Appwrite/Query.swift b/Sources/Appwrite/Query.swift index 7610dc3..40bdbd7 100644 --- a/Sources/Appwrite/Query.swift +++ b/Sources/Appwrite/Query.swift @@ -165,6 +165,20 @@ public struct Query : Codable, CustomStringConvertible { ).description } + /// Filter resources where attribute matches a regular expression pattern. + /// + /// - Parameters: + /// - attribute: The attribute to filter on. + /// - pattern: The regular expression pattern to match. + /// - Returns: The query string. + public static func regex(_ attribute: String, pattern: String) -> String { + return Query( + method: "regex", + attribute: attribute, + values: [pattern] + ).description + } + public static func lessThan(_ attribute: String, value: Any) -> String { return Query( method: "lessThan", @@ -211,6 +225,28 @@ public struct Query : Codable, CustomStringConvertible { ).description } + /// Filter resources where the specified attributes exist. + /// + /// - Parameter attributes: The list of attributes that must exist. + /// - Returns: The query string. + public static func exists(_ attributes: [String]) -> String { + return Query( + method: "exists", + values: attributes + ).description + } + + /// Filter resources where the specified attributes do not exist. + /// + /// - Parameter attributes: The list of attributes that must not exist. + /// - Returns: The query string. + public static func notExists(_ attributes: [String]) -> String { + return Query( + method: "notExists", + values: attributes + ).description + } + public static func between(_ attribute: String, start: Int, end: Int) -> String { return Query( method: "between", @@ -432,6 +468,28 @@ public struct Query : Codable, CustomStringConvertible { ).description } + /// Filter array elements where at least one element matches all the specified queries. + /// + /// - Parameters: + /// - attribute: The attribute containing the array to filter on. + /// - queries: The list of query strings to match against array elements. + /// - Returns: The query string. + public static func elemMatch(_ attribute: String, queries: [String]) -> String { + let decoder = JSONDecoder() + let decodedQueries = queries.compactMap { queryStr -> Query? in + guard let data = queryStr.data(using: .utf8) else { + return nil + } + return try? decoder.decode(Query.self, from: data) + } + + return Query( + method: "elemMatch", + attribute: attribute, + values: decodedQueries + ).description + } + public static func distanceEqual(_ attribute: String, values: [Any], distance: Double, meters: Bool = true) -> String { return Query( method: "distanceEqual", diff --git a/Sources/Appwrite/Services/Account.swift b/Sources/Appwrite/Services/Account.swift index 90db63d..a05909f 100644 --- a/Sources/Appwrite/Services/Account.swift +++ b/Sources/Appwrite/Services/Account.swift @@ -272,14 +272,19 @@ open class Account: Service { /// from its creation and will be invalid if the user will logout in that time /// frame. /// + /// - Parameters: + /// - duration: Int (optional) /// - Throws: Exception if the request fails /// - Returns: AppwriteModels.Jwt /// open func createJWT( + duration: Int? = nil ) async throws -> AppwriteModels.Jwt { let apiPath: String = "/account/jwts" - let apiParams: [String: Any] = [:] + let apiParams: [String: Any?] = [ + "duration": duration + ] let apiHeaders: [String: String] = [ "content-type": "application/json" diff --git a/Sources/Appwrite/Services/Avatars.swift b/Sources/Appwrite/Services/Avatars.swift index b250ad2..7ec0d6a 100644 --- a/Sources/Appwrite/Services/Avatars.swift +++ b/Sources/Appwrite/Services/Avatars.swift @@ -317,12 +317,12 @@ open class Avatars: Service { /// - longitude: Double (optional) /// - accuracy: Double (optional) /// - touch: Bool (optional) - /// - permissions: [String] (optional) + /// - permissions: [AppwriteEnums.BrowserPermission] (optional) /// - sleep: Int (optional) /// - width: Int (optional) /// - height: Int (optional) /// - quality: Int (optional) - /// - output: AppwriteEnums.Output (optional) + /// - output: AppwriteEnums.ImageFormat (optional) /// - Throws: Exception if the request fails /// - Returns: ByteBuffer /// @@ -341,12 +341,12 @@ open class Avatars: Service { longitude: Double? = nil, accuracy: Double? = nil, touch: Bool? = nil, - permissions: [String]? = nil, + permissions: [AppwriteEnums.BrowserPermission]? = nil, sleep: Int? = nil, width: Int? = nil, height: Int? = nil, quality: Int? = nil, - output: AppwriteEnums.Output? = nil + output: AppwriteEnums.ImageFormat? = nil ) async throws -> ByteBuffer { let apiPath: String = "/avatars/screenshots" diff --git a/Sources/Appwrite/Services/Databases.swift b/Sources/Appwrite/Services/Databases.swift index 96d4846..2a9b52b 100644 --- a/Sources/Appwrite/Services/Databases.swift +++ b/Sources/Appwrite/Services/Databases.swift @@ -465,7 +465,7 @@ open class Databases: Service { /// - databaseId: String /// - collectionId: String /// - documentId: String - /// - data: Any + /// - data: Any (optional) /// - permissions: [String] (optional) /// - transactionId: String (optional) /// - Throws: Exception if the request fails @@ -476,7 +476,7 @@ open class Databases: Service { databaseId: String, collectionId: String, documentId: String, - data: Any, + data: Any? = nil, permissions: [String]? = nil, transactionId: String? = nil, nestedType: T.Type @@ -519,7 +519,7 @@ open class Databases: Service { /// - databaseId: String /// - collectionId: String /// - documentId: String - /// - data: Any + /// - data: Any (optional) /// - permissions: [String] (optional) /// - transactionId: String (optional) /// - Throws: Exception if the request fails @@ -530,7 +530,7 @@ open class Databases: Service { databaseId: String, collectionId: String, documentId: String, - data: Any, + data: Any? = nil, permissions: [String]? = nil, transactionId: String? = nil ) async throws -> AppwriteModels.Document<[String: AnyCodable]> { diff --git a/Sources/Appwrite/Services/Realtime.swift b/Sources/Appwrite/Services/Realtime.swift index 88be6ad..7595772 100644 --- a/Sources/Appwrite/Services/Realtime.swift +++ b/Sources/Appwrite/Services/Realtime.swift @@ -117,8 +117,16 @@ open class Realtime : Service { } } + /** + * Convert channel value to string + * All Channel instances and String conform to ChannelValue + */ + private func channelToString(_ channel: ChannelValue) -> String { + return channel.toString() + } + public func subscribe( - channel: String, + channel: ChannelValue, callback: @escaping (RealtimeResponseEvent) -> Void ) async throws -> RealtimeSubscription { return try await subscribe( @@ -129,23 +137,35 @@ open class Realtime : Service { } public func subscribe( - channels: Set, + channels: [ChannelValue], callback: @escaping (RealtimeResponseEvent) -> Void ) async throws -> RealtimeSubscription { return try await subscribe( - channels: channels, + channels: Set(channels.map { channelToString($0) }), payloadType: String.self, callback: callback ) } public func subscribe( - channel: String, + channel: ChannelValue, payloadType: T.Type, callback: @escaping (RealtimeResponseEvent) -> Void ) async throws -> RealtimeSubscription { return try await subscribe( - channels: [channel], + channels: Set([channelToString(channel)]), + payloadType: T.self, + callback: callback + ) + } + + public func subscribe( + channels: [ChannelValue], + payloadType: T.Type, + callback: @escaping (RealtimeResponseEvent) -> Void + ) async throws -> RealtimeSubscription { + return try await subscribe( + channels: Set(channels.map { channelToString($0) }), payloadType: T.self, callback: callback ) @@ -205,7 +225,7 @@ open class Realtime : Service { extension Realtime: WebSocketClientDelegate { - public func onOpen(channel: Channel) { + public func onOpen(channel: NIO.Channel) { self.reconnectAttempts = 0 onOpenCallbacks.forEach { $0() } startHeartbeat() @@ -225,7 +245,7 @@ extension Realtime: WebSocketClientDelegate { } } - public func onClose(channel: Channel, data: Data) async throws { + public func onClose(channel: NIO.Channel, data: Data) async throws { stopHeartbeat() onCloseCallbacks.forEach { $0() } diff --git a/Sources/Appwrite/Services/Teams.swift b/Sources/Appwrite/Services/Teams.swift index 54744d9..693c9e5 100644 --- a/Sources/Appwrite/Services/Teams.swift +++ b/Sources/Appwrite/Services/Teams.swift @@ -343,7 +343,7 @@ open class Teams: Service { /// /// - Parameters: /// - teamId: String - /// - roles: [String] + /// - roles: [AppwriteEnums.Roles] /// - email: String (optional) /// - userId: String (optional) /// - phone: String (optional) @@ -354,7 +354,7 @@ open class Teams: Service { /// open func createMembership( teamId: String, - roles: [String], + roles: [AppwriteEnums.Roles], email: String? = nil, userId: String? = nil, phone: String? = nil, @@ -435,14 +435,14 @@ open class Teams: Service { /// - Parameters: /// - teamId: String /// - membershipId: String - /// - roles: [String] + /// - roles: [AppwriteEnums.Roles] /// - Throws: Exception if the request fails /// - Returns: AppwriteModels.Membership /// open func updateMembership( teamId: String, membershipId: String, - roles: [String] + roles: [AppwriteEnums.Roles] ) async throws -> AppwriteModels.Membership { let apiPath: String = "/teams/{teamId}/memberships/{membershipId}" .replacingOccurrences(of: "{teamId}", with: teamId) diff --git a/Sources/Appwrite/WebSockets/WebSocketClient.swift b/Sources/Appwrite/WebSockets/WebSocketClient.swift index e28502e..7c004d2 100644 --- a/Sources/Appwrite/WebSockets/WebSocketClient.swift +++ b/Sources/Appwrite/WebSockets/WebSocketClient.swift @@ -32,7 +32,7 @@ public class WebSocketClient { private let channelQueue = DispatchQueue(label: WEBSOCKET_CHANNEL_QUEUE) private let threadGroupQueue = DispatchQueue(label: WEBSOCKET_THREAD_QUEUE) - var channel: Channel? { + var channel: NIOCore.Channel? { get { return channelQueue.sync { _channel } } @@ -40,7 +40,7 @@ public class WebSocketClient { channelQueue.sync { _channel = newValue } } } - private var _channel: Channel? = nil + private var _channel: NIOCore.Channel? = nil var threadGroup: MultiThreadedEventLoopGroup? { get { @@ -61,8 +61,8 @@ public class WebSocketClient { // MARK: - Stored callbacks - private var _openCallback: (Channel) -> Void = { _ in } - var onOpen: (Channel) -> Void { + private var _openCallback: (NIOCore.Channel) -> Void = { _ in } + var onOpen: (NIOCore.Channel) -> Void { get { return locker.sync { return _openCallback @@ -75,8 +75,8 @@ public class WebSocketClient { } } - private var _closeCallback: (Channel, Data) -> Void = { _,_ in } - var onClose: (Channel, Data) -> Void { + private var _closeCallback: (NIOCore.Channel, Data) -> Void = { _,_ in } + var onClose: (NIOCore.Channel, Data) -> Void { get { return locker.sync { return _closeCallback @@ -137,7 +137,7 @@ public class WebSocketClient { /// /// - parameters: /// - callback: Callback to fie when a WebSocket connection is opened - public func onOpen(_ callback: @escaping (Channel) -> Void) { + public func onOpen(_ callback: @escaping (NIOCore.Channel) -> Void) { onOpen = callback } @@ -161,7 +161,7 @@ public class WebSocketClient { /// /// - parameters: /// - callback: Callback to fie when a WebSocket close message is received - public func onClose(_ callback: @escaping (Channel, Data) -> Void) { + public func onClose(_ callback: @escaping (NIOCore.Channel, Data) -> Void) { onClose = callback } @@ -262,7 +262,7 @@ public class WebSocketClient { .get() } - private func openChannel(channel: Channel) -> EventLoopFuture { + private func openChannel(channel: NIOCore.Channel) -> EventLoopFuture { let httpHandler = HTTPHandler(client: self, headers: headers) let basicUpgrader = NIOWebSocketClientUpgrader( @@ -290,7 +290,7 @@ public class WebSocketClient { } } - private func upgradePipelineHandler(channel: Channel, response: HTTPResponseHead) -> EventLoopFuture { + private func upgradePipelineHandler(channel: NIOCore.Channel, response: HTTPResponseHead) -> EventLoopFuture { let handler = MessageHandler(client: self) if response.status == .switchingProtocols { @@ -387,7 +387,6 @@ public class WebSocketClient { ) } - /// Sends the JSON representation of the given model to the connected server in multiple frames. /// /// - parameters: diff --git a/Sources/Appwrite/WebSockets/WebSocketClientDelegate.swift b/Sources/Appwrite/WebSockets/WebSocketClientDelegate.swift index d1556ac..d6327e0 100644 --- a/Sources/Appwrite/WebSockets/WebSocketClientDelegate.swift +++ b/Sources/Appwrite/WebSockets/WebSocketClientDelegate.swift @@ -4,22 +4,22 @@ import NIOHTTP1 /// Handles messages received by a connected WebSocket server. public protocol WebSocketClientDelegate : AnyObject { - func onOpen(channel: Channel) + func onOpen(channel: NIOCore.Channel) func onMessage(text: String) throws func onMessage(data: Data) throws - func onClose(channel: Channel, data: Data) + func onClose(channel: NIOCore.Channel, data: Data) func onError(error: Swift.Error?, status: HTTPResponseStatus?) throws } // Add empty default implementations extension WebSocketClientDelegate { - public func onOpen(channel: Channel) { + public func onOpen(channel: NIOCore.Channel) { } public func onMessage(text: String) { } public func onMessage(data: Data) { } - public func onClose(channel: Channel, data: Data) { + public func onClose(channel: NIOCore.Channel, data: Data) { } public func onError(error: Swift.Error?, status: HTTPResponseStatus?) throws { } diff --git a/Sources/AppwriteEnums/BrowserPermission.swift b/Sources/AppwriteEnums/BrowserPermission.swift new file mode 100644 index 0000000..69143d7 --- /dev/null +++ b/Sources/AppwriteEnums/BrowserPermission.swift @@ -0,0 +1,28 @@ +import Foundation + +public enum BrowserPermission: String, CustomStringConvertible { + case geolocation = "geolocation" + case camera = "camera" + case microphone = "microphone" + case notifications = "notifications" + case midi = "midi" + case push = "push" + case clipboardRead = "clipboard-read" + case clipboardWrite = "clipboard-write" + case paymentHandler = "payment-handler" + case usb = "usb" + case bluetooth = "bluetooth" + case accelerometer = "accelerometer" + case gyroscope = "gyroscope" + case magnetometer = "magnetometer" + case ambientLightSensor = "ambient-light-sensor" + case backgroundSync = "background-sync" + case persistentStorage = "persistent-storage" + case screenWakeLock = "screen-wake-lock" + case webShare = "web-share" + case xrSpatialTracking = "xr-spatial-tracking" + + public var description: String { + return rawValue + } +} diff --git a/Sources/AppwriteEnums/OAuthProvider.swift b/Sources/AppwriteEnums/OAuthProvider.swift index 4c4ec6e..fb715a4 100644 --- a/Sources/AppwriteEnums/OAuthProvider.swift +++ b/Sources/AppwriteEnums/OAuthProvider.swift @@ -40,7 +40,6 @@ public enum OAuthProvider: String, CustomStringConvertible { case yandex = "yandex" case zoho = "zoho" case zoom = "zoom" - case mock = "mock" public var description: String { return rawValue diff --git a/Sources/AppwriteEnums/Output.swift b/Sources/AppwriteEnums/Output.swift deleted file mode 100644 index c8d245f..0000000 --- a/Sources/AppwriteEnums/Output.swift +++ /dev/null @@ -1,15 +0,0 @@ -import Foundation - -public enum Output: String, CustomStringConvertible { - case jpg = "jpg" - case jpeg = "jpeg" - case png = "png" - case webp = "webp" - case heic = "heic" - case avif = "avif" - case gif = "gif" - - public var description: String { - return rawValue - } -} diff --git a/Sources/AppwriteEnums/Roles.swift b/Sources/AppwriteEnums/Roles.swift new file mode 100644 index 0000000..48132fb --- /dev/null +++ b/Sources/AppwriteEnums/Roles.swift @@ -0,0 +1,11 @@ +import Foundation + +public enum Roles: String, CustomStringConvertible { + case admin = "admin" + case developer = "developer" + case owner = "owner" + + public var description: String { + return rawValue + } +} diff --git a/Sources/AppwriteModels/AlgoArgon2.swift b/Sources/AppwriteModels/AlgoArgon2.swift index fd88955..b43668e 100644 --- a/Sources/AppwriteModels/AlgoArgon2.swift +++ b/Sources/AppwriteModels/AlgoArgon2.swift @@ -13,17 +13,13 @@ open class AlgoArgon2: Codable { /// Algo type. public let type: String - /// Memory used to compute hash. public let memoryCost: Int - /// Amount of time consumed to compute hash public let timeCost: Int - /// Number of threads used to compute hash. public let threads: Int - init( type: String, memoryCost: Int, diff --git a/Sources/AppwriteModels/AlgoBcrypt.swift b/Sources/AppwriteModels/AlgoBcrypt.swift index b34095d..1da5027 100644 --- a/Sources/AppwriteModels/AlgoBcrypt.swift +++ b/Sources/AppwriteModels/AlgoBcrypt.swift @@ -11,7 +11,6 @@ open class AlgoBcrypt: Codable { /// Algo type. public let type: String - init( type: String ) { diff --git a/Sources/AppwriteModels/AlgoMd5.swift b/Sources/AppwriteModels/AlgoMd5.swift index 72fbb8d..210e26f 100644 --- a/Sources/AppwriteModels/AlgoMd5.swift +++ b/Sources/AppwriteModels/AlgoMd5.swift @@ -11,7 +11,6 @@ open class AlgoMd5: Codable { /// Algo type. public let type: String - init( type: String ) { diff --git a/Sources/AppwriteModels/AlgoPhpass.swift b/Sources/AppwriteModels/AlgoPhpass.swift index 7bd0c99..b044d8e 100644 --- a/Sources/AppwriteModels/AlgoPhpass.swift +++ b/Sources/AppwriteModels/AlgoPhpass.swift @@ -11,7 +11,6 @@ open class AlgoPhpass: Codable { /// Algo type. public let type: String - init( type: String ) { diff --git a/Sources/AppwriteModels/AlgoScrypt.swift b/Sources/AppwriteModels/AlgoScrypt.swift index 03ce541..45289c6 100644 --- a/Sources/AppwriteModels/AlgoScrypt.swift +++ b/Sources/AppwriteModels/AlgoScrypt.swift @@ -14,20 +14,15 @@ open class AlgoScrypt: Codable { /// Algo type. public let type: String - /// CPU complexity of computed hash. public let costCpu: Int - /// Memory complexity of computed hash. public let costMemory: Int - /// Parallelization of computed hash. public let costParallel: Int - /// Length used to compute hash. public let length: Int - init( type: String, costCpu: Int, diff --git a/Sources/AppwriteModels/AlgoScryptModified.swift b/Sources/AppwriteModels/AlgoScryptModified.swift index 0b2fa4e..5e64b11 100644 --- a/Sources/AppwriteModels/AlgoScryptModified.swift +++ b/Sources/AppwriteModels/AlgoScryptModified.swift @@ -13,17 +13,13 @@ open class AlgoScryptModified: Codable { /// Algo type. public let type: String - /// Salt used to compute hash. public let salt: String - /// Separator used to compute hash. public let saltSeparator: String - /// Key used to compute hash. public let signerKey: String - init( type: String, salt: String, diff --git a/Sources/AppwriteModels/AlgoSha.swift b/Sources/AppwriteModels/AlgoSha.swift index ffc0e05..399ab8b 100644 --- a/Sources/AppwriteModels/AlgoSha.swift +++ b/Sources/AppwriteModels/AlgoSha.swift @@ -11,7 +11,6 @@ open class AlgoSha: Codable { /// Algo type. public let type: String - init( type: String ) { diff --git a/Sources/AppwriteModels/Continent.swift b/Sources/AppwriteModels/Continent.swift index b8994d9..a310304 100644 --- a/Sources/AppwriteModels/Continent.swift +++ b/Sources/AppwriteModels/Continent.swift @@ -11,11 +11,9 @@ open class Continent: Codable { /// Continent name. public let name: String - /// Continent two letter code. public let code: String - init( name: String, code: String diff --git a/Sources/AppwriteModels/ContinentList.swift b/Sources/AppwriteModels/ContinentList.swift index 0e697e7..2279b9b 100644 --- a/Sources/AppwriteModels/ContinentList.swift +++ b/Sources/AppwriteModels/ContinentList.swift @@ -11,11 +11,9 @@ open class ContinentList: Codable { /// Total number of continents that matched your query. public let total: Int - /// List of continents. public let continents: [Continent] - init( total: Int, continents: [Continent] diff --git a/Sources/AppwriteModels/Country.swift b/Sources/AppwriteModels/Country.swift index c24f7e9..f5a7a10 100644 --- a/Sources/AppwriteModels/Country.swift +++ b/Sources/AppwriteModels/Country.swift @@ -11,11 +11,9 @@ open class Country: Codable { /// Country name. public let name: String - /// Country two-character ISO 3166-1 alpha code. public let code: String - init( name: String, code: String diff --git a/Sources/AppwriteModels/CountryList.swift b/Sources/AppwriteModels/CountryList.swift index 15a8d89..4d83832 100644 --- a/Sources/AppwriteModels/CountryList.swift +++ b/Sources/AppwriteModels/CountryList.swift @@ -11,11 +11,9 @@ open class CountryList: Codable { /// Total number of countries that matched your query. public let total: Int - /// List of countries. public let countries: [Country] - init( total: Int, countries: [Country] diff --git a/Sources/AppwriteModels/Currency.swift b/Sources/AppwriteModels/Currency.swift index 320337b..6e546f1 100644 --- a/Sources/AppwriteModels/Currency.swift +++ b/Sources/AppwriteModels/Currency.swift @@ -16,26 +16,19 @@ open class Currency: Codable { /// Currency symbol. public let symbol: String - /// Currency name. public let name: String - /// Currency native symbol. public let symbolNative: String - /// Number of decimal digits. public let decimalDigits: Int - /// Currency digit rounding. public let rounding: Double - /// Currency code in [ISO 4217-1](http://en.wikipedia.org/wiki/ISO_4217) three-character format. public let code: String - /// Currency plural name public let namePlural: String - init( symbol: String, name: String, diff --git a/Sources/AppwriteModels/CurrencyList.swift b/Sources/AppwriteModels/CurrencyList.swift index 81d1c26..3d8cdcd 100644 --- a/Sources/AppwriteModels/CurrencyList.swift +++ b/Sources/AppwriteModels/CurrencyList.swift @@ -11,11 +11,9 @@ open class CurrencyList: Codable { /// Total number of currencies that matched your query. public let total: Int - /// List of currencies. public let currencies: [Currency] - init( total: Int, currencies: [Currency] diff --git a/Sources/AppwriteModels/Document.swift b/Sources/AppwriteModels/Document.swift index 763db10..1a031a6 100644 --- a/Sources/AppwriteModels/Document.swift +++ b/Sources/AppwriteModels/Document.swift @@ -17,25 +17,18 @@ open class Document: Codable { /// Document ID. public let id: String - /// Document automatically incrementing ID. public let sequence: Int - /// Collection ID. public let collectionId: String - /// Database ID. public let databaseId: String - /// Document creation date in ISO 8601 format. public let createdAt: String - /// Document update date in ISO 8601 format. public let updatedAt: String - /// Document permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). public let permissions: [String] - /// Additional properties public let data: T diff --git a/Sources/AppwriteModels/DocumentList.swift b/Sources/AppwriteModels/DocumentList.swift index 77f2679..4f55579 100644 --- a/Sources/AppwriteModels/DocumentList.swift +++ b/Sources/AppwriteModels/DocumentList.swift @@ -11,11 +11,9 @@ open class DocumentList: Codable { /// Total number of documents that matched your query. public let total: Int - /// List of documents. public let documents: [Document] - init( total: Int, documents: [Document] diff --git a/Sources/AppwriteModels/Execution.swift b/Sources/AppwriteModels/Execution.swift index 625fd39..c4ee4ea 100644 --- a/Sources/AppwriteModels/Execution.swift +++ b/Sources/AppwriteModels/Execution.swift @@ -28,59 +28,41 @@ open class Execution: Codable { /// Execution ID. public let id: String - /// Execution creation date in ISO 8601 format. public let createdAt: String - /// Execution update date in ISO 8601 format. public let updatedAt: String - /// Execution roles. public let permissions: [String] - /// Function ID. public let functionId: String - /// Function's deployment ID used to create the execution. public let deploymentId: String - /// The trigger that caused the function to execute. Possible values can be: `http`, `schedule`, or `event`. public let trigger: AppwriteEnums.ExecutionTrigger - /// The status of the function execution. Possible values can be: `waiting`, `processing`, `completed`, `failed`, or `scheduled`. public let status: AppwriteEnums.ExecutionStatus - /// HTTP request method type. public let requestMethod: String - /// HTTP request path and query. public let requestPath: String - /// HTTP request headers as a key-value object. This will return only whitelisted headers. All headers are returned if execution is created as synchronous. public let requestHeaders: [Headers] - /// HTTP response status code. public let responseStatusCode: Int - /// HTTP response body. This will return empty unless execution is created as synchronous. public let responseBody: String - /// HTTP response headers as a key-value object. This will return only whitelisted headers. All headers are returned if execution is created as synchronous. public let responseHeaders: [Headers] - /// Function logs. Includes the last 4,000 characters. This will return an empty string unless the response is returned using an API key or as part of a webhook payload. public let logs: String - /// Function errors. Includes the last 4,000 characters. This will return an empty string unless the response is returned using an API key or as part of a webhook payload. public let errors: String - /// Resource(function/site) execution duration in seconds. public let duration: Double - /// The scheduled time for execution. If left empty, execution will be queued immediately. public let scheduledAt: String? - init( id: String, createdAt: String, diff --git a/Sources/AppwriteModels/ExecutionList.swift b/Sources/AppwriteModels/ExecutionList.swift index c903b34..4e09927 100644 --- a/Sources/AppwriteModels/ExecutionList.swift +++ b/Sources/AppwriteModels/ExecutionList.swift @@ -11,11 +11,9 @@ open class ExecutionList: Codable { /// Total number of executions that matched your query. public let total: Int - /// List of executions. public let executions: [Execution] - init( total: Int, executions: [Execution] diff --git a/Sources/AppwriteModels/File.swift b/Sources/AppwriteModels/File.swift index 713c7ca..5a19f88 100644 --- a/Sources/AppwriteModels/File.swift +++ b/Sources/AppwriteModels/File.swift @@ -16,41 +16,36 @@ open class File: Codable { case sizeOriginal = "sizeOriginal" case chunksTotal = "chunksTotal" case chunksUploaded = "chunksUploaded" + case encryption = "encryption" + case compression = "compression" } /// File ID. public let id: String - /// Bucket ID. public let bucketId: String - /// File creation date in ISO 8601 format. public let createdAt: String - /// File update date in ISO 8601 format. public let updatedAt: String - /// File permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). public let permissions: [String] - /// File name. public let name: String - /// File MD5 signature. public let signature: String - /// File mime type. public let mimeType: String - /// File original size in bytes. public let sizeOriginal: Int - /// Total number of chunks available public let chunksTotal: Int - /// Total number of chunks uploaded public let chunksUploaded: Int - + /// Whether file contents are encrypted at rest. + public let encryption: Bool + /// Compression algorithm used for the file. Will be one of none, [gzip](https://en.wikipedia.org/wiki/Gzip), or [zstd](https://en.wikipedia.org/wiki/Zstd). + public let compression: String init( id: String, @@ -63,7 +58,9 @@ open class File: Codable { mimeType: String, sizeOriginal: Int, chunksTotal: Int, - chunksUploaded: Int + chunksUploaded: Int, + encryption: Bool, + compression: String ) { self.id = id self.bucketId = bucketId @@ -76,6 +73,8 @@ open class File: Codable { self.sizeOriginal = sizeOriginal self.chunksTotal = chunksTotal self.chunksUploaded = chunksUploaded + self.encryption = encryption + self.compression = compression } public required init(from decoder: Decoder) throws { @@ -92,6 +91,8 @@ open class File: Codable { self.sizeOriginal = try container.decode(Int.self, forKey: .sizeOriginal) self.chunksTotal = try container.decode(Int.self, forKey: .chunksTotal) self.chunksUploaded = try container.decode(Int.self, forKey: .chunksUploaded) + self.encryption = try container.decode(Bool.self, forKey: .encryption) + self.compression = try container.decode(String.self, forKey: .compression) } public func encode(to encoder: Encoder) throws { @@ -108,6 +109,8 @@ open class File: Codable { try container.encode(sizeOriginal, forKey: .sizeOriginal) try container.encode(chunksTotal, forKey: .chunksTotal) try container.encode(chunksUploaded, forKey: .chunksUploaded) + try container.encode(encryption, forKey: .encryption) + try container.encode(compression, forKey: .compression) } public func toMap() -> [String: Any] { @@ -122,7 +125,9 @@ open class File: Codable { "mimeType": mimeType as Any, "sizeOriginal": sizeOriginal as Any, "chunksTotal": chunksTotal as Any, - "chunksUploaded": chunksUploaded as Any + "chunksUploaded": chunksUploaded as Any, + "encryption": encryption as Any, + "compression": compression as Any ] } @@ -138,7 +143,9 @@ open class File: Codable { mimeType: map["mimeType"] as! String, sizeOriginal: map["sizeOriginal"] as! Int, chunksTotal: map["chunksTotal"] as! Int, - chunksUploaded: map["chunksUploaded"] as! Int + chunksUploaded: map["chunksUploaded"] as! Int, + encryption: map["encryption"] as! Bool, + compression: map["compression"] as! String ) } } diff --git a/Sources/AppwriteModels/FileList.swift b/Sources/AppwriteModels/FileList.swift index 19d52a0..b265a6e 100644 --- a/Sources/AppwriteModels/FileList.swift +++ b/Sources/AppwriteModels/FileList.swift @@ -11,11 +11,9 @@ open class FileList: Codable { /// Total number of files that matched your query. public let total: Int - /// List of files. public let files: [File] - init( total: Int, files: [File] diff --git a/Sources/AppwriteModels/Headers.swift b/Sources/AppwriteModels/Headers.swift index ae468e5..0d344fc 100644 --- a/Sources/AppwriteModels/Headers.swift +++ b/Sources/AppwriteModels/Headers.swift @@ -11,11 +11,9 @@ open class Headers: Codable { /// Header name. public let name: String - /// Header value. public let value: String - init( name: String, value: String diff --git a/Sources/AppwriteModels/Identity.swift b/Sources/AppwriteModels/Identity.swift index f93035d..a0a565c 100644 --- a/Sources/AppwriteModels/Identity.swift +++ b/Sources/AppwriteModels/Identity.swift @@ -19,35 +19,25 @@ open class Identity: Codable { /// Identity ID. public let id: String - /// Identity creation date in ISO 8601 format. public let createdAt: String - /// Identity update date in ISO 8601 format. public let updatedAt: String - /// User ID. public let userId: String - /// Identity Provider. public let provider: String - /// ID of the User in the Identity Provider. public let providerUid: String - /// Email of the User in the Identity Provider. public let providerEmail: String - /// Identity Provider Access Token. public let providerAccessToken: String - /// The date of when the access token expires in ISO 8601 format. public let providerAccessTokenExpiry: String - /// Identity Provider Refresh Token. public let providerRefreshToken: String - init( id: String, createdAt: String, diff --git a/Sources/AppwriteModels/IdentityList.swift b/Sources/AppwriteModels/IdentityList.swift index abcc362..0ff998d 100644 --- a/Sources/AppwriteModels/IdentityList.swift +++ b/Sources/AppwriteModels/IdentityList.swift @@ -11,11 +11,9 @@ open class IdentityList: Codable { /// Total number of identities that matched your query. public let total: Int - /// List of identities. public let identities: [Identity] - init( total: Int, identities: [Identity] diff --git a/Sources/AppwriteModels/Jwt.swift b/Sources/AppwriteModels/Jwt.swift index fd7fb49..22c5be2 100644 --- a/Sources/AppwriteModels/Jwt.swift +++ b/Sources/AppwriteModels/Jwt.swift @@ -11,7 +11,6 @@ open class Jwt: Codable { /// JWT encoded string. public let jwt: String - init( jwt: String ) { diff --git a/Sources/AppwriteModels/Language.swift b/Sources/AppwriteModels/Language.swift index d1e1a15..6b12959 100644 --- a/Sources/AppwriteModels/Language.swift +++ b/Sources/AppwriteModels/Language.swift @@ -12,14 +12,11 @@ open class Language: Codable { /// Language name. public let name: String - /// Language two-character ISO 639-1 codes. public let code: String - /// Language native name. public let nativeName: String - init( name: String, code: String, diff --git a/Sources/AppwriteModels/LanguageList.swift b/Sources/AppwriteModels/LanguageList.swift index 2b1f03c..0d57fdd 100644 --- a/Sources/AppwriteModels/LanguageList.swift +++ b/Sources/AppwriteModels/LanguageList.swift @@ -11,11 +11,9 @@ open class LanguageList: Codable { /// Total number of languages that matched your query. public let total: Int - /// List of languages. public let languages: [Language] - init( total: Int, languages: [Language] diff --git a/Sources/AppwriteModels/Locale.swift b/Sources/AppwriteModels/Locale.swift index 4d034f4..c550fc9 100644 --- a/Sources/AppwriteModels/Locale.swift +++ b/Sources/AppwriteModels/Locale.swift @@ -16,26 +16,19 @@ open class Locale: Codable { /// User IP address. public let ip: String - /// Country code in [ISO 3166-1](http://en.wikipedia.org/wiki/ISO_3166-1) two-character format public let countryCode: String - /// Country name. This field support localization. public let country: String - /// Continent code. A two character continent code "AF" for Africa, "AN" for Antarctica, "AS" for Asia, "EU" for Europe, "NA" for North America, "OC" for Oceania, and "SA" for South America. public let continentCode: String - /// Continent name. This field support localization. public let continent: String - /// True if country is part of the European Union. public let eu: Bool - /// Currency code in [ISO 4217-1](http://en.wikipedia.org/wiki/ISO_4217) three-character format public let currency: String - init( ip: String, countryCode: String, diff --git a/Sources/AppwriteModels/LocaleCode.swift b/Sources/AppwriteModels/LocaleCode.swift index d2678bb..f4ac0fc 100644 --- a/Sources/AppwriteModels/LocaleCode.swift +++ b/Sources/AppwriteModels/LocaleCode.swift @@ -11,11 +11,9 @@ open class LocaleCode: Codable { /// Locale codes in [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) public let code: String - /// Locale name public let name: String - init( code: String, name: String diff --git a/Sources/AppwriteModels/LocaleCodeList.swift b/Sources/AppwriteModels/LocaleCodeList.swift index f1d1678..5a655bc 100644 --- a/Sources/AppwriteModels/LocaleCodeList.swift +++ b/Sources/AppwriteModels/LocaleCodeList.swift @@ -11,11 +11,9 @@ open class LocaleCodeList: Codable { /// Total number of localeCodes that matched your query. public let total: Int - /// List of localeCodes. public let localeCodes: [LocaleCode] - init( total: Int, localeCodes: [LocaleCode] diff --git a/Sources/AppwriteModels/Log.swift b/Sources/AppwriteModels/Log.swift index 16c27ef..ae5a3a5 100644 --- a/Sources/AppwriteModels/Log.swift +++ b/Sources/AppwriteModels/Log.swift @@ -30,68 +30,47 @@ open class Log: Codable { /// Event name. public let event: String - /// User ID. public let userId: String - /// User Email. public let userEmail: String - /// User Name. public let userName: String - /// API mode when event triggered. public let mode: String - /// IP session in use when the session was created. public let ip: String - /// Log creation date in ISO 8601 format. public let time: String - /// Operating system code name. View list of [available options](https://github.com/appwrite/appwrite/blob/master/docs/lists/os.json). public let osCode: String - /// Operating system name. public let osName: String - /// Operating system version. public let osVersion: String - /// Client type. public let clientType: String - /// Client code name. View list of [available options](https://github.com/appwrite/appwrite/blob/master/docs/lists/clients.json). public let clientCode: String - /// Client name. public let clientName: String - /// Client version. public let clientVersion: String - /// Client engine name. public let clientEngine: String - /// Client engine name. public let clientEngineVersion: String - /// Device name. public let deviceName: String - /// Device brand name. public let deviceBrand: String - /// Device model name. public let deviceModel: String - /// Country two-character ISO 3166-1 alpha code. public let countryCode: String - /// Country name. public let countryName: String - init( event: String, userId: String, diff --git a/Sources/AppwriteModels/LogList.swift b/Sources/AppwriteModels/LogList.swift index ba76a8a..ac545e2 100644 --- a/Sources/AppwriteModels/LogList.swift +++ b/Sources/AppwriteModels/LogList.swift @@ -11,11 +11,9 @@ open class LogList: Codable { /// Total number of logs that matched your query. public let total: Int - /// List of logs. public let logs: [Log] - init( total: Int, logs: [Log] diff --git a/Sources/AppwriteModels/Membership.swift b/Sources/AppwriteModels/Membership.swift index 8d26766..8ff61ee 100644 --- a/Sources/AppwriteModels/Membership.swift +++ b/Sources/AppwriteModels/Membership.swift @@ -22,44 +22,31 @@ open class Membership: Codable { /// Membership ID. public let id: String - /// Membership creation date in ISO 8601 format. public let createdAt: String - /// Membership update date in ISO 8601 format. public let updatedAt: String - /// User ID. public let userId: String - /// User name. Hide this attribute by toggling membership privacy in the Console. public let userName: String - /// User email address. Hide this attribute by toggling membership privacy in the Console. public let userEmail: String - /// Team ID. public let teamId: String - /// Team name. public let teamName: String - /// Date, the user has been invited to join the team in ISO 8601 format. public let invited: String - /// Date, the user has accepted the invitation to join the team in ISO 8601 format. public let joined: String - /// User confirmation status, true if the user has joined the team or false otherwise. public let confirm: Bool - /// Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console. public let mfa: Bool - /// User list of roles public let roles: [String] - init( id: String, createdAt: String, diff --git a/Sources/AppwriteModels/MembershipList.swift b/Sources/AppwriteModels/MembershipList.swift index 7d6ffd1..283abae 100644 --- a/Sources/AppwriteModels/MembershipList.swift +++ b/Sources/AppwriteModels/MembershipList.swift @@ -11,11 +11,9 @@ open class MembershipList: Codable { /// Total number of memberships that matched your query. public let total: Int - /// List of memberships. public let memberships: [Membership] - init( total: Int, memberships: [Membership] diff --git a/Sources/AppwriteModels/MfaChallenge.swift b/Sources/AppwriteModels/MfaChallenge.swift index c6b77a5..55d82ab 100644 --- a/Sources/AppwriteModels/MfaChallenge.swift +++ b/Sources/AppwriteModels/MfaChallenge.swift @@ -13,17 +13,13 @@ open class MfaChallenge: Codable { /// Token ID. public let id: String - /// Token creation date in ISO 8601 format. public let createdAt: String - /// User ID. public let userId: String - /// Token expiration date in ISO 8601 format. public let expire: String - init( id: String, createdAt: String, diff --git a/Sources/AppwriteModels/MfaFactors.swift b/Sources/AppwriteModels/MfaFactors.swift index 4291fab..fb8f35c 100644 --- a/Sources/AppwriteModels/MfaFactors.swift +++ b/Sources/AppwriteModels/MfaFactors.swift @@ -13,17 +13,13 @@ open class MfaFactors: Codable { /// Can TOTP be used for MFA challenge for this account. public let totp: Bool - /// Can phone (SMS) be used for MFA challenge for this account. public let phone: Bool - /// Can email be used for MFA challenge for this account. public let email: Bool - /// Can recovery code be used for MFA challenge for this account. public let recoveryCode: Bool - init( totp: Bool, phone: Bool, diff --git a/Sources/AppwriteModels/MfaRecoveryCodes.swift b/Sources/AppwriteModels/MfaRecoveryCodes.swift index bd2968f..47c80ab 100644 --- a/Sources/AppwriteModels/MfaRecoveryCodes.swift +++ b/Sources/AppwriteModels/MfaRecoveryCodes.swift @@ -11,7 +11,6 @@ open class MfaRecoveryCodes: Codable { /// Recovery codes. public let recoveryCodes: [String] - init( recoveryCodes: [String] ) { diff --git a/Sources/AppwriteModels/MfaType.swift b/Sources/AppwriteModels/MfaType.swift index 8646385..2aaca85 100644 --- a/Sources/AppwriteModels/MfaType.swift +++ b/Sources/AppwriteModels/MfaType.swift @@ -11,11 +11,9 @@ open class MfaType: Codable { /// Secret token used for TOTP factor. public let secret: String - /// URI for authenticator apps. public let uri: String - init( secret: String, uri: String diff --git a/Sources/AppwriteModels/Phone.swift b/Sources/AppwriteModels/Phone.swift index fc90d49..41f6818 100644 --- a/Sources/AppwriteModels/Phone.swift +++ b/Sources/AppwriteModels/Phone.swift @@ -12,14 +12,11 @@ open class Phone: Codable { /// Phone code. public let code: String - /// Country two-character ISO 3166-1 alpha code. public let countryCode: String - /// Country name. public let countryName: String - init( code: String, countryCode: String, diff --git a/Sources/AppwriteModels/PhoneList.swift b/Sources/AppwriteModels/PhoneList.swift index f09d239..5a824e1 100644 --- a/Sources/AppwriteModels/PhoneList.swift +++ b/Sources/AppwriteModels/PhoneList.swift @@ -11,11 +11,9 @@ open class PhoneList: Codable { /// Total number of phones that matched your query. public let total: Int - /// List of phones. public let phones: [Phone] - init( total: Int, phones: [Phone] diff --git a/Sources/AppwriteModels/Row.swift b/Sources/AppwriteModels/Row.swift index 5c6a215..44f3859 100644 --- a/Sources/AppwriteModels/Row.swift +++ b/Sources/AppwriteModels/Row.swift @@ -17,25 +17,18 @@ open class Row: Codable { /// Row ID. public let id: String - /// Row automatically incrementing ID. public let sequence: Int - /// Table ID. public let tableId: String - /// Database ID. public let databaseId: String - /// Row creation date in ISO 8601 format. public let createdAt: String - /// Row update date in ISO 8601 format. public let updatedAt: String - /// Row permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). public let permissions: [String] - /// Additional properties public let data: T diff --git a/Sources/AppwriteModels/RowList.swift b/Sources/AppwriteModels/RowList.swift index c14c83b..8562ef2 100644 --- a/Sources/AppwriteModels/RowList.swift +++ b/Sources/AppwriteModels/RowList.swift @@ -11,11 +11,9 @@ open class RowList: Codable { /// Total number of rows that matched your query. public let total: Int - /// List of rows. public let rows: [Row] - init( total: Int, rows: [Row] diff --git a/Sources/AppwriteModels/Session.swift b/Sources/AppwriteModels/Session.swift index b5c25a6..1da34cc 100644 --- a/Sources/AppwriteModels/Session.swift +++ b/Sources/AppwriteModels/Session.swift @@ -38,92 +38,63 @@ open class Session: Codable { /// Session ID. public let id: String - /// Session creation date in ISO 8601 format. public let createdAt: String - /// Session update date in ISO 8601 format. public let updatedAt: String - /// User ID. public let userId: String - /// Session expiration date in ISO 8601 format. public let expire: String - /// Session Provider. public let provider: String - /// Session Provider User ID. public let providerUid: String - /// Session Provider Access Token. public let providerAccessToken: String - /// The date of when the access token expires in ISO 8601 format. public let providerAccessTokenExpiry: String - /// Session Provider Refresh Token. public let providerRefreshToken: String - /// IP in use when the session was created. public let ip: String - /// Operating system code name. View list of [available options](https://github.com/appwrite/appwrite/blob/master/docs/lists/os.json). public let osCode: String - /// Operating system name. public let osName: String - /// Operating system version. public let osVersion: String - /// Client type. public let clientType: String - /// Client code name. View list of [available options](https://github.com/appwrite/appwrite/blob/master/docs/lists/clients.json). public let clientCode: String - /// Client name. public let clientName: String - /// Client version. public let clientVersion: String - /// Client engine name. public let clientEngine: String - /// Client engine name. public let clientEngineVersion: String - /// Device name. public let deviceName: String - /// Device brand name. public let deviceBrand: String - /// Device model name. public let deviceModel: String - /// Country two-character ISO 3166-1 alpha code. public let countryCode: String - /// Country name. public let countryName: String - /// Returns true if this the current user session. public let current: Bool - /// Returns a list of active session factors. public let factors: [String] - /// Secret used to authenticate the user. Only included if the request was made with an API key public let secret: String - /// Most recent date in ISO 8601 format when the session successfully passed MFA challenge. public let mfaUpdatedAt: String - init( id: String, createdAt: String, diff --git a/Sources/AppwriteModels/SessionList.swift b/Sources/AppwriteModels/SessionList.swift index c9c8394..81e9d1a 100644 --- a/Sources/AppwriteModels/SessionList.swift +++ b/Sources/AppwriteModels/SessionList.swift @@ -11,11 +11,9 @@ open class SessionList: Codable { /// Total number of sessions that matched your query. public let total: Int - /// List of sessions. public let sessions: [Session] - init( total: Int, sessions: [Session] diff --git a/Sources/AppwriteModels/Subscriber.swift b/Sources/AppwriteModels/Subscriber.swift index ad6fa5d..8dc1c13 100644 --- a/Sources/AppwriteModels/Subscriber.swift +++ b/Sources/AppwriteModels/Subscriber.swift @@ -18,32 +18,23 @@ open class Subscriber: Codable { /// Subscriber ID. public let id: String - /// Subscriber creation time in ISO 8601 format. public let createdAt: String - /// Subscriber update date in ISO 8601 format. public let updatedAt: String - /// Target ID. public let targetId: String - /// Target. public let target: Target - /// Topic ID. public let userId: String - /// User Name. public let userName: String - /// Topic ID. public let topicId: String - /// The target provider type. Can be one of the following: `email`, `sms` or `push`. public let providerType: String - init( id: String, createdAt: String, diff --git a/Sources/AppwriteModels/Target.swift b/Sources/AppwriteModels/Target.swift index 0581a61..4be8f67 100644 --- a/Sources/AppwriteModels/Target.swift +++ b/Sources/AppwriteModels/Target.swift @@ -18,32 +18,23 @@ open class Target: Codable { /// Target ID. public let id: String - /// Target creation time in ISO 8601 format. public let createdAt: String - /// Target update date in ISO 8601 format. public let updatedAt: String - /// Target Name. public let name: String - /// User ID. public let userId: String - /// Provider ID. public let providerId: String? - /// The target provider type. Can be one of the following: `email`, `sms` or `push`. public let providerType: String - /// The target identifier. public let identifier: String - /// Is the target expired. public let expired: Bool - init( id: String, createdAt: String, diff --git a/Sources/AppwriteModels/Team.swift b/Sources/AppwriteModels/Team.swift index 9ca7307..232f36c 100644 --- a/Sources/AppwriteModels/Team.swift +++ b/Sources/AppwriteModels/Team.swift @@ -15,23 +15,17 @@ open class Team: Codable { /// Team ID. public let id: String - /// Team creation date in ISO 8601 format. public let createdAt: String - /// Team update date in ISO 8601 format. public let updatedAt: String - /// Team name. public let name: String - /// Total number of team members. public let total: Int - /// Team preferences as a key-value object public let prefs: Preferences - init( id: String, createdAt: String, diff --git a/Sources/AppwriteModels/TeamList.swift b/Sources/AppwriteModels/TeamList.swift index 2b789d9..60dfaf3 100644 --- a/Sources/AppwriteModels/TeamList.swift +++ b/Sources/AppwriteModels/TeamList.swift @@ -11,11 +11,9 @@ open class TeamList: Codable { /// Total number of teams that matched your query. public let total: Int - /// List of teams. public let teams: [Team] - init( total: Int, teams: [Team] diff --git a/Sources/AppwriteModels/Token.swift b/Sources/AppwriteModels/Token.swift index f832402..e6716cd 100644 --- a/Sources/AppwriteModels/Token.swift +++ b/Sources/AppwriteModels/Token.swift @@ -15,23 +15,17 @@ open class Token: Codable { /// Token ID. public let id: String - /// Token creation date in ISO 8601 format. public let createdAt: String - /// User ID. public let userId: String - /// Token secret key. This will return an empty string unless the response is returned using an API key or as part of a webhook payload. public let secret: String - /// Token expiration date in ISO 8601 format. public let expire: String - /// Security phrase of a token. Empty if security phrase was not requested when creating a token. It includes randomly generated phrase which is also sent in the external resource such as email. public let phrase: String - init( id: String, createdAt: String, diff --git a/Sources/AppwriteModels/Transaction.swift b/Sources/AppwriteModels/Transaction.swift index 584c4c3..fcc7f0d 100644 --- a/Sources/AppwriteModels/Transaction.swift +++ b/Sources/AppwriteModels/Transaction.swift @@ -15,23 +15,17 @@ open class Transaction: Codable { /// Transaction ID. public let id: String - /// Transaction creation time in ISO 8601 format. public let createdAt: String - /// Transaction update date in ISO 8601 format. public let updatedAt: String - /// Current status of the transaction. One of: pending, committing, committed, rolled_back, failed. public let status: String - /// Number of operations in the transaction. public let operations: Int - /// Expiration time in ISO 8601 format. public let expiresAt: String - init( id: String, createdAt: String, diff --git a/Sources/AppwriteModels/TransactionList.swift b/Sources/AppwriteModels/TransactionList.swift index 49a976a..93915a9 100644 --- a/Sources/AppwriteModels/TransactionList.swift +++ b/Sources/AppwriteModels/TransactionList.swift @@ -11,11 +11,9 @@ open class TransactionList: Codable { /// Total number of transactions that matched your query. public let total: Int - /// List of transactions. public let transactions: [Transaction] - init( total: Int, transactions: [Transaction] diff --git a/Sources/AppwriteModels/User.swift b/Sources/AppwriteModels/User.swift index 6e972d3..186da68 100644 --- a/Sources/AppwriteModels/User.swift +++ b/Sources/AppwriteModels/User.swift @@ -28,62 +28,43 @@ open class User: Codable { /// User ID. public let id: String - /// User creation date in ISO 8601 format. public let createdAt: String - /// User update date in ISO 8601 format. public let updatedAt: String - /// User name. public let name: String - /// Hashed user password. public let password: String? - /// Password hashing algorithm. public let hash: String? - /// Password hashing algorithm configuration. public let hashOptions: [String: AnyCodable]? - /// User registration date in ISO 8601 format. public let registration: String - /// User status. Pass `true` for enabled and `false` for disabled. public let status: Bool - /// Labels for the user. public let labels: [String] - /// Password update time in ISO 8601 format. public let passwordUpdate: String - /// User email address. public let email: String - /// User phone number in E.164 format. public let phone: String - /// Email verification status. public let emailVerification: Bool - /// Phone verification status. public let phoneVerification: Bool - /// Multi factor authentication status. public let mfa: Bool - /// User preferences as a key-value object public let prefs: Preferences - /// A user-owned message receiver. A single user may have multiple e.g. emails, phones, and a browser. Each target is registered with a single provider. public let targets: [Target] - /// Most recent access date in ISO 8601 format. This attribute is only updated again after 24 hours. public let accessedAt: String - init( id: String, createdAt: String, diff --git a/Sources/JSONCodable/Codable+JSON.swift b/Sources/JSONCodable/Codable+JSON.swift index c9b8711..e08de62 100644 --- a/Sources/JSONCodable/Codable+JSON.swift +++ b/Sources/JSONCodable/Codable+JSON.swift @@ -121,7 +121,6 @@ extension AnyCodable: ExpressibleByStringLiteral {} extension AnyCodable: ExpressibleByArrayLiteral {} extension AnyCodable: ExpressibleByDictionaryLiteral {} - extension AnyCodable: Hashable { public func hash(into hasher: inout Hasher) { switch value { diff --git a/docs/examples/account/create-jwt.md b/docs/examples/account/create-jwt.md index fbcd504..34b29f4 100644 --- a/docs/examples/account/create-jwt.md +++ b/docs/examples/account/create-jwt.md @@ -6,5 +6,7 @@ let client = Client() let account = Account(client) -let jwt = try await account.createJWT() +let jwt = try await account.createJWT( + duration: 0 // optional +) diff --git a/docs/examples/avatars/get-screenshot.md b/docs/examples/avatars/get-screenshot.md index 20d635a..b8f6a48 100644 --- a/docs/examples/avatars/get-screenshot.md +++ b/docs/examples/avatars/get-screenshot.md @@ -16,20 +16,20 @@ let bytes = try await avatars.getScreenshot( viewportWidth: 1920, // optional viewportHeight: 1080, // optional scale: 2, // optional - theme: .light, // optional + theme: .dark, // optional userAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15", // optional fullpage: true, // optional locale: "en-US", // optional - timezone: .africaAbidjan, // optional + timezone: .americaNewYork, // optional latitude: 37.7749, // optional longitude: -122.4194, // optional accuracy: 100, // optional touch: true, // optional - permissions: ["geolocation","notifications"], // optional + permissions: [.geolocation, .notifications], // optional sleep: 3, // optional width: 800, // optional height: 600, // optional quality: 85, // optional - output: .jpg // optional + output: .jpeg // optional ) diff --git a/docs/examples/databases/update-document.md b/docs/examples/databases/update-document.md index 33dce44..3a1b4c4 100644 --- a/docs/examples/databases/update-document.md +++ b/docs/examples/databases/update-document.md @@ -10,7 +10,13 @@ let document = try await databases.updateDocument( databaseId: "", collectionId: "", documentId: "", - data: [:], // optional + data: [ + "username": "walter.obrien", + "email": "walter.obrien@example.com", + "fullName": "Walter O'Brien", + "age": 33, + "isAdmin": false + ], // optional permissions: [Permission.read(Role.any())], // optional transactionId: "" // optional ) diff --git a/docs/examples/databases/upsert-document.md b/docs/examples/databases/upsert-document.md index e678632..4026c33 100644 --- a/docs/examples/databases/upsert-document.md +++ b/docs/examples/databases/upsert-document.md @@ -10,7 +10,13 @@ let document = try await databases.upsertDocument( databaseId: "", collectionId: "", documentId: "", - data: [:], + data: [ + "username": "walter.obrien", + "email": "walter.obrien@example.com", + "fullName": "Walter O'Brien", + "age": 30, + "isAdmin": false + ], // optional permissions: [Permission.read(Role.any())], // optional transactionId: "" // optional ) diff --git a/docs/examples/tablesdb/update-row.md b/docs/examples/tablesdb/update-row.md index 90bf66a..e9b32e6 100644 --- a/docs/examples/tablesdb/update-row.md +++ b/docs/examples/tablesdb/update-row.md @@ -10,7 +10,13 @@ let row = try await tablesDB.updateRow( databaseId: "", tableId: "", rowId: "", - data: [:], // optional + data: [ + "username": "walter.obrien", + "email": "walter.obrien@example.com", + "fullName": "Walter O'Brien", + "age": 33, + "isAdmin": false + ], // optional permissions: [Permission.read(Role.any())], // optional transactionId: "" // optional ) diff --git a/docs/examples/tablesdb/upsert-row.md b/docs/examples/tablesdb/upsert-row.md index 5665f92..f1e3872 100644 --- a/docs/examples/tablesdb/upsert-row.md +++ b/docs/examples/tablesdb/upsert-row.md @@ -10,7 +10,13 @@ let row = try await tablesDB.upsertRow( databaseId: "", tableId: "", rowId: "", - data: [:], // optional + data: [ + "username": "walter.obrien", + "email": "walter.obrien@example.com", + "fullName": "Walter O'Brien", + "age": 33, + "isAdmin": false + ], // optional permissions: [Permission.read(Role.any())], // optional transactionId: "" // optional ) diff --git a/docs/examples/teams/create-membership.md b/docs/examples/teams/create-membership.md index 3c6d093..6b0eaaf 100644 --- a/docs/examples/teams/create-membership.md +++ b/docs/examples/teams/create-membership.md @@ -1,4 +1,5 @@ import Appwrite +import AppwriteEnums let client = Client() .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint @@ -8,7 +9,7 @@ let teams = Teams(client) let membership = try await teams.createMembership( teamId: "", - roles: [], + roles: [.admin], email: "email@example.com", // optional userId: "", // optional phone: "+12065550100", // optional diff --git a/docs/examples/teams/update-membership.md b/docs/examples/teams/update-membership.md index eaa6179..a61f792 100644 --- a/docs/examples/teams/update-membership.md +++ b/docs/examples/teams/update-membership.md @@ -1,4 +1,5 @@ import Appwrite +import AppwriteEnums let client = Client() .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint @@ -9,6 +10,6 @@ let teams = Teams(client) let membership = try await teams.updateMembership( teamId: "", membershipId: "", - roles: [] + roles: [.admin] ) From 1eca2028658077f99b61f092f43c375f99e7ff9a Mon Sep 17 00:00:00 2001 From: root Date: Mon, 2 Feb 2026 12:28:33 +0000 Subject: [PATCH 2/2] update changelog etc --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22a5519..470d1d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ## 14.0.0 * Add array-based enum parameters (e.g., `permissions: [BrowserPermission]`). +* Breaking change: `Output` enum has been removed; use `ImageFormat` instead. +* Add `Channel` helpers for Realtime. ## 13.5.0