From 1672cb0f3a09a5d642260a44e6a01ef51980edcd Mon Sep 17 00:00:00 2001 From: root Date: Sat, 17 Aug 2024 08:51:08 +0000 Subject: [PATCH] chore: release rc --- Package.swift | 4 +- README.md | 4 +- Sources/Appwrite/Client.swift | 4 +- Sources/Appwrite/Services/Account.swift | 14 +- Sources/Appwrite/Services/Avatars.swift | 2 + Sources/Appwrite/Services/Functions.swift | 116 +++++++++++++-- Sources/AppwriteModels/Execution.swift | 13 +- Sources/AppwriteModels/Runtime.swift | 7 + Sources/AppwriteModels/TemplateFunction.swift | 140 ++++++++++++++++++ .../AppwriteModels/TemplateFunctionList.swift | 35 +++++ Sources/AppwriteModels/TemplateRuntime.swift | 49 ++++++ Sources/AppwriteModels/TemplateVariable.swift | 63 ++++++++ .../account/delete-mfa-authenticator.md | 3 +- docs/examples/functions/create.md | 2 +- ...ployment.md => get-deployment-download.md} | 4 +- docs/examples/functions/get-template.md | 12 ++ docs/examples/functions/list-templates.md | 15 ++ 17 files changed, 449 insertions(+), 38 deletions(-) create mode 100644 Sources/AppwriteModels/TemplateFunction.swift create mode 100644 Sources/AppwriteModels/TemplateFunctionList.swift create mode 100644 Sources/AppwriteModels/TemplateRuntime.swift create mode 100644 Sources/AppwriteModels/TemplateVariable.swift rename docs/examples/functions/{download-deployment.md => get-deployment-download.md} (70%) create mode 100644 docs/examples/functions/get-template.md create mode 100644 docs/examples/functions/list-templates.md diff --git a/Package.swift b/Package.swift index 91daadf..3e916e1 100644 --- a/Package.swift +++ b/Package.swift @@ -22,8 +22,8 @@ let package = Package( ), ], dependencies: [ - .package(url: "https://github.com/swift-server/async-http-client.git", from: "1.9.0"), - .package(url: "https://github.com/apple/swift-nio.git", from: "2.32.0"), + .package(url: "https://github.com/swift-server/async-http-client.git", from: "1.19.0"), + .package(url: "https://github.com/apple/swift-nio.git", from: "2.58.0"), ], targets: [ .target( diff --git a/README.md b/README.md index fbbc21c..cabb58f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![Swift Package Manager](https://img.shields.io/github/v/release/appwrite/sdk-for-swift.svg?color=green&style=flat-square) ![License](https://img.shields.io/github/license/appwrite/sdk-for-swift.svg?style=flat-square) -![Version](https://img.shields.io/badge/api%20version-1.5.7-blue.svg?style=flat-square) +![Version](https://img.shields.io/badge/api%20version-1.6.0-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) @@ -33,7 +33,7 @@ Add the package to your `Package.swift` dependencies: ```swift dependencies: [ - .package(url: "git@github.com:appwrite/sdk-for-swift.git", from: "5.0.2"), + .package(url: "git@github.com:appwrite/sdk-for-swift.git", from: "6.0.0-rc.1"), ], ``` diff --git a/Sources/Appwrite/Client.swift b/Sources/Appwrite/Client.swift index ed77521..021e269 100644 --- a/Sources/Appwrite/Client.swift +++ b/Sources/Appwrite/Client.swift @@ -21,8 +21,8 @@ open class Client { "x-sdk-name": "Swift", "x-sdk-platform": "server", "x-sdk-language": "swift", - "x-sdk-version": "5.0.2", - "x-appwrite-response-format": "1.5.0" + "x-sdk-version": "6.0.0-rc.1", + "x-appwrite-response-format": "1.6.0" ] internal var config: [String: String] = [:] diff --git a/Sources/Appwrite/Services/Account.swift b/Sources/Appwrite/Services/Account.swift index 065a7cb..06dbc35 100644 --- a/Sources/Appwrite/Services/Account.swift +++ b/Sources/Appwrite/Services/Account.swift @@ -402,7 +402,7 @@ open class Account: Service { } /// - /// Add Authenticator + /// Create Authenticator /// /// Add an authenticator app to be used as an MFA factor. Verify the /// authenticator using the [verify @@ -508,20 +508,16 @@ open class Account: Service { /// Delete an authenticator for a user by ID. /// /// @param AppwriteEnums.AuthenticatorType type - /// @param String otp /// @throws Exception /// @return array /// open func deleteMfaAuthenticator( - type: AppwriteEnums.AuthenticatorType, - otp: String + type: AppwriteEnums.AuthenticatorType ) async throws -> Any { let apiPath: String = "/account/mfa/authenticators/{type}" .replacingOccurrences(of: "{type}", with: type.rawValue) - let apiParams: [String: Any?] = [ - "otp": otp - ] + let apiParams: [String: Any] = [:] let apiHeaders: [String: String] = [ "content-type": "application/json" @@ -535,7 +531,7 @@ open class Account: Service { } /// - /// Create 2FA Challenge + /// Create MFA Challenge /// /// Begin the process of MFA verification after sign-in. Finish the flow with /// [updateMfaChallenge](/docs/references/cloud/client-web/account#updateMfaChallenge) @@ -1877,7 +1873,7 @@ open class Account: Service { } /// - /// Create phone verification (confirmation) + /// Update phone verification (confirmation) /// /// Use this endpoint to complete the user phone verification process. Use the /// **userId** and **secret** that were sent to your user's phone number to diff --git a/Sources/Appwrite/Services/Avatars.swift b/Sources/Appwrite/Services/Avatars.swift index 182bd62..8699edf 100644 --- a/Sources/Appwrite/Services/Avatars.swift +++ b/Sources/Appwrite/Services/Avatars.swift @@ -111,6 +111,7 @@ open class Avatars: Service { /// Use this endpoint to fetch the favorite icon (AKA favicon) of any remote /// website URL. /// + /// This endpoint does not follow HTTP redirects. /// /// @param String url /// @throws Exception @@ -200,6 +201,7 @@ open class Avatars: Service { /// image at source quality. If dimensions are not specified, the default size /// of image returned is 400x400px. /// + /// This endpoint does not follow HTTP redirects. /// /// @param String url /// @param Int width diff --git a/Sources/Appwrite/Services/Functions.swift b/Sources/Appwrite/Services/Functions.swift index f223d93..1084a6c 100644 --- a/Sources/Appwrite/Services/Functions.swift +++ b/Sources/Appwrite/Services/Functions.swift @@ -75,7 +75,7 @@ open class Functions: Service { /// @param String templateRepository /// @param String templateOwner /// @param String templateRootDirectory - /// @param String templateBranch + /// @param String templateVersion /// @throws Exception /// @return array /// @@ -100,7 +100,7 @@ open class Functions: Service { templateRepository: String? = nil, templateOwner: String? = nil, templateRootDirectory: String? = nil, - templateBranch: String? = nil + templateVersion: String? = nil ) async throws -> AppwriteModels.Function { let apiPath: String = "/functions" @@ -125,7 +125,7 @@ open class Functions: Service { "templateRepository": templateRepository, "templateOwner": templateOwner, "templateRootDirectory": templateRootDirectory, - "templateBranch": templateBranch + "templateVersion": templateVersion ] let apiHeaders: [String: String] = [ @@ -176,6 +176,88 @@ open class Functions: Service { ) } + /// + /// List function templates + /// + /// List available function templates. You can use template details in + /// [createFunction](/docs/references/cloud/server-nodejs/functions#create) + /// method. + /// + /// @param [String] runtimes + /// @param [String] useCases + /// @param Int limit + /// @param Int offset + /// @throws Exception + /// @return array + /// + open func listTemplates( + runtimes: [String]? = nil, + useCases: [String]? = nil, + limit: Int? = nil, + offset: Int? = nil + ) async throws -> AppwriteModels.TemplateFunctionList { + let apiPath: String = "/functions/templates" + + let apiParams: [String: Any?] = [ + "runtimes": runtimes, + "useCases": useCases, + "limit": limit, + "offset": offset + ] + + let apiHeaders: [String: String] = [ + "content-type": "application/json" + ] + + let converter: (Any) -> AppwriteModels.TemplateFunctionList = { response in + return AppwriteModels.TemplateFunctionList.from(map: response as! [String: Any]) + } + + return try await client.call( + method: "GET", + path: apiPath, + headers: apiHeaders, + params: apiParams, + converter: converter + ) + } + + /// + /// Get function template + /// + /// Get a function template using ID. You can use template details in + /// [createFunction](/docs/references/cloud/server-nodejs/functions#create) + /// method. + /// + /// @param String templateId + /// @throws Exception + /// @return array + /// + open func getTemplate( + templateId: String + ) async throws -> AppwriteModels.TemplateFunction { + let apiPath: String = "/functions/templates/{templateId}" + .replacingOccurrences(of: "{templateId}", with: templateId) + + let apiParams: [String: Any] = [:] + + let apiHeaders: [String: String] = [ + "content-type": "application/json" + ] + + let converter: (Any) -> AppwriteModels.TemplateFunction = { response in + return AppwriteModels.TemplateFunction.from(map: response as! [String: Any]) + } + + return try await client.call( + method: "GET", + path: apiPath, + headers: apiHeaders, + params: apiParams, + converter: converter + ) + } + /// /// Get function /// @@ -462,7 +544,7 @@ open class Functions: Service { } /// - /// Update function deployment + /// Update deployment /// /// Update the function code deployment ID using the unique function ID. Use /// this endpoint to switch the code deployment that should be executed by the @@ -600,7 +682,7 @@ open class Functions: Service { } /// - /// Download Deployment + /// Download deployment /// /// Get a Deployment's contents by its unique ID. This endpoint supports range /// requests for partial or streaming file download. @@ -610,7 +692,7 @@ open class Functions: Service { /// @throws Exception /// @return array /// - open func downloadDeployment( + open func getDeploymentDownload( functionId: String, deploymentId: String ) async throws -> ByteBuffer { @@ -698,12 +780,13 @@ open class Functions: Service { path: String? = nil, method: AppwriteEnums.ExecutionMethod? = nil, headers: Any? = nil, - scheduledAt: String? = nil + scheduledAt: String? = nil, + onProgress: ((UploadProgress) -> Void)? = nil ) async throws -> AppwriteModels.Execution { let apiPath: String = "/functions/{functionId}/executions" .replacingOccurrences(of: "{functionId}", with: functionId) - let apiParams: [String: Any?] = [ + var apiParams: [String: Any?] = [ "body": body, "async": async, "path": path, @@ -712,20 +795,23 @@ open class Functions: Service { "scheduledAt": scheduledAt ] - let apiHeaders: [String: String] = [ - "content-type": "application/json" + var apiHeaders: [String: String] = [ + "content-type": "multipart/form-data" ] let converter: (Any) -> AppwriteModels.Execution = { response in return AppwriteModels.Execution.from(map: response as! [String: Any]) } - return try await client.call( - method: "POST", + let idParamName: String? = nil + return try await client.chunkedUpload( path: apiPath, - headers: apiHeaders, - params: apiParams, - converter: converter + headers: &apiHeaders, + params: &apiParams, + paramName: paramName, + idParamName: idParamName, + converter: converter, + onProgress: onProgress ) } diff --git a/Sources/AppwriteModels/Execution.swift b/Sources/AppwriteModels/Execution.swift index 2cb6d9a..add85f6 100644 --- a/Sources/AppwriteModels/Execution.swift +++ b/Sources/AppwriteModels/Execution.swift @@ -52,6 +52,9 @@ public class Execution { /// Function 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, @@ -69,7 +72,8 @@ public class Execution { responseHeaders: [Headers], logs: String, errors: String, - duration: Double + duration: Double, + scheduledAt: String?? ) { self.id = id self.createdAt = createdAt @@ -87,6 +91,7 @@ public class Execution { self.logs = logs self.errors = errors self.duration = duration + self.scheduledAt = scheduledAt } public func toMap() -> [String: Any] { @@ -106,7 +111,8 @@ public class Execution { "responseHeaders": responseHeaders.map { $0.toMap() } as Any, "logs": logs as Any, "errors": errors as Any, - "duration": duration as Any + "duration": duration as Any, + "scheduledAt": scheduledAt as Any ] } @@ -127,7 +133,8 @@ public class Execution { responseHeaders: (map["responseHeaders"] as! [[String: Any]]).map { Headers.from(map: $0) }, logs: map["logs"] as! String, errors: map["errors"] as! String, - duration: map["duration"] as! Double + duration: map["duration"] as! Double, + scheduledAt: map["scheduledAt"] as? String? ) } } diff --git a/Sources/AppwriteModels/Runtime.swift b/Sources/AppwriteModels/Runtime.swift index 2e524ba..66906e1 100644 --- a/Sources/AppwriteModels/Runtime.swift +++ b/Sources/AppwriteModels/Runtime.swift @@ -7,6 +7,9 @@ public class Runtime { /// Runtime ID. public let id: String + /// Parent runtime key. + public let key: String + /// Runtime Name. public let name: String @@ -28,6 +31,7 @@ public class Runtime { init( id: String, + key: String, name: String, version: String, base: String, @@ -36,6 +40,7 @@ public class Runtime { supports: [Any] ) { self.id = id + self.key = key self.name = name self.version = version self.base = base @@ -47,6 +52,7 @@ public class Runtime { public func toMap() -> [String: Any] { return [ "$id": id as Any, + "key": key as Any, "name": name as Any, "version": version as Any, "base": base as Any, @@ -59,6 +65,7 @@ public class Runtime { public static func from(map: [String: Any] ) -> Runtime { return Runtime( id: map["$id"] as! String, + key: map["key"] as! String, name: map["name"] as! String, version: map["version"] as! String, base: map["base"] as! String, diff --git a/Sources/AppwriteModels/TemplateFunction.swift b/Sources/AppwriteModels/TemplateFunction.swift new file mode 100644 index 0000000..e174a05 --- /dev/null +++ b/Sources/AppwriteModels/TemplateFunction.swift @@ -0,0 +1,140 @@ +import Foundation +import JSONCodable + +/// Template Function +public class TemplateFunction { + + /// Function Template Icon. + public let icon: String + + /// Function Template ID. + public let id: String + + /// Function Template Name. + public let name: String + + /// Function Template Tagline. + public let tagline: String + + /// Execution permissions. + public let permissions: [Any] + + /// Function trigger events. + public let events: [Any] + + /// Function execution schedult in CRON format. + public let cron: String + + /// Function execution timeout in seconds. + public let timeout: Int + + /// Function use cases. + public let useCases: [Any] + + /// List of runtimes that can be used with this template. + public let runtimes: [TemplateRuntime] + + /// Function Template Instructions. + public let instructions: String + + /// VCS (Version Control System) Provider. + public let vcsProvider: String + + /// VCS (Version Control System) Repository ID + public let providerRepositoryId: String + + /// VCS (Version Control System) Owner. + public let providerOwner: String + + /// VCS (Version Control System) branch version (tag). + public let providerVersion: String + + /// Function variables. + public let variables: [TemplateVariable] + + /// Function scopes. + public let scopes: [Any] + + + init( + icon: String, + id: String, + name: String, + tagline: String, + permissions: [Any], + events: [Any], + cron: String, + timeout: Int, + useCases: [Any], + runtimes: [TemplateRuntime], + instructions: String, + vcsProvider: String, + providerRepositoryId: String, + providerOwner: String, + providerVersion: String, + variables: [TemplateVariable], + scopes: [Any] + ) { + self.icon = icon + self.id = id + self.name = name + self.tagline = tagline + self.permissions = permissions + self.events = events + self.cron = cron + self.timeout = timeout + self.useCases = useCases + self.runtimes = runtimes + self.instructions = instructions + self.vcsProvider = vcsProvider + self.providerRepositoryId = providerRepositoryId + self.providerOwner = providerOwner + self.providerVersion = providerVersion + self.variables = variables + self.scopes = scopes + } + + public func toMap() -> [String: Any] { + return [ + "icon": icon as Any, + "id": id as Any, + "name": name as Any, + "tagline": tagline as Any, + "permissions": permissions as Any, + "events": events as Any, + "cron": cron as Any, + "timeout": timeout as Any, + "useCases": useCases as Any, + "runtimes": runtimes.map { $0.toMap() } as Any, + "instructions": instructions as Any, + "vcsProvider": vcsProvider as Any, + "providerRepositoryId": providerRepositoryId as Any, + "providerOwner": providerOwner as Any, + "providerVersion": providerVersion as Any, + "variables": variables.map { $0.toMap() } as Any, + "scopes": scopes as Any + ] + } + + public static func from(map: [String: Any] ) -> TemplateFunction { + return TemplateFunction( + icon: map["icon"] as! String, + id: map["id"] as! String, + name: map["name"] as! String, + tagline: map["tagline"] as! String, + permissions: map["permissions"] as! [Any], + events: map["events"] as! [Any], + cron: map["cron"] as! String, + timeout: map["timeout"] as! Int, + useCases: map["useCases"] as! [Any], + runtimes: (map["runtimes"] as! [[String: Any]]).map { TemplateRuntime.from(map: $0) }, + instructions: map["instructions"] as! String, + vcsProvider: map["vcsProvider"] as! String, + providerRepositoryId: map["providerRepositoryId"] as! String, + providerOwner: map["providerOwner"] as! String, + providerVersion: map["providerVersion"] as! String, + variables: (map["variables"] as! [[String: Any]]).map { TemplateVariable.from(map: $0) }, + scopes: map["scopes"] as! [Any] + ) + } +} diff --git a/Sources/AppwriteModels/TemplateFunctionList.swift b/Sources/AppwriteModels/TemplateFunctionList.swift new file mode 100644 index 0000000..2fe319b --- /dev/null +++ b/Sources/AppwriteModels/TemplateFunctionList.swift @@ -0,0 +1,35 @@ +import Foundation +import JSONCodable + +/// Function Templates List +public class TemplateFunctionList { + + /// Total number of templates documents that matched your query. + public let total: Int + + /// List of templates. + public let templates: [TemplateFunction] + + + init( + total: Int, + templates: [TemplateFunction] + ) { + self.total = total + self.templates = templates + } + + public func toMap() -> [String: Any] { + return [ + "total": total as Any, + "templates": templates.map { $0.toMap() } as Any + ] + } + + public static func from(map: [String: Any] ) -> TemplateFunctionList { + return TemplateFunctionList( + total: map["total"] as! Int, + templates: (map["templates"] as! [[String: Any]]).map { TemplateFunction.from(map: $0) } + ) + } +} diff --git a/Sources/AppwriteModels/TemplateRuntime.swift b/Sources/AppwriteModels/TemplateRuntime.swift new file mode 100644 index 0000000..637c020 --- /dev/null +++ b/Sources/AppwriteModels/TemplateRuntime.swift @@ -0,0 +1,49 @@ +import Foundation +import JSONCodable + +/// Template Runtime +public class TemplateRuntime { + + /// Runtime Name. + public let name: String + + /// The build command used to build the deployment. + public let commands: String + + /// The entrypoint file used to execute the deployment. + public let entrypoint: String + + /// Path to function in VCS (Version Control System) repository + public let providerRootDirectory: String + + + init( + name: String, + commands: String, + entrypoint: String, + providerRootDirectory: String + ) { + self.name = name + self.commands = commands + self.entrypoint = entrypoint + self.providerRootDirectory = providerRootDirectory + } + + public func toMap() -> [String: Any] { + return [ + "name": name as Any, + "commands": commands as Any, + "entrypoint": entrypoint as Any, + "providerRootDirectory": providerRootDirectory as Any + ] + } + + public static func from(map: [String: Any] ) -> TemplateRuntime { + return TemplateRuntime( + name: map["name"] as! String, + commands: map["commands"] as! String, + entrypoint: map["entrypoint"] as! String, + providerRootDirectory: map["providerRootDirectory"] as! String + ) + } +} diff --git a/Sources/AppwriteModels/TemplateVariable.swift b/Sources/AppwriteModels/TemplateVariable.swift new file mode 100644 index 0000000..71c0a57 --- /dev/null +++ b/Sources/AppwriteModels/TemplateVariable.swift @@ -0,0 +1,63 @@ +import Foundation +import JSONCodable + +/// Template Variable +public class TemplateVariable { + + /// Variable Name. + public let name: String + + /// Variable Description. + public let description: String + + /// Variable Value. + public let value: String + + /// Variable Placeholder. + public let placeholder: String + + /// Is the variable required? + public let `required`: Bool + + /// Variable Type. + public let type: String + + + init( + name: String, + description: String, + value: String, + placeholder: String, + `required`: Bool, + type: String + ) { + self.name = name + self.description = description + self.value = value + self.placeholder = placeholder + self.`required` = `required` + self.type = type + } + + public func toMap() -> [String: Any] { + return [ + "name": name as Any, + "description": description as Any, + "value": value as Any, + "placeholder": placeholder as Any, + "`required`": `required` as Any, + "type": type as Any + ] + } + + public static func from(map: [String: Any] ) -> TemplateVariable { + return TemplateVariable( + name: map["name"] as! String, + description: map["description"] as! String, + value: map["value"] as! String, + placeholder: map["placeholder"] as! String, + `required`: map["required"] as! Bool, + type: map["type"] as! String + ) + } +} diff --git a/docs/examples/account/delete-mfa-authenticator.md b/docs/examples/account/delete-mfa-authenticator.md index e4f76e6..6d8854a 100644 --- a/docs/examples/account/delete-mfa-authenticator.md +++ b/docs/examples/account/delete-mfa-authenticator.md @@ -9,7 +9,6 @@ let client = Client() let account = Account(client) let result = try await account.deleteMfaAuthenticator( - type: .totp, - otp: "" + type: .totp ) diff --git a/docs/examples/functions/create.md b/docs/examples/functions/create.md index e508281..96d4b3f 100644 --- a/docs/examples/functions/create.md +++ b/docs/examples/functions/create.md @@ -29,6 +29,6 @@ let function = try await functions.create( templateRepository: "", // optional templateOwner: "", // optional templateRootDirectory: "", // optional - templateBranch: "" // optional + templateVersion: "" // optional ) diff --git a/docs/examples/functions/download-deployment.md b/docs/examples/functions/get-deployment-download.md similarity index 70% rename from docs/examples/functions/download-deployment.md rename to docs/examples/functions/get-deployment-download.md index 5e50b67..3d640a8 100644 --- a/docs/examples/functions/download-deployment.md +++ b/docs/examples/functions/get-deployment-download.md @@ -3,11 +3,11 @@ import Appwrite let client = Client() .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint .setProject("<YOUR_PROJECT_ID>") // Your project ID - .setKey("<YOUR_API_KEY>") // Your secret API key + .setSession("") // The user session to authenticate with let functions = Functions(client) -let bytes = try await functions.downloadDeployment( +let bytes = try await functions.getDeploymentDownload( functionId: "", deploymentId: "" ) diff --git a/docs/examples/functions/get-template.md b/docs/examples/functions/get-template.md new file mode 100644 index 0000000..e4fa185 --- /dev/null +++ b/docs/examples/functions/get-template.md @@ -0,0 +1,12 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + +let functions = Functions(client) + +let templateFunction = try await functions.getTemplate( + templateId: "" +) + diff --git a/docs/examples/functions/list-templates.md b/docs/examples/functions/list-templates.md new file mode 100644 index 0000000..d93beef --- /dev/null +++ b/docs/examples/functions/list-templates.md @@ -0,0 +1,15 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + +let functions = Functions(client) + +let templateFunctionList = try await functions.listTemplates( + runtimes: [], // optional + useCases: [], // optional + limit: 1, // optional + offset: 0 // optional +) +