diff --git a/README.md b/README.md index 8a06d52..d77ecca 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Appwrite Node.js SDK ![License](https://img.shields.io/github/license/appwrite/sdk-for-node.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 6434cff..173c663 100644 --- a/docs/examples/account/delete-mfa-authenticator.md +++ b/docs/examples/account/delete-mfa-authenticator.md @@ -8,6 +8,5 @@ const client = new sdk.Client() const account = new sdk.Account(client); const result = await account.deleteMfaAuthenticator( - sdk.AuthenticatorType.Totp, // type - '' // otp + sdk.AuthenticatorType.Totp // type ); diff --git a/docs/examples/functions/create-execution.md b/docs/examples/functions/create-execution.md index 1b5e09b..cf531c7 100644 --- a/docs/examples/functions/create-execution.md +++ b/docs/examples/functions/create-execution.md @@ -1,4 +1,5 @@ const sdk = require('node-appwrite'); +const fs = require('fs'); const client = new sdk.Client() .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint diff --git a/docs/examples/functions/create.md b/docs/examples/functions/create.md index 0ba3985..c4deaf6 100644 --- a/docs/examples/functions/create.md +++ b/docs/examples/functions/create.md @@ -28,5 +28,5 @@ const result = 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 73% rename from docs/examples/functions/download-deployment.md rename to docs/examples/functions/get-deployment-download.md index cae51c9..3369784 100644 --- a/docs/examples/functions/download-deployment.md +++ b/docs/examples/functions/get-deployment-download.md @@ -3,11 +3,11 @@ const sdk = require('node-appwrite'); const client = new sdk.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 sdk.Functions(client); -const result = await functions.downloadDeployment( +const result = 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..08ce857 --- /dev/null +++ b/docs/examples/functions/get-template.md @@ -0,0 +1,11 @@ +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>'); // Your project ID + +const functions = new sdk.Functions(client); + +const result = 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..a8203e5 --- /dev/null +++ b/docs/examples/functions/list-templates.md @@ -0,0 +1,14 @@ +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>'); // Your project ID + +const functions = new sdk.Functions(client); + +const result = await functions.listTemplates( + [], // runtimes (optional) + [], // useCases (optional) + 1, // limit (optional) + 0 // offset (optional) +); diff --git a/package.json b/package.json index 4a74625..3b57707 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "node-appwrite", "homepage": "https://appwrite.io/support", "description": "Appwrite is an open-source self-hosted backend server that abstract and simplify complex and repetitive development tasks behind a very simple REST API", - "version": "14.0.0-rc.1", + "version": "14.0.0-rc.2", "license": "BSD-3-Clause", "main": "dist/index.js", "type": "commonjs", diff --git a/src/client.ts b/src/client.ts index 9f5e1b4..bb89292 100644 --- a/src/client.ts +++ b/src/client.ts @@ -33,7 +33,7 @@ class AppwriteException extends Error { } function getUserAgent() { - let ua = 'AppwriteNodeJSSDK/14.0.0-rc.1'; + let ua = 'AppwriteNodeJSSDK/14.0.0-rc.2'; // `process` is a global in Node.js, but not fully available in all runtimes. const platform: string[] = []; @@ -82,9 +82,9 @@ class Client { 'x-sdk-name': 'Node.js', 'x-sdk-platform': 'server', 'x-sdk-language': 'nodejs', - 'x-sdk-version': '14.0.0-rc.1', + 'x-sdk-version': '14.0.0-rc.2', 'user-agent' : getUserAgent(), - 'X-Appwrite-Response-Format': '1.5.0', + 'X-Appwrite-Response-Format': '1.6.0', }; /** diff --git a/src/models.ts b/src/models.ts index 72a5547..98f6c79 100644 --- a/src/models.ts +++ b/src/models.ts @@ -171,6 +171,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 */ @@ -1716,6 +1729,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 */ @@ -1724,6 +1860,10 @@ export namespace Models { * Runtime ID. */ $id: string; + /** + * Parent runtime key. + */ + key: string; /** * Runtime Name. */ @@ -1914,6 +2054,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 d000c8a..213b137 100644 --- a/src/services/account.ts +++ b/src/services/account.ts @@ -264,7 +264,7 @@ This endpoint can also be used to convert an anonymous account to a normal one, ); } /** - * Add Authenticator + * Create Authenticator * * Add an authenticator app to be used as an MFA factor. Verify the authenticator using the [verify authenticator](/docs/references/cloud/client-web/account#updateMfaAuthenticator) method. * @@ -332,22 +332,15 @@ This endpoint can also be used to convert an anonymous account to a normal one, * 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; - } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -362,7 +355,7 @@ This endpoint can also be used to convert an anonymous account to a normal one, ); } /** - * 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) method. * @@ -1378,7 +1371,7 @@ Please note that in order to avoid a [Redirect Attack](https://github.com/OWASP/ ); } /** - * 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 verify the user email ownership. If confirmed this route will return a 200 status code. * diff --git a/src/services/avatars.ts b/src/services/avatars.ts index c9a9cbb..3111f49 100644 --- a/src/services/avatars.ts +++ b/src/services/avatars.ts @@ -103,6 +103,7 @@ When one dimension is specified and the other is 0, the image is scaled with pre * * 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} @@ -182,6 +183,7 @@ When one dimension is specified and the other is 0, the image is scaled with pre When one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an 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 d50a4db..0ecbfec 100644 --- a/src/services/functions.ts +++ b/src/services/functions.ts @@ -67,11 +67,11 @@ export class Functions { * @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"'); } @@ -143,8 +143,8 @@ export class Functions { if (typeof templateRootDirectory !== 'undefined') { payload['templateRootDirectory'] = templateRootDirectory; } - if (typeof templateBranch !== 'undefined') { - payload['templateBranch'] = templateBranch; + if (typeof templateVersion !== 'undefined') { + payload['templateVersion'] = templateVersion; } const uri = new URL(this.client.config.endpoint + apiPath); @@ -183,6 +183,74 @@ export class Functions { payload, ); } + /** + * 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; + } + const uri = new URL(this.client.config.endpoint + apiPath); + + const apiHeaders: { [header: string]: string } = { + 'content-type': 'application/json', + } + + return await this.client.call( + 'get', + uri, + apiHeaders, + payload, + ); + } + /** + * 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 = {}; + const uri = new URL(this.client.config.endpoint + apiPath); + + const apiHeaders: { [header: string]: string } = { + 'content-type': 'application/json', + } + + return await this.client.call( + 'get', + uri, + apiHeaders, + payload, + ); + } /** * Get function * @@ -458,7 +526,7 @@ Use the "command" param to set the entrypoint used to execute your cod ); } /** - * 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 execution endpoint. * @@ -588,7 +656,7 @@ Use the "command" param to set the entrypoint used to execute your cod ); } /** - * Download Deployment + * Download deployment * * Get a Deployment's contents by its unique ID. This endpoint supports range requests for partial or streaming file download. * @@ -597,7 +665,7 @@ Use the "command" param to set the entrypoint used to execute your cod * @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"'); } @@ -671,7 +739,7 @@ Use the "command" param to set the entrypoint used to execute your cod * @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"'); } @@ -698,14 +766,15 @@ Use the "command" param to set the entrypoint used to execute your cod const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', + 'content-type': 'multipart/form-data', } - return await this.client.call( + return await this.client.chunkedUpload( 'post', uri, apiHeaders, payload, + onProgress ); } /**