diff --git a/README.md b/README.md index dbbc95b..46e347f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Appwrite Deno SDK ![License](https://img.shields.io/github/license/appwrite/sdk-for-deno.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) diff --git a/docs/examples/account/delete-mfa-authenticator.md b/docs/examples/account/delete-mfa-authenticator.md index 0f32c19..3fafb7e 100644 --- a/docs/examples/account/delete-mfa-authenticator.md +++ b/docs/examples/account/delete-mfa-authenticator.md @@ -8,6 +8,5 @@ const client = new Client() const account = new Account(client); const response = await account.deleteMfaAuthenticator( - AuthenticatorType.Totp, // type - '' // otp + AuthenticatorType.Totp // type ); diff --git a/docs/examples/functions/create.md b/docs/examples/functions/create.md index c31bdfe..9b3264e 100644 --- a/docs/examples/functions/create.md +++ b/docs/examples/functions/create.md @@ -28,5 +28,5 @@ const response = 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 76% rename from docs/examples/functions/download-deployment.md rename to docs/examples/functions/get-deployment-download.md index 2fdf148..21980fa 100644 --- a/docs/examples/functions/download-deployment.md +++ b/docs/examples/functions/get-deployment-download.md @@ -3,11 +3,11 @@ import { Client, Functions } from "https://deno.land/x/appwrite/mod.ts"; const client = new 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 const functions = new Functions(client); -const result = functions.downloadDeployment( +const result = 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..961e84e --- /dev/null +++ b/docs/examples/functions/get-template.md @@ -0,0 +1,11 @@ +import { Client, Functions } from "https://deno.land/x/appwrite/mod.ts"; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>'); // Your project ID + +const functions = new Functions(client); + +const response = 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..005464a --- /dev/null +++ b/docs/examples/functions/list-templates.md @@ -0,0 +1,14 @@ +import { Client, Functions } from "https://deno.land/x/appwrite/mod.ts"; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>'); // Your project ID + +const functions = new Functions(client); + +const response = await functions.listTemplates( + [], // runtimes (optional) + [], // useCases (optional) + 1, // limit (optional) + 0 // offset (optional) +); diff --git a/src/client.ts b/src/client.ts index 615c294..fd07765 100644 --- a/src/client.ts +++ b/src/client.ts @@ -11,12 +11,12 @@ export class Client { endpoint: string = 'https://cloud.appwrite.io/v1'; headers: Payload = { 'content-type': '', - 'user-agent' : `AppwriteDenoSDK/11.0.0 (${Deno.build.os}; ${Deno.build.arch})`, + 'user-agent' : `AppwriteDenoSDK/12.0.0-rc.1 (${Deno.build.os}; ${Deno.build.arch})`, 'x-sdk-name': 'Deno', 'x-sdk-platform': 'server', 'x-sdk-language': 'deno', - 'x-sdk-version': '11.0.0', - 'X-Appwrite-Response-Format':'1.5.0', + 'x-sdk-version': '12.0.0-rc.1', + 'X-Appwrite-Response-Format':'1.6.0', }; /** diff --git a/src/models.d.ts b/src/models.d.ts index 345300a..ac3cc9f 100644 --- a/src/models.d.ts +++ b/src/models.d.ts @@ -168,6 +168,19 @@ export namespace Models { */ functions: Function[]; } + /** + * Function Templates List + */ + export type TemplateFunctionList = { + /** + * Total number of templates documents that matched your query. + */ + total: number; + /** + * List of templates. + */ + templates: TemplateFunction[]; + } /** * Runtimes List */ @@ -1711,6 +1724,129 @@ export namespace Models { */ providerSilentMode: boolean; } + /** + * Template Function + */ + export type TemplateFunction = { + /** + * Function Template Icon. + */ + icon: string; + /** + * Function Template ID. + */ + id: string; + /** + * Function Template Name. + */ + name: string; + /** + * Function Template Tagline. + */ + tagline: string; + /** + * Execution permissions. + */ + permissions: string[]; + /** + * Function trigger events. + */ + events: string[]; + /** + * Function execution schedult in CRON format. + */ + cron: string; + /** + * Function execution timeout in seconds. + */ + timeout: number; + /** + * Function use cases. + */ + useCases: string[]; + /** + * List of runtimes that can be used with this template. + */ + runtimes: TemplateRuntime[]; + /** + * Function Template Instructions. + */ + instructions: string; + /** + * VCS (Version Control System) Provider. + */ + vcsProvider: string; + /** + * VCS (Version Control System) Repository ID + */ + providerRepositoryId: string; + /** + * VCS (Version Control System) Owner. + */ + providerOwner: string; + /** + * VCS (Version Control System) branch version (tag). + */ + providerVersion: string; + /** + * Function variables. + */ + variables: TemplateVariable[]; + /** + * Function scopes. + */ + scopes: string[]; + } + /** + * Template Runtime + */ + export type TemplateRuntime = { + /** + * Runtime Name. + */ + name: string; + /** + * The build command used to build the deployment. + */ + commands: string; + /** + * The entrypoint file used to execute the deployment. + */ + entrypoint: string; + /** + * Path to function in VCS (Version Control System) repository + */ + providerRootDirectory: string; + } + /** + * Template Variable + */ + export type TemplateVariable = { + /** + * Variable Name. + */ + name: string; + /** + * Variable Description. + */ + description: string; + /** + * Variable Value. + */ + value: string; + /** + * Variable Placeholder. + */ + placeholder: string; + /** + * Is the variable required? + */ + required: boolean; + /** + * Variable Type. + */ + type: string; + } /** * Runtime */ @@ -1719,6 +1855,10 @@ export namespace Models { * Runtime ID. */ $id: string; + /** + * Parent runtime key. + */ + key: string; /** * Runtime Name. */ @@ -1909,6 +2049,10 @@ export namespace Models { * Function execution duration in seconds. */ duration: number; + /** + * The scheduled time for execution. If left empty, execution will be queued immediately. + */ + scheduledAt?: string; } /** * Build diff --git a/src/services/account.ts b/src/services/account.ts index 6c75523..52279ad 100644 --- a/src/services/account.ts +++ b/src/services/account.ts @@ -286,7 +286,7 @@ export class Account extends Service { ); } /** - * Add Authenticator + * Create Authenticator * * Add an authenticator app to be used as an MFA factor. Verify the * authenticator using the [verify @@ -358,25 +358,17 @@ export class Account extends Service { * Delete an authenticator for a user by ID. * * @param {AuthenticatorType} type - * @param {string} otp * @throws {AppwriteException} * @returns {Promise} */ - async deleteMfaAuthenticator(type: AuthenticatorType, otp: string): Promise { + async deleteMfaAuthenticator(type: AuthenticatorType): Promise { if (typeof type === 'undefined') { throw new AppwriteException('Missing required parameter: "type"'); } - if (typeof otp === 'undefined') { - throw new AppwriteException('Missing required parameter: "otp"'); - } - const apiPath = '/account/mfa/authenticators/{type}'.replace('{type}', type); const payload: Payload = {}; - if (typeof otp !== 'undefined') { - payload['otp'] = otp; - } return await this.client.call( 'delete', apiPath, @@ -388,7 +380,7 @@ export class Account extends 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) @@ -1499,7 +1491,7 @@ export class Account extends 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/src/services/avatars.ts b/src/services/avatars.ts index 1f18324..f47b654 100644 --- a/src/services/avatars.ts +++ b/src/services/avatars.ts @@ -131,6 +131,7 @@ export class Avatars extends 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 {AppwriteException} @@ -222,6 +223,7 @@ export class Avatars extends 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 {number} width diff --git a/src/services/functions.ts b/src/services/functions.ts index 2ba992c..3726590 100644 --- a/src/services/functions.ts +++ b/src/services/functions.ts @@ -84,11 +84,11 @@ export class Functions extends Service { * @param {string} templateRepository * @param {string} templateOwner * @param {string} templateRootDirectory - * @param {string} templateBranch + * @param {string} templateVersion * @throws {AppwriteException} * @returns {Promise} */ - async create(functionId: string, name: string, runtime: Runtime, execute?: string[], events?: string[], schedule?: string, timeout?: number, enabled?: boolean, logging?: boolean, entrypoint?: string, commands?: string, scopes?: string[], installationId?: string, providerRepositoryId?: string, providerBranch?: string, providerSilentMode?: boolean, providerRootDirectory?: string, templateRepository?: string, templateOwner?: string, templateRootDirectory?: string, templateBranch?: string): Promise { + async create(functionId: string, name: string, runtime: Runtime, execute?: string[], events?: string[], schedule?: string, timeout?: number, enabled?: boolean, logging?: boolean, entrypoint?: string, commands?: string, scopes?: string[], installationId?: string, providerRepositoryId?: string, providerBranch?: string, providerSilentMode?: boolean, providerRootDirectory?: string, templateRepository?: string, templateOwner?: string, templateRootDirectory?: string, templateVersion?: string): Promise { if (typeof functionId === 'undefined') { throw new AppwriteException('Missing required parameter: "functionId"'); } @@ -164,8 +164,8 @@ export class Functions extends Service { if (typeof templateRootDirectory !== 'undefined') { payload['templateRootDirectory'] = templateRootDirectory; } - if (typeof templateBranch !== 'undefined') { - payload['templateBranch'] = templateBranch; + if (typeof templateVersion !== 'undefined') { + payload['templateVersion'] = templateVersion; } return await this.client.call( 'post', @@ -199,6 +199,79 @@ export class Functions extends Service { 'json' ); } + /** + * 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 {number} limit + * @param {number} offset + * @throws {AppwriteException} + * @returns {Promise} + */ + async listTemplates(runtimes?: string[], useCases?: string[], limit?: number, offset?: number): Promise { + const apiPath = '/functions/templates'; + const payload: Payload = {}; + + if (typeof runtimes !== 'undefined') { + payload['runtimes'] = runtimes; + } + + if (typeof useCases !== 'undefined') { + payload['useCases'] = useCases; + } + + if (typeof limit !== 'undefined') { + payload['limit'] = limit; + } + + if (typeof offset !== 'undefined') { + payload['offset'] = offset; + } + + return await this.client.call( + 'get', + apiPath, + { + 'content-type': 'application/json', + }, + payload, + 'json' + ); + } + /** + * 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 {AppwriteException} + * @returns {Promise} + */ + async getTemplate(templateId: string): Promise { + if (typeof templateId === 'undefined') { + throw new AppwriteException('Missing required parameter: "templateId"'); + } + + const apiPath = '/functions/templates/{templateId}'.replace('{templateId}', templateId); + const payload: Payload = {}; + + return await this.client.call( + 'get', + apiPath, + { + 'content-type': 'application/json', + }, + payload, + 'json' + ); + } /** * Get function * @@ -559,7 +632,7 @@ export class Functions extends 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 @@ -689,7 +762,7 @@ export class Functions extends 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. @@ -699,7 +772,7 @@ export class Functions extends Service { * @throws {AppwriteException} * @returns {Promise} */ - async downloadDeployment(functionId: string, deploymentId: string): Promise { + async getDeploymentDownload(functionId: string, deploymentId: string): Promise { if (typeof functionId === 'undefined') { throw new AppwriteException('Missing required parameter: "functionId"'); } @@ -777,7 +850,7 @@ export class Functions extends Service { * @throws {AppwriteException} * @returns {Promise} */ - async createExecution(functionId: string, body?: string, async?: boolean, xpath?: string, method?: ExecutionMethod, headers?: object, scheduledAt?: string): Promise { + async createExecution(functionId: string, body?: string, async?: boolean, xpath?: string, method?: ExecutionMethod, headers?: object, scheduledAt?: string, onProgress = (progress: UploadProgress) => {}): Promise { if (typeof functionId === 'undefined') { throw new AppwriteException('Missing required parameter: "functionId"'); } @@ -789,7 +862,7 @@ export class Functions extends Service { payload['body'] = body; } if (typeof async !== 'undefined') { - payload['async'] = async; + payload['async'] = async.toString(); } if (typeof xpath !== 'undefined') { payload['path'] = xpath; @@ -798,20 +871,11 @@ export class Functions extends Service { payload['method'] = method; } if (typeof headers !== 'undefined') { - payload['headers'] = headers; + payload['headers'] = headers.toString(); } if (typeof scheduledAt !== 'undefined') { payload['scheduledAt'] = scheduledAt; } - return await this.client.call( - 'post', - apiPath, - { - 'content-type': 'application/json', - }, - payload, - 'json' - ); } /** * Get execution diff --git a/test/services/account.test.ts b/test/services/account.test.ts index e6f5044..58664e6 100644 --- a/test/services/account.test.ts +++ b/test/services/account.test.ts @@ -247,7 +247,6 @@ describe('Account service', () => { const response = await account.deleteMfaAuthenticator( 'totp', - '', ); const text = await response.text(); diff --git a/test/services/functions.test.ts b/test/services/functions.test.ts index db966d5..8d1dd61 100644 --- a/test/services/functions.test.ts +++ b/test/services/functions.test.ts @@ -81,6 +81,52 @@ describe('Functions service', () => { }); + test('test method listTemplates()', async () => { + const data = { + 'total': 5, + 'templates': [],}; + + const stubbedFetch = stub(globalThis, 'fetch', () => Promise.resolve(Response.json(data))); + + const response = await functions.listTemplates( + ); + + assertEquals(response, data); + stubbedFetch.restore(); + }); + + + test('test method getTemplate()', async () => { + const data = { + 'icon': 'icon-lightning-bolt', + 'id': 'starter', + 'name': 'Starter function', + 'tagline': 'A simple function to get started.', + 'permissions': [], + 'events': [], + 'cron': '0 0 * * *', + 'timeout': 300, + 'useCases': [], + 'runtimes': [], + 'instructions': 'For documentation and instructions check out .', + 'vcsProvider': 'github', + 'providerRepositoryId': 'templates', + 'providerOwner': 'appwrite', + 'providerVersion': 'main', + 'variables': [], + 'scopes': [],}; + + const stubbedFetch = stub(globalThis, 'fetch', () => Promise.resolve(Response.json(data))); + + const response = await functions.getTemplate( + '', + ); + + assertEquals(response, data); + stubbedFetch.restore(); + }); + + test('test method get()', async () => { const data = { '\$id': '5e5ea5c16897e', @@ -358,12 +404,12 @@ describe('Functions service', () => { }); - test('test method downloadDeployment()', async () => { + test('test method getDeploymentDownload()', async () => { const data = new Uint8Array(0); const stubbedFetch = stub(globalThis, 'fetch', () => Promise.resolve(new Response(data.buffer))); - const response = await functions.downloadDeployment( + const response = await functions.getDeploymentDownload( '', '', );