diff --git a/README.md b/README.md index 314cfe7..5d5ad67 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Appwrite Web SDK ![License](https://img.shields.io/github/license/appwrite/sdk-for-web.svg?style=flat-square) -![Version](https://img.shields.io/badge/api%20version-1.6.1-blue.svg?style=flat-square) +![Version](https://img.shields.io/badge/api%20version-1.6.2-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 @@ import { Client, Account } from "appwrite"; To install with a CDN (content delivery network) add the following scripts to the bottom of your tag, but before you use any Appwrite services: ```html - + ``` diff --git a/package.json b/package.json index 6d17ef8..1e29eb0 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "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": "17.0.1", + "version": "17.0.2", "license": "BSD-3-Clause", "main": "dist/cjs/sdk.js", "exports": { diff --git a/src/client.ts b/src/client.ts index b93d845..c4895e8 100644 --- a/src/client.ts +++ b/src/client.ts @@ -315,7 +315,7 @@ class Client { 'x-sdk-name': 'Web', 'x-sdk-platform': 'client', 'x-sdk-language': 'web', - 'x-sdk-version': '17.0.1', + 'x-sdk-version': '17.0.2', 'X-Appwrite-Response-Format': '1.6.0', }; @@ -329,8 +329,12 @@ class Client { * @returns {this} */ setEndpoint(endpoint: string): this { + if (!endpoint.startsWith('http://') && !endpoint.startsWith('https://')) { + throw new AppwriteException('Invalid endpoint URL: ' + endpoint); + } + this.config.endpoint = endpoint; - this.config.endpointRealtime = this.config.endpointRealtime || this.config.endpoint.replace('https://', 'wss://').replace('http://', 'ws://'); + this.config.endpointRealtime = endpoint.replace('https://', 'wss://').replace('http://', 'ws://'); return this; } @@ -343,8 +347,11 @@ class Client { * @returns {this} */ setEndpointRealtime(endpointRealtime: string): this { - this.config.endpointRealtime = endpointRealtime; + if (!endpointRealtime.startsWith('ws://') && !endpointRealtime.startsWith('wss://')) { + throw new AppwriteException('Invalid realtime endpoint URL: ' + endpointRealtime); + } + this.config.endpointRealtime = endpointRealtime; return this; } @@ -656,6 +663,10 @@ class Client { async chunkedUpload(method: string, url: URL, headers: Headers = {}, originalPayload: Payload = {}, onProgress: (progress: UploadProgress) => void) { const file = Object.values(originalPayload).find((value) => value instanceof File); + if (!file) { + throw new Error('File not found in payload'); + } + if (file.size <= Client.CHUNK_SIZE) { return await this.call(method, url, headers, originalPayload); } @@ -704,7 +715,6 @@ class Client { const { uri, options } = this.prepareRequest(method, url, headers, params); let data: any = null; - let text: string = ''; const response = await fetch(uri, options); @@ -715,18 +725,22 @@ class Client { if (response.headers.get('content-type')?.includes('application/json')) { data = await response.json(); - text = JSON.stringify(data); } else if (responseType === 'arrayBuffer') { data = await response.arrayBuffer(); } else { - text = await response.text(); data = { - message: text + message: await response.text() }; } if (400 <= response.status) { - throw new AppwriteException(data?.message, response.status, data?.type, text); + let responseText = ''; + if (response.headers.get('content-type')?.includes('application/json') || responseType === 'arrayBuffer') { + responseText = JSON.stringify(data); + } else { + responseText = data?.message; + } + throw new AppwriteException(data?.message, response.status, data?.type, responseText); } const cookieFallback = response.headers.get('X-Fallback-Cookies'); diff --git a/src/enums/credit-card.ts b/src/enums/credit-card.ts index daf43c7..a96c73a 100644 --- a/src/enums/credit-card.ts +++ b/src/enums/credit-card.ts @@ -15,4 +15,5 @@ export enum CreditCard { Visa = 'visa', MIR = 'mir', Maestro = 'maestro', + Rupay = 'rupay', } \ No newline at end of file diff --git a/src/enums/o-auth-provider.ts b/src/enums/o-auth-provider.ts index b2bf4d1..7a3fcb3 100644 --- a/src/enums/o-auth-provider.ts +++ b/src/enums/o-auth-provider.ts @@ -13,6 +13,7 @@ export enum OAuthProvider { Dropbox = 'dropbox', Etsy = 'etsy', Facebook = 'facebook', + Figma = 'figma', Github = 'github', Gitlab = 'gitlab', Google = 'google', diff --git a/src/services/account.ts b/src/services/account.ts index 2a435bb..b3f42d8 100644 --- a/src/services/account.ts +++ b/src/services/account.ts @@ -24,7 +24,6 @@ export class Account { const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -135,7 +134,6 @@ This endpoint can also be used to convert an anonymous account to a normal one, const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -209,7 +207,6 @@ This endpoint can also be used to convert an anonymous account to a normal one, const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -410,7 +407,6 @@ This endpoint can also be used to convert an anonymous account to a normal one, const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -432,7 +428,6 @@ This endpoint can also be used to convert an anonymous account to a normal one, const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -596,7 +591,6 @@ This endpoint can also be used to convert an anonymous account to a normal one, const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -728,7 +722,6 @@ Please note that in order to avoid a [Redirect Attack](https://github.com/OWASP/ const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -889,7 +882,6 @@ A user is limited to 10 active sessions at a time by default. [Learn more about const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } payload['project'] = this.client.config.project; @@ -993,7 +985,6 @@ A user is limited to 10 active sessions at a time by default. [Learn more about const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -1297,7 +1288,6 @@ A user is limited to 10 active sessions at a time by default. [Learn more about const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } payload['project'] = this.client.config.project; diff --git a/src/services/avatars.ts b/src/services/avatars.ts index 3d48964..f1960a6 100644 --- a/src/services/avatars.ts +++ b/src/services/avatars.ts @@ -42,7 +42,6 @@ When one dimension is specified and the other is 0, the image is scaled with pre const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } payload['project'] = this.client.config.project; @@ -84,7 +83,6 @@ When one dimension is specified and the other is 0, the image is scaled with pre const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } payload['project'] = this.client.config.project; @@ -116,7 +114,6 @@ This endpoint does not follow HTTP redirects. const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } payload['project'] = this.client.config.project; @@ -158,7 +155,6 @@ When one dimension is specified and the other is 0, the image is scaled with pre const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } payload['project'] = this.client.config.project; @@ -200,7 +196,6 @@ This endpoint does not follow HTTP redirects. const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } payload['project'] = this.client.config.project; @@ -244,7 +239,6 @@ When one dimension is specified and the other is 0, the image is scaled with pre const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } payload['project'] = this.client.config.project; @@ -287,7 +281,6 @@ When one dimension is specified and the other is 0, the image is scaled with pre const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } payload['project'] = this.client.config.project; diff --git a/src/services/databases.ts b/src/services/databases.ts index aea2689..e8e493d 100644 --- a/src/services/databases.ts +++ b/src/services/databases.ts @@ -33,7 +33,6 @@ export class Databases { const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -45,6 +44,7 @@ export class Databases { } /** * Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) API or directly from your database console. + * * @param {string} databaseId * @param {string} collectionId @@ -119,7 +119,6 @@ export class Databases { const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( diff --git a/src/services/functions.ts b/src/services/functions.ts index 6468e12..9efc8b7 100644 --- a/src/services/functions.ts +++ b/src/services/functions.ts @@ -34,7 +34,6 @@ export class Functions { const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -114,7 +113,6 @@ export class Functions { const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( diff --git a/src/services/locale.ts b/src/services/locale.ts index 8dcd5ea..d36eaa3 100644 --- a/src/services/locale.ts +++ b/src/services/locale.ts @@ -23,7 +23,6 @@ export class Locale { const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -45,7 +44,6 @@ export class Locale { const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -67,7 +65,6 @@ export class Locale { const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -89,7 +86,6 @@ export class Locale { const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -111,7 +107,6 @@ export class Locale { const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -133,7 +128,6 @@ export class Locale { const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -155,7 +149,6 @@ export class Locale { const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -177,7 +170,6 @@ export class Locale { const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( diff --git a/src/services/storage.ts b/src/services/storage.ts index 00791d7..01ce961 100644 --- a/src/services/storage.ts +++ b/src/services/storage.ts @@ -35,7 +35,6 @@ export class Storage { const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -117,7 +116,6 @@ If you're creating a new file using one of the Appwrite SDKs, all the chunk const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -215,7 +213,6 @@ If you're creating a new file using one of the Appwrite SDKs, all the chunk const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } payload['project'] = this.client.config.project; @@ -290,7 +287,6 @@ If you're creating a new file using one of the Appwrite SDKs, all the chunk const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } payload['project'] = this.client.config.project; @@ -321,7 +317,6 @@ If you're creating a new file using one of the Appwrite SDKs, all the chunk const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } payload['project'] = this.client.config.project; diff --git a/src/services/teams.ts b/src/services/teams.ts index 4622f33..bb5d9da 100644 --- a/src/services/teams.ts +++ b/src/services/teams.ts @@ -29,7 +29,6 @@ export class Teams { const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -95,7 +94,6 @@ export class Teams { const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -188,7 +186,6 @@ export class Teams { const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -278,7 +275,6 @@ Please note that to avoid a [Redirect Attack](https://github.com/OWASP/CheatShee const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call( @@ -419,7 +415,6 @@ If the request is successful, a session for the user is automatically created. const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json', } return this.client.call(