From f642ef15f9800fc93d57c54b29c2e211eeacd251 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 20 May 2025 06:50:33 +0000 Subject: [PATCH 1/4] feat: (breaking) methods to generate file URLs --- CHANGELOG.md | 7 + docs/examples/databases/create-document.md | 4 +- src/client.ts | 4 +- src/services/account.ts | 1 + src/services/avatars.ts | 333 +++++++++++++++++++-- src/services/databases.ts | 1 + src/services/functions.ts | 1 + src/services/graphql.ts | 1 + src/services/locale.ts | 1 + src/services/messaging.ts | 1 + src/services/storage.ts | 157 +++++++++- src/services/teams.ts | 1 + 12 files changed, 478 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f720e11a..1bc7d893 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Change log +## 0.9.0 + +* Add `token` param to `getFilePreview` and `getFileView` for File tokens usage +* Update default `quality` for `getFilePreview` from 0 to -1 +* Remove `Gif` from ImageFormat enum +* Remove `search` param from `listExecutions` method + ## 0.7.4 * Upgrade dependencies to resolve PlatformConstants error with Expo 53 diff --git a/docs/examples/databases/create-document.md b/docs/examples/databases/create-document.md index ec768fcf..1b28231e 100644 --- a/docs/examples/databases/create-document.md +++ b/docs/examples/databases/create-document.md @@ -2,9 +2,7 @@ import { Client, Databases } from "react-native-appwrite"; const client = new Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint - .setSession('') // The user session to authenticate with - .setKey('') // - .setJWT(''); // Your secret JSON Web Token + .setProject(''); // Your project ID const databases = new Databases(client); diff --git a/src/client.ts b/src/client.ts index bc3d647c..5c0799bd 100644 --- a/src/client.ts +++ b/src/client.ts @@ -416,7 +416,7 @@ class Client { } } - async call(method: string, url: URL, headers: Headers = {}, params: Payload = {}): Promise { + async call(method: string, url: URL, headers: Headers = {}, params: Payload = {}, responseType = 'json'): Promise { method = method.toUpperCase(); headers = Object.assign({}, this.headers, headers); @@ -469,6 +469,8 @@ class Client { if (response.headers.get('content-type')?.includes('application/json')) { data = await response.json(); + } else if (responseType === 'arrayBuffer') { + data = await response.arrayBuffer(); } else { data = { message: await response.text() diff --git a/src/services/account.ts b/src/services/account.ts index bcd37339..b48f2549 100644 --- a/src/services/account.ts +++ b/src/services/account.ts @@ -1457,4 +1457,5 @@ export class Account extends Service { 'content-type': 'application/json', }, payload); } + }; diff --git a/src/services/avatars.ts b/src/services/avatars.ts index 1d640843..8e2e20a7 100644 --- a/src/services/avatars.ts +++ b/src/services/avatars.ts @@ -33,9 +33,9 @@ export class Avatars extends Service { * @param {number} height * @param {number} quality * @throws {AppwriteException} - * @returns {URL} + * @returns {ArrayBuffer} */ - getBrowser(code: Browser, width?: number, height?: number, quality?: number): URL { + getBrowser(code: Browser, width?: number, height?: number, quality?: number): Promise { if (typeof code === 'undefined') { throw new AppwriteException('Missing required parameter: "code"'); } @@ -62,7 +62,8 @@ export class Avatars extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return uri; + return this.client.call('get', uri, { + }, payload, 'arrayBuffer'); } /** @@ -81,9 +82,9 @@ export class Avatars extends Service { * @param {number} height * @param {number} quality * @throws {AppwriteException} - * @returns {URL} + * @returns {ArrayBuffer} */ - getCreditCard(code: CreditCard, width?: number, height?: number, quality?: number): URL { + getCreditCard(code: CreditCard, width?: number, height?: number, quality?: number): Promise { if (typeof code === 'undefined') { throw new AppwriteException('Missing required parameter: "code"'); } @@ -110,7 +111,8 @@ export class Avatars extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return uri; + return this.client.call('get', uri, { + }, payload, 'arrayBuffer'); } /** @@ -121,9 +123,9 @@ export class Avatars extends Service { * * @param {string} url * @throws {AppwriteException} - * @returns {URL} + * @returns {ArrayBuffer} */ - getFavicon(url: string): URL { + getFavicon(url: string): Promise { if (typeof url === 'undefined') { throw new AppwriteException('Missing required parameter: "url"'); } @@ -142,7 +144,8 @@ export class Avatars extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return uri; + return this.client.call('get', uri, { + }, payload, 'arrayBuffer'); } /** @@ -162,9 +165,9 @@ export class Avatars extends Service { * @param {number} height * @param {number} quality * @throws {AppwriteException} - * @returns {URL} + * @returns {ArrayBuffer} */ - getFlag(code: Flag, width?: number, height?: number, quality?: number): URL { + getFlag(code: Flag, width?: number, height?: number, quality?: number): Promise { if (typeof code === 'undefined') { throw new AppwriteException('Missing required parameter: "code"'); } @@ -191,7 +194,8 @@ export class Avatars extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return uri; + return this.client.call('get', uri, { + }, payload, 'arrayBuffer'); } /** @@ -211,9 +215,9 @@ export class Avatars extends Service { * @param {number} width * @param {number} height * @throws {AppwriteException} - * @returns {URL} + * @returns {ArrayBuffer} */ - getImage(url: string, width?: number, height?: number): URL { + getImage(url: string, width?: number, height?: number): Promise { if (typeof url === 'undefined') { throw new AppwriteException('Missing required parameter: "url"'); } @@ -240,7 +244,8 @@ export class Avatars extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return uri; + return this.client.call('get', uri, { + }, payload, 'arrayBuffer'); } /** @@ -266,9 +271,9 @@ export class Avatars extends Service { * @param {number} height * @param {string} background * @throws {AppwriteException} - * @returns {URL} + * @returns {ArrayBuffer} */ - getInitials(name?: string, width?: number, height?: number, background?: string): URL { + getInitials(name?: string, width?: number, height?: number, background?: string): Promise { const apiPath = '/avatars/initials'; const payload: Payload = {}; @@ -295,7 +300,8 @@ export class Avatars extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return uri; + return this.client.call('get', uri, { + }, payload, 'arrayBuffer'); } /** @@ -308,9 +314,9 @@ export class Avatars extends Service { * @param {number} margin * @param {boolean} download * @throws {AppwriteException} - * @returns {URL} + * @returns {ArrayBuffer} */ - getQR(text: string, size?: number, margin?: number, download?: boolean): URL { + getQR(text: string, size?: number, margin?: number, download?: boolean): Promise { if (typeof text === 'undefined') { throw new AppwriteException('Missing required parameter: "text"'); } @@ -341,6 +347,291 @@ export class Avatars extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return uri; + return this.client.call('get', uri, { + }, payload, 'arrayBuffer'); + } + + + /** + * You can use this endpoint to show different browser icons to your users. + * The code argument receives the browser code as it appears in your user [GET + * /account/sessions](https://appwrite.io/docs/references/cloud/client-web/account#getSessions) + * endpoint. Use width, height and quality arguments to change the output + * settings. + * + * 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 100x100px. + * + * @param {Browser} code + * @param {number} width + * @param {number} height + * @param {number} quality + * @throws {AppwriteException} + * @returns ArrayBuffer + + */ + getBrowserURL(code: Browser, width?: number, height?: number, quality?: number): Promise { + const apiPath = '/avatars/browsers/{code}'.replace('{code}', code); + const payload: Payload = {}; + + if (typeof width !== 'undefined') { + payload['width'] = width; + } + + if (typeof height !== 'undefined') { + payload['height'] = height; + } + + if (typeof quality !== 'undefined') { + payload['quality'] = quality; + } + + const uri = new URL(this.client.config.endpoint + apiPath); + + return this.client.call('get', uri, { + }, payload); + } + + /** + * The credit card endpoint will return you the icon of the credit card + * provider you need. Use width, height and quality arguments to change the + * output settings. + * + * 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 100x100px. + * + * + * @param {CreditCard} code + * @param {number} width + * @param {number} height + * @param {number} quality + * @throws {AppwriteException} + * @returns ArrayBuffer + + */ + getCreditCardURL(code: CreditCard, width?: number, height?: number, quality?: number): Promise { + const apiPath = '/avatars/credit-cards/{code}'.replace('{code}', code); + const payload: Payload = {}; + + if (typeof width !== 'undefined') { + payload['width'] = width; + } + + if (typeof height !== 'undefined') { + payload['height'] = height; + } + + if (typeof quality !== 'undefined') { + payload['quality'] = quality; + } + + const uri = new URL(this.client.config.endpoint + apiPath); + + return this.client.call('get', uri, { + }, payload); + } + + /** + * 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} + * @returns ArrayBuffer + + */ + getFaviconURL(url: string): Promise { + const apiPath = '/avatars/favicon'; + const payload: Payload = {}; + + if (typeof url !== 'undefined') { + payload['url'] = url; + } + + const uri = new URL(this.client.config.endpoint + apiPath); + + return this.client.call('get', uri, { + }, payload); + } + + /** + * You can use this endpoint to show different country flags icons to your + * users. The code argument receives the 2 letter country code. Use width, + * height and quality arguments to change the output settings. Country codes + * follow the [ISO 3166-1](https://en.wikipedia.org/wiki/ISO_3166-1) standard. + * + * 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 100x100px. + * + * + * @param {Flag} code + * @param {number} width + * @param {number} height + * @param {number} quality + * @throws {AppwriteException} + * @returns ArrayBuffer + + */ + getFlagURL(code: Flag, width?: number, height?: number, quality?: number): Promise { + const apiPath = '/avatars/flags/{code}'.replace('{code}', code); + const payload: Payload = {}; + + if (typeof width !== 'undefined') { + payload['width'] = width; + } + + if (typeof height !== 'undefined') { + payload['height'] = height; + } + + if (typeof quality !== 'undefined') { + payload['quality'] = quality; + } + + const uri = new URL(this.client.config.endpoint + apiPath); + + return this.client.call('get', uri, { + }, payload); + } + + /** + * Use this endpoint to fetch a remote image URL and crop it to any image size + * you want. This endpoint is very useful if you need to crop and display + * remote images in your app or in case you want to make sure a 3rd party + * image is properly served using a TLS protocol. + * + * 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 + * @param {number} height + * @throws {AppwriteException} + * @returns ArrayBuffer + + */ + getImageURL(url: string, width?: number, height?: number): Promise { + const apiPath = '/avatars/image'; + const payload: Payload = {}; + + if (typeof url !== 'undefined') { + payload['url'] = url; + } + + if (typeof width !== 'undefined') { + payload['width'] = width; + } + + if (typeof height !== 'undefined') { + payload['height'] = height; + } + + const uri = new URL(this.client.config.endpoint + apiPath); + + return this.client.call('get', uri, { + }, payload); + } + + /** + * Use this endpoint to show your user initials avatar icon on your website or + * app. By default, this route will try to print your logged-in user name or + * email initials. You can also overwrite the user name if you pass the 'name' + * parameter. If no name is given and no user is logged, an empty avatar will + * be returned. + * + * You can use the color and background params to change the avatar colors. By + * default, a random theme will be selected. The random theme will persist for + * the user's initials when reloading the same theme will always return for + * the same initials. + * + * 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 100x100px. + * + * + * @param {string} name + * @param {number} width + * @param {number} height + * @param {string} background + * @throws {AppwriteException} + * @returns ArrayBuffer + + */ + getInitialsURL(name?: string, width?: number, height?: number, background?: string): Promise { + const apiPath = '/avatars/initials'; + const payload: Payload = {}; + + if (typeof name !== 'undefined') { + payload['name'] = name; + } + + if (typeof width !== 'undefined') { + payload['width'] = width; + } + + if (typeof height !== 'undefined') { + payload['height'] = height; + } + + if (typeof background !== 'undefined') { + payload['background'] = background; + } + + const uri = new URL(this.client.config.endpoint + apiPath); + + return this.client.call('get', uri, { + }, payload); + } + + /** + * Converts a given plain text to a QR code image. You can use the query + * parameters to change the size and style of the resulting image. + * + * + * @param {string} text + * @param {number} size + * @param {number} margin + * @param {boolean} download + * @throws {AppwriteException} + * @returns ArrayBuffer + + */ + getQRURL(text: string, size?: number, margin?: number, download?: boolean): Promise { + const apiPath = '/avatars/qr'; + const payload: Payload = {}; + + if (typeof text !== 'undefined') { + payload['text'] = text; + } + + if (typeof size !== 'undefined') { + payload['size'] = size; + } + + if (typeof margin !== 'undefined') { + payload['margin'] = margin; + } + + if (typeof download !== 'undefined') { + payload['download'] = download; + } + + const uri = new URL(this.client.config.endpoint + apiPath); + + return this.client.call('get', uri, { + }, payload); } }; diff --git a/src/services/databases.ts b/src/services/databases.ts index 1ec4dfe1..272d8bba 100644 --- a/src/services/databases.ts +++ b/src/services/databases.ts @@ -204,4 +204,5 @@ export class Databases extends Service { 'content-type': 'application/json', }, payload); } + }; diff --git a/src/services/functions.ts b/src/services/functions.ts index 4f41fe09..b2668c4d 100644 --- a/src/services/functions.ts +++ b/src/services/functions.ts @@ -118,4 +118,5 @@ export class Functions extends Service { return this.client.call('get', uri, { }, payload); } + }; diff --git a/src/services/graphql.ts b/src/services/graphql.ts index a24adaa4..89820038 100644 --- a/src/services/graphql.ts +++ b/src/services/graphql.ts @@ -64,4 +64,5 @@ export class Graphql extends Service { 'content-type': 'application/json', }, payload); } + }; diff --git a/src/services/locale.ts b/src/services/locale.ts index 6498bd98..1937f5f9 100644 --- a/src/services/locale.ts +++ b/src/services/locale.ts @@ -145,4 +145,5 @@ export class Locale extends Service { return this.client.call('get', uri, { }, payload); } + }; diff --git a/src/services/messaging.ts b/src/services/messaging.ts index 6e33b9ab..2c021b01 100644 --- a/src/services/messaging.ts +++ b/src/services/messaging.ts @@ -77,4 +77,5 @@ export class Messaging extends Service { 'content-type': 'application/json', }, payload); } + }; diff --git a/src/services/storage.ts b/src/services/storage.ts index 0df7865e..fff9ce1d 100644 --- a/src/services/storage.ts +++ b/src/services/storage.ts @@ -260,9 +260,9 @@ export class Storage extends Service { * @param {string} fileId * @param {string} token * @throws {AppwriteException} - * @returns {URL} + * @returns {ArrayBuffer} */ - getFileDownload(bucketId: string, fileId: string, token?: string): URL { + getFileDownload(bucketId: string, fileId: string, token?: string): Promise { if (typeof bucketId === 'undefined') { throw new AppwriteException('Missing required parameter: "bucketId"'); } @@ -285,7 +285,8 @@ export class Storage extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return uri; + return this.client.call('get', uri, { + }, payload, 'arrayBuffer'); } /** @@ -310,9 +311,9 @@ export class Storage extends Service { * @param {ImageFormat} output * @param {string} token * @throws {AppwriteException} - * @returns {URL} + * @returns {ArrayBuffer} */ - getFilePreview(bucketId: string, fileId: string, width?: number, height?: number, gravity?: ImageGravity, quality?: number, borderWidth?: number, borderColor?: string, borderRadius?: number, opacity?: number, rotation?: number, background?: string, output?: ImageFormat, token?: string): URL { + getFilePreview(bucketId: string, fileId: string, width?: number, height?: number, gravity?: ImageGravity, quality?: number, borderWidth?: number, borderColor?: string, borderRadius?: number, opacity?: number, rotation?: number, background?: string, output?: ImageFormat, token?: string): Promise { if (typeof bucketId === 'undefined') { throw new AppwriteException('Missing required parameter: "bucketId"'); } @@ -379,7 +380,8 @@ export class Storage extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return uri; + return this.client.call('get', uri, { + }, payload, 'arrayBuffer'); } /** @@ -391,9 +393,9 @@ export class Storage extends Service { * @param {string} fileId * @param {string} token * @throws {AppwriteException} - * @returns {URL} + * @returns {ArrayBuffer} */ - getFileView(bucketId: string, fileId: string, token?: string): URL { + getFileView(bucketId: string, fileId: string, token?: string): Promise { if (typeof bucketId === 'undefined') { throw new AppwriteException('Missing required parameter: "bucketId"'); } @@ -416,6 +418,143 @@ export class Storage extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return uri; + return this.client.call('get', uri, { + }, payload, 'arrayBuffer'); + } + + + /** + * Get a file content by its unique ID. The endpoint response return with a + * 'Content-Disposition: attachment' header that tells the browser to start + * downloading the file to user downloads directory. + * + * @param {string} bucketId + * @param {string} fileId + * @param {string} token + * @throws {AppwriteException} + * @returns ArrayBuffer + + */ + getFileDownloadURL(bucketId: string, fileId: string, token?: string): Promise { + const apiPath = '/storage/buckets/{bucketId}/files/{fileId}/download'.replace('{bucketId}', bucketId).replace('{fileId}', fileId); + const payload: Payload = {}; + + if (typeof token !== 'undefined') { + payload['token'] = token; + } + + const uri = new URL(this.client.config.endpoint + apiPath); + + return this.client.call('get', uri, { + }, payload); + } + + /** + * Get a file preview image. Currently, this method supports preview for image + * files (jpg, png, and gif), other supported formats, like pdf, docs, slides, + * and spreadsheets, will return the file icon image. You can also pass query + * string arguments for cutting and resizing your preview image. Preview is + * supported only for image files smaller than 10MB. + * + * @param {string} bucketId + * @param {string} fileId + * @param {number} width + * @param {number} height + * @param {ImageGravity} gravity + * @param {number} quality + * @param {number} borderWidth + * @param {string} borderColor + * @param {number} borderRadius + * @param {number} opacity + * @param {number} rotation + * @param {string} background + * @param {ImageFormat} output + * @param {string} token + * @throws {AppwriteException} + * @returns ArrayBuffer + + */ + getFilePreviewURL(bucketId: string, fileId: string, width?: number, height?: number, gravity?: ImageGravity, quality?: number, borderWidth?: number, borderColor?: string, borderRadius?: number, opacity?: number, rotation?: number, background?: string, output?: ImageFormat, token?: string): Promise { + const apiPath = '/storage/buckets/{bucketId}/files/{fileId}/preview'.replace('{bucketId}', bucketId).replace('{fileId}', fileId); + const payload: Payload = {}; + + if (typeof width !== 'undefined') { + payload['width'] = width; + } + + if (typeof height !== 'undefined') { + payload['height'] = height; + } + + if (typeof gravity !== 'undefined') { + payload['gravity'] = gravity; + } + + if (typeof quality !== 'undefined') { + payload['quality'] = quality; + } + + if (typeof borderWidth !== 'undefined') { + payload['borderWidth'] = borderWidth; + } + + if (typeof borderColor !== 'undefined') { + payload['borderColor'] = borderColor; + } + + if (typeof borderRadius !== 'undefined') { + payload['borderRadius'] = borderRadius; + } + + if (typeof opacity !== 'undefined') { + payload['opacity'] = opacity; + } + + if (typeof rotation !== 'undefined') { + payload['rotation'] = rotation; + } + + if (typeof background !== 'undefined') { + payload['background'] = background; + } + + if (typeof output !== 'undefined') { + payload['output'] = output; + } + + if (typeof token !== 'undefined') { + payload['token'] = token; + } + + const uri = new URL(this.client.config.endpoint + apiPath); + + return this.client.call('get', uri, { + }, payload); + } + + /** + * Get a file content by its unique ID. This endpoint is similar to the + * download method but returns with no 'Content-Disposition: attachment' + * header. + * + * @param {string} bucketId + * @param {string} fileId + * @param {string} token + * @throws {AppwriteException} + * @returns ArrayBuffer + + */ + getFileViewURL(bucketId: string, fileId: string, token?: string): Promise { + const apiPath = '/storage/buckets/{bucketId}/files/{fileId}/view'.replace('{bucketId}', bucketId).replace('{fileId}', fileId); + const payload: Payload = {}; + + if (typeof token !== 'undefined') { + payload['token'] = token; + } + + const uri = new URL(this.client.config.endpoint + apiPath); + + return this.client.call('get', uri, { + }, payload); } }; diff --git a/src/services/teams.ts b/src/services/teams.ts index 98e459f6..d2a70f98 100644 --- a/src/services/teams.ts +++ b/src/services/teams.ts @@ -455,4 +455,5 @@ export class Teams extends Service { 'content-type': 'application/json', }, payload); } + }; From 9fa0199a10f2768fa392df94db7031e6275200aa Mon Sep 17 00:00:00 2001 From: root Date: Tue, 20 May 2025 11:43:07 +0000 Subject: [PATCH 2/4] fix: return types --- src/services/avatars.ts | 49 ++++++++++++++++++----------------------- src/services/storage.ts | 21 ++++++++---------- 2 files changed, 30 insertions(+), 40 deletions(-) diff --git a/src/services/avatars.ts b/src/services/avatars.ts index 8e2e20a7..f0784ed2 100644 --- a/src/services/avatars.ts +++ b/src/services/avatars.ts @@ -369,10 +369,10 @@ export class Avatars extends Service { * @param {number} height * @param {number} quality * @throws {AppwriteException} - * @returns ArrayBuffer + * @returns {URL} */ - getBrowserURL(code: Browser, width?: number, height?: number, quality?: number): Promise { + getBrowserURL(code: Browser, width?: number, height?: number, quality?: number): URL { const apiPath = '/avatars/browsers/{code}'.replace('{code}', code); const payload: Payload = {}; @@ -390,8 +390,7 @@ export class Avatars extends Service { const uri = new URL(this.client.config.endpoint + apiPath); - return this.client.call('get', uri, { - }, payload); + return uri; } /** @@ -410,10 +409,10 @@ export class Avatars extends Service { * @param {number} height * @param {number} quality * @throws {AppwriteException} - * @returns ArrayBuffer + * @returns {URL} */ - getCreditCardURL(code: CreditCard, width?: number, height?: number, quality?: number): Promise { + getCreditCardURL(code: CreditCard, width?: number, height?: number, quality?: number): URL { const apiPath = '/avatars/credit-cards/{code}'.replace('{code}', code); const payload: Payload = {}; @@ -431,8 +430,7 @@ export class Avatars extends Service { const uri = new URL(this.client.config.endpoint + apiPath); - return this.client.call('get', uri, { - }, payload); + return uri; } /** @@ -443,10 +441,10 @@ export class Avatars extends Service { * * @param {string} url * @throws {AppwriteException} - * @returns ArrayBuffer + * @returns {URL} */ - getFaviconURL(url: string): Promise { + getFaviconURL(url: string): URL { const apiPath = '/avatars/favicon'; const payload: Payload = {}; @@ -456,8 +454,7 @@ export class Avatars extends Service { const uri = new URL(this.client.config.endpoint + apiPath); - return this.client.call('get', uri, { - }, payload); + return uri; } /** @@ -477,10 +474,10 @@ export class Avatars extends Service { * @param {number} height * @param {number} quality * @throws {AppwriteException} - * @returns ArrayBuffer + * @returns {URL} */ - getFlagURL(code: Flag, width?: number, height?: number, quality?: number): Promise { + getFlagURL(code: Flag, width?: number, height?: number, quality?: number): URL { const apiPath = '/avatars/flags/{code}'.replace('{code}', code); const payload: Payload = {}; @@ -498,8 +495,7 @@ export class Avatars extends Service { const uri = new URL(this.client.config.endpoint + apiPath); - return this.client.call('get', uri, { - }, payload); + return uri; } /** @@ -519,10 +515,10 @@ export class Avatars extends Service { * @param {number} width * @param {number} height * @throws {AppwriteException} - * @returns ArrayBuffer + * @returns {URL} */ - getImageURL(url: string, width?: number, height?: number): Promise { + getImageURL(url: string, width?: number, height?: number): URL { const apiPath = '/avatars/image'; const payload: Payload = {}; @@ -540,8 +536,7 @@ export class Avatars extends Service { const uri = new URL(this.client.config.endpoint + apiPath); - return this.client.call('get', uri, { - }, payload); + return uri; } /** @@ -567,10 +562,10 @@ export class Avatars extends Service { * @param {number} height * @param {string} background * @throws {AppwriteException} - * @returns ArrayBuffer + * @returns {URL} */ - getInitialsURL(name?: string, width?: number, height?: number, background?: string): Promise { + getInitialsURL(name?: string, width?: number, height?: number, background?: string): URL { const apiPath = '/avatars/initials'; const payload: Payload = {}; @@ -592,8 +587,7 @@ export class Avatars extends Service { const uri = new URL(this.client.config.endpoint + apiPath); - return this.client.call('get', uri, { - }, payload); + return uri; } /** @@ -606,10 +600,10 @@ export class Avatars extends Service { * @param {number} margin * @param {boolean} download * @throws {AppwriteException} - * @returns ArrayBuffer + * @returns {URL} */ - getQRURL(text: string, size?: number, margin?: number, download?: boolean): Promise { + getQRURL(text: string, size?: number, margin?: number, download?: boolean): URL { const apiPath = '/avatars/qr'; const payload: Payload = {}; @@ -631,7 +625,6 @@ export class Avatars extends Service { const uri = new URL(this.client.config.endpoint + apiPath); - return this.client.call('get', uri, { - }, payload); + return uri; } }; diff --git a/src/services/storage.ts b/src/services/storage.ts index fff9ce1d..77ae2d8d 100644 --- a/src/services/storage.ts +++ b/src/services/storage.ts @@ -432,10 +432,10 @@ export class Storage extends Service { * @param {string} fileId * @param {string} token * @throws {AppwriteException} - * @returns ArrayBuffer + * @returns {URL} */ - getFileDownloadURL(bucketId: string, fileId: string, token?: string): Promise { + getFileDownloadURL(bucketId: string, fileId: string, token?: string): URL { const apiPath = '/storage/buckets/{bucketId}/files/{fileId}/download'.replace('{bucketId}', bucketId).replace('{fileId}', fileId); const payload: Payload = {}; @@ -445,8 +445,7 @@ export class Storage extends Service { const uri = new URL(this.client.config.endpoint + apiPath); - return this.client.call('get', uri, { - }, payload); + return uri; } /** @@ -471,10 +470,10 @@ export class Storage extends Service { * @param {ImageFormat} output * @param {string} token * @throws {AppwriteException} - * @returns ArrayBuffer + * @returns {URL} */ - getFilePreviewURL(bucketId: string, fileId: string, width?: number, height?: number, gravity?: ImageGravity, quality?: number, borderWidth?: number, borderColor?: string, borderRadius?: number, opacity?: number, rotation?: number, background?: string, output?: ImageFormat, token?: string): Promise { + getFilePreviewURL(bucketId: string, fileId: string, width?: number, height?: number, gravity?: ImageGravity, quality?: number, borderWidth?: number, borderColor?: string, borderRadius?: number, opacity?: number, rotation?: number, background?: string, output?: ImageFormat, token?: string): URL { const apiPath = '/storage/buckets/{bucketId}/files/{fileId}/preview'.replace('{bucketId}', bucketId).replace('{fileId}', fileId); const payload: Payload = {}; @@ -528,8 +527,7 @@ export class Storage extends Service { const uri = new URL(this.client.config.endpoint + apiPath); - return this.client.call('get', uri, { - }, payload); + return uri; } /** @@ -541,10 +539,10 @@ export class Storage extends Service { * @param {string} fileId * @param {string} token * @throws {AppwriteException} - * @returns ArrayBuffer + * @returns {URL} */ - getFileViewURL(bucketId: string, fileId: string, token?: string): Promise { + getFileViewURL(bucketId: string, fileId: string, token?: string): URL { const apiPath = '/storage/buckets/{bucketId}/files/{fileId}/view'.replace('{bucketId}', bucketId).replace('{fileId}', fileId); const payload: Payload = {}; @@ -554,7 +552,6 @@ export class Storage extends Service { const uri = new URL(this.client.config.endpoint + apiPath); - return this.client.call('get', uri, { - }, payload); + return uri; } }; From 796d4611a370b81a4c2c367ef4e260929c575ef6 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 21 May 2025 05:14:47 +0000 Subject: [PATCH 3/4] chore: add setDevKey and upsertDocument methods --- docs/examples/databases/create-document.md | 4 +- docs/examples/databases/create-documents.md | 15 + package.json | 2 +- src/client.ts | 6 +- src/services/account.ts | 1 - src/services/avatars.ts | 324 ++------------------ src/services/databases.ts | 39 ++- src/services/functions.ts | 1 - src/services/graphql.ts | 1 - src/services/locale.ts | 1 - src/services/messaging.ts | 1 - src/services/storage.ts | 152 +-------- src/services/teams.ts | 1 - 13 files changed, 87 insertions(+), 461 deletions(-) create mode 100644 docs/examples/databases/create-documents.md diff --git a/docs/examples/databases/create-document.md b/docs/examples/databases/create-document.md index 1b28231e..ec768fcf 100644 --- a/docs/examples/databases/create-document.md +++ b/docs/examples/databases/create-document.md @@ -2,7 +2,9 @@ import { Client, Databases } from "react-native-appwrite"; const client = new Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint - .setProject(''); // Your project ID + .setSession('') // The user session to authenticate with + .setKey('') // + .setJWT(''); // Your secret JSON Web Token const databases = new Databases(client); diff --git a/docs/examples/databases/create-documents.md b/docs/examples/databases/create-documents.md new file mode 100644 index 00000000..08663b6d --- /dev/null +++ b/docs/examples/databases/create-documents.md @@ -0,0 +1,15 @@ +import { Client, Databases } from "react-native-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setKey(''); // + +const databases = new Databases(client); + +const result = await databases.createDocuments( + '', // databaseId + '', // collectionId + [] // documents +); + +console.log(result); diff --git a/package.json b/package.json index 55f72634..690e55c4 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "react-native-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": "0.9.0", + "version": "0.9.1", "license": "BSD-3-Clause", "main": "dist/cjs/sdk.js", "exports": { diff --git a/src/client.ts b/src/client.ts index 5c0799bd..2d41c2b8 100644 --- a/src/client.ts +++ b/src/client.ts @@ -114,7 +114,7 @@ class Client { 'x-sdk-name': 'React Native', 'x-sdk-platform': 'client', 'x-sdk-language': 'reactnative', - 'x-sdk-version': '0.9.0', + 'x-sdk-version': '0.9.1', 'X-Appwrite-Response-Format': '1.7.0', }; @@ -416,7 +416,7 @@ class Client { } } - async call(method: string, url: URL, headers: Headers = {}, params: Payload = {}, responseType = 'json'): Promise { + async call(method: string, url: URL, headers: Headers = {}, params: Payload = {}): Promise { method = method.toUpperCase(); headers = Object.assign({}, this.headers, headers); @@ -469,8 +469,6 @@ class Client { if (response.headers.get('content-type')?.includes('application/json')) { data = await response.json(); - } else if (responseType === 'arrayBuffer') { - data = await response.arrayBuffer(); } else { data = { message: await response.text() diff --git a/src/services/account.ts b/src/services/account.ts index b48f2549..bcd37339 100644 --- a/src/services/account.ts +++ b/src/services/account.ts @@ -1457,5 +1457,4 @@ export class Account extends Service { 'content-type': 'application/json', }, payload); } - }; diff --git a/src/services/avatars.ts b/src/services/avatars.ts index f0784ed2..1d640843 100644 --- a/src/services/avatars.ts +++ b/src/services/avatars.ts @@ -33,9 +33,9 @@ export class Avatars extends Service { * @param {number} height * @param {number} quality * @throws {AppwriteException} - * @returns {ArrayBuffer} + * @returns {URL} */ - getBrowser(code: Browser, width?: number, height?: number, quality?: number): Promise { + getBrowser(code: Browser, width?: number, height?: number, quality?: number): URL { if (typeof code === 'undefined') { throw new AppwriteException('Missing required parameter: "code"'); } @@ -62,8 +62,7 @@ export class Avatars extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return this.client.call('get', uri, { - }, payload, 'arrayBuffer'); + return uri; } /** @@ -82,9 +81,9 @@ export class Avatars extends Service { * @param {number} height * @param {number} quality * @throws {AppwriteException} - * @returns {ArrayBuffer} + * @returns {URL} */ - getCreditCard(code: CreditCard, width?: number, height?: number, quality?: number): Promise { + getCreditCard(code: CreditCard, width?: number, height?: number, quality?: number): URL { if (typeof code === 'undefined') { throw new AppwriteException('Missing required parameter: "code"'); } @@ -111,8 +110,7 @@ export class Avatars extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return this.client.call('get', uri, { - }, payload, 'arrayBuffer'); + return uri; } /** @@ -123,9 +121,9 @@ export class Avatars extends Service { * * @param {string} url * @throws {AppwriteException} - * @returns {ArrayBuffer} + * @returns {URL} */ - getFavicon(url: string): Promise { + getFavicon(url: string): URL { if (typeof url === 'undefined') { throw new AppwriteException('Missing required parameter: "url"'); } @@ -144,8 +142,7 @@ export class Avatars extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return this.client.call('get', uri, { - }, payload, 'arrayBuffer'); + return uri; } /** @@ -165,9 +162,9 @@ export class Avatars extends Service { * @param {number} height * @param {number} quality * @throws {AppwriteException} - * @returns {ArrayBuffer} + * @returns {URL} */ - getFlag(code: Flag, width?: number, height?: number, quality?: number): Promise { + getFlag(code: Flag, width?: number, height?: number, quality?: number): URL { if (typeof code === 'undefined') { throw new AppwriteException('Missing required parameter: "code"'); } @@ -194,8 +191,7 @@ export class Avatars extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return this.client.call('get', uri, { - }, payload, 'arrayBuffer'); + return uri; } /** @@ -215,9 +211,9 @@ export class Avatars extends Service { * @param {number} width * @param {number} height * @throws {AppwriteException} - * @returns {ArrayBuffer} + * @returns {URL} */ - getImage(url: string, width?: number, height?: number): Promise { + getImage(url: string, width?: number, height?: number): URL { if (typeof url === 'undefined') { throw new AppwriteException('Missing required parameter: "url"'); } @@ -244,8 +240,7 @@ export class Avatars extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return this.client.call('get', uri, { - }, payload, 'arrayBuffer'); + return uri; } /** @@ -271,9 +266,9 @@ export class Avatars extends Service { * @param {number} height * @param {string} background * @throws {AppwriteException} - * @returns {ArrayBuffer} + * @returns {URL} */ - getInitials(name?: string, width?: number, height?: number, background?: string): Promise { + getInitials(name?: string, width?: number, height?: number, background?: string): URL { const apiPath = '/avatars/initials'; const payload: Payload = {}; @@ -300,8 +295,7 @@ export class Avatars extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return this.client.call('get', uri, { - }, payload, 'arrayBuffer'); + return uri; } /** @@ -314,9 +308,9 @@ export class Avatars extends Service { * @param {number} margin * @param {boolean} download * @throws {AppwriteException} - * @returns {ArrayBuffer} + * @returns {URL} */ - getQR(text: string, size?: number, margin?: number, download?: boolean): Promise { + getQR(text: string, size?: number, margin?: number, download?: boolean): URL { if (typeof text === 'undefined') { throw new AppwriteException('Missing required parameter: "text"'); } @@ -347,284 +341,6 @@ export class Avatars extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return this.client.call('get', uri, { - }, payload, 'arrayBuffer'); - } - - - /** - * You can use this endpoint to show different browser icons to your users. - * The code argument receives the browser code as it appears in your user [GET - * /account/sessions](https://appwrite.io/docs/references/cloud/client-web/account#getSessions) - * endpoint. Use width, height and quality arguments to change the output - * settings. - * - * 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 100x100px. - * - * @param {Browser} code - * @param {number} width - * @param {number} height - * @param {number} quality - * @throws {AppwriteException} - * @returns {URL} - - */ - getBrowserURL(code: Browser, width?: number, height?: number, quality?: number): URL { - const apiPath = '/avatars/browsers/{code}'.replace('{code}', code); - const payload: Payload = {}; - - if (typeof width !== 'undefined') { - payload['width'] = width; - } - - if (typeof height !== 'undefined') { - payload['height'] = height; - } - - if (typeof quality !== 'undefined') { - payload['quality'] = quality; - } - - const uri = new URL(this.client.config.endpoint + apiPath); - - return uri; - } - - /** - * The credit card endpoint will return you the icon of the credit card - * provider you need. Use width, height and quality arguments to change the - * output settings. - * - * 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 100x100px. - * - * - * @param {CreditCard} code - * @param {number} width - * @param {number} height - * @param {number} quality - * @throws {AppwriteException} - * @returns {URL} - - */ - getCreditCardURL(code: CreditCard, width?: number, height?: number, quality?: number): URL { - const apiPath = '/avatars/credit-cards/{code}'.replace('{code}', code); - const payload: Payload = {}; - - if (typeof width !== 'undefined') { - payload['width'] = width; - } - - if (typeof height !== 'undefined') { - payload['height'] = height; - } - - if (typeof quality !== 'undefined') { - payload['quality'] = quality; - } - - const uri = new URL(this.client.config.endpoint + apiPath); - - return uri; - } - - /** - * 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} - * @returns {URL} - - */ - getFaviconURL(url: string): URL { - const apiPath = '/avatars/favicon'; - const payload: Payload = {}; - - if (typeof url !== 'undefined') { - payload['url'] = url; - } - - const uri = new URL(this.client.config.endpoint + apiPath); - - return uri; - } - - /** - * You can use this endpoint to show different country flags icons to your - * users. The code argument receives the 2 letter country code. Use width, - * height and quality arguments to change the output settings. Country codes - * follow the [ISO 3166-1](https://en.wikipedia.org/wiki/ISO_3166-1) standard. - * - * 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 100x100px. - * - * - * @param {Flag} code - * @param {number} width - * @param {number} height - * @param {number} quality - * @throws {AppwriteException} - * @returns {URL} - - */ - getFlagURL(code: Flag, width?: number, height?: number, quality?: number): URL { - const apiPath = '/avatars/flags/{code}'.replace('{code}', code); - const payload: Payload = {}; - - if (typeof width !== 'undefined') { - payload['width'] = width; - } - - if (typeof height !== 'undefined') { - payload['height'] = height; - } - - if (typeof quality !== 'undefined') { - payload['quality'] = quality; - } - - const uri = new URL(this.client.config.endpoint + apiPath); - - return uri; - } - - /** - * Use this endpoint to fetch a remote image URL and crop it to any image size - * you want. This endpoint is very useful if you need to crop and display - * remote images in your app or in case you want to make sure a 3rd party - * image is properly served using a TLS protocol. - * - * 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 - * @param {number} height - * @throws {AppwriteException} - * @returns {URL} - - */ - getImageURL(url: string, width?: number, height?: number): URL { - const apiPath = '/avatars/image'; - const payload: Payload = {}; - - if (typeof url !== 'undefined') { - payload['url'] = url; - } - - if (typeof width !== 'undefined') { - payload['width'] = width; - } - - if (typeof height !== 'undefined') { - payload['height'] = height; - } - - const uri = new URL(this.client.config.endpoint + apiPath); - - return uri; - } - - /** - * Use this endpoint to show your user initials avatar icon on your website or - * app. By default, this route will try to print your logged-in user name or - * email initials. You can also overwrite the user name if you pass the 'name' - * parameter. If no name is given and no user is logged, an empty avatar will - * be returned. - * - * You can use the color and background params to change the avatar colors. By - * default, a random theme will be selected. The random theme will persist for - * the user's initials when reloading the same theme will always return for - * the same initials. - * - * 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 100x100px. - * - * - * @param {string} name - * @param {number} width - * @param {number} height - * @param {string} background - * @throws {AppwriteException} - * @returns {URL} - - */ - getInitialsURL(name?: string, width?: number, height?: number, background?: string): URL { - const apiPath = '/avatars/initials'; - const payload: Payload = {}; - - if (typeof name !== 'undefined') { - payload['name'] = name; - } - - if (typeof width !== 'undefined') { - payload['width'] = width; - } - - if (typeof height !== 'undefined') { - payload['height'] = height; - } - - if (typeof background !== 'undefined') { - payload['background'] = background; - } - - const uri = new URL(this.client.config.endpoint + apiPath); - - return uri; - } - - /** - * Converts a given plain text to a QR code image. You can use the query - * parameters to change the size and style of the resulting image. - * - * - * @param {string} text - * @param {number} size - * @param {number} margin - * @param {boolean} download - * @throws {AppwriteException} - * @returns {URL} - - */ - getQRURL(text: string, size?: number, margin?: number, download?: boolean): URL { - const apiPath = '/avatars/qr'; - const payload: Payload = {}; - - if (typeof text !== 'undefined') { - payload['text'] = text; - } - - if (typeof size !== 'undefined') { - payload['size'] = size; - } - - if (typeof margin !== 'undefined') { - payload['margin'] = margin; - } - - if (typeof download !== 'undefined') { - payload['download'] = download; - } - - const uri = new URL(this.client.config.endpoint + apiPath); - return uri; } }; diff --git a/src/services/databases.ts b/src/services/databases.ts index 272d8bba..84be0215 100644 --- a/src/services/databases.ts +++ b/src/services/databases.ts @@ -96,6 +96,44 @@ export class Databases extends Service { }, payload); } + /** + * Create new Documents. 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 + * @param {object[]} documents + * @throws {AppwriteException} + * @returns {Promise} + */ + createDocuments(databaseId: string, collectionId: string, documents: object[]): Promise> { + if (typeof databaseId === 'undefined') { + throw new AppwriteException('Missing required parameter: "databaseId"'); + } + + if (typeof collectionId === 'undefined') { + throw new AppwriteException('Missing required parameter: "collectionId"'); + } + + if (typeof documents === 'undefined') { + throw new AppwriteException('Missing required parameter: "documents"'); + } + + const apiPath = '/databases/{databaseId}/collections/{collectionId}/documents'.replace('{databaseId}', databaseId).replace('{collectionId}', collectionId); + const payload: Payload = {}; + + if (typeof documents !== 'undefined') { + payload['documents'] = documents; + } + + const uri = new URL(this.client.config.endpoint + apiPath); + return this.client.call('post', uri, { + 'content-type': 'application/json', + }, payload); + } + /** * Get a document by its unique ID. This endpoint response returns a JSON * object with the document data. @@ -204,5 +242,4 @@ export class Databases extends Service { 'content-type': 'application/json', }, payload); } - }; diff --git a/src/services/functions.ts b/src/services/functions.ts index b2668c4d..4f41fe09 100644 --- a/src/services/functions.ts +++ b/src/services/functions.ts @@ -118,5 +118,4 @@ export class Functions extends Service { return this.client.call('get', uri, { }, payload); } - }; diff --git a/src/services/graphql.ts b/src/services/graphql.ts index 89820038..a24adaa4 100644 --- a/src/services/graphql.ts +++ b/src/services/graphql.ts @@ -64,5 +64,4 @@ export class Graphql extends Service { 'content-type': 'application/json', }, payload); } - }; diff --git a/src/services/locale.ts b/src/services/locale.ts index 1937f5f9..6498bd98 100644 --- a/src/services/locale.ts +++ b/src/services/locale.ts @@ -145,5 +145,4 @@ export class Locale extends Service { return this.client.call('get', uri, { }, payload); } - }; diff --git a/src/services/messaging.ts b/src/services/messaging.ts index 2c021b01..6e33b9ab 100644 --- a/src/services/messaging.ts +++ b/src/services/messaging.ts @@ -77,5 +77,4 @@ export class Messaging extends Service { 'content-type': 'application/json', }, payload); } - }; diff --git a/src/services/storage.ts b/src/services/storage.ts index 77ae2d8d..0df7865e 100644 --- a/src/services/storage.ts +++ b/src/services/storage.ts @@ -260,9 +260,9 @@ export class Storage extends Service { * @param {string} fileId * @param {string} token * @throws {AppwriteException} - * @returns {ArrayBuffer} + * @returns {URL} */ - getFileDownload(bucketId: string, fileId: string, token?: string): Promise { + getFileDownload(bucketId: string, fileId: string, token?: string): URL { if (typeof bucketId === 'undefined') { throw new AppwriteException('Missing required parameter: "bucketId"'); } @@ -285,8 +285,7 @@ export class Storage extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return this.client.call('get', uri, { - }, payload, 'arrayBuffer'); + return uri; } /** @@ -311,9 +310,9 @@ export class Storage extends Service { * @param {ImageFormat} output * @param {string} token * @throws {AppwriteException} - * @returns {ArrayBuffer} + * @returns {URL} */ - getFilePreview(bucketId: string, fileId: string, width?: number, height?: number, gravity?: ImageGravity, quality?: number, borderWidth?: number, borderColor?: string, borderRadius?: number, opacity?: number, rotation?: number, background?: string, output?: ImageFormat, token?: string): Promise { + getFilePreview(bucketId: string, fileId: string, width?: number, height?: number, gravity?: ImageGravity, quality?: number, borderWidth?: number, borderColor?: string, borderRadius?: number, opacity?: number, rotation?: number, background?: string, output?: ImageFormat, token?: string): URL { if (typeof bucketId === 'undefined') { throw new AppwriteException('Missing required parameter: "bucketId"'); } @@ -380,8 +379,7 @@ export class Storage extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return this.client.call('get', uri, { - }, payload, 'arrayBuffer'); + return uri; } /** @@ -393,9 +391,9 @@ export class Storage extends Service { * @param {string} fileId * @param {string} token * @throws {AppwriteException} - * @returns {ArrayBuffer} + * @returns {URL} */ - getFileView(bucketId: string, fileId: string, token?: string): Promise { + getFileView(bucketId: string, fileId: string, token?: string): URL { if (typeof bucketId === 'undefined') { throw new AppwriteException('Missing required parameter: "bucketId"'); } @@ -418,140 +416,6 @@ export class Storage extends Service { for (const [key, value] of Object.entries(Service.flatten(payload))) { uri.searchParams.append(key, value); } - return this.client.call('get', uri, { - }, payload, 'arrayBuffer'); - } - - - /** - * Get a file content by its unique ID. The endpoint response return with a - * 'Content-Disposition: attachment' header that tells the browser to start - * downloading the file to user downloads directory. - * - * @param {string} bucketId - * @param {string} fileId - * @param {string} token - * @throws {AppwriteException} - * @returns {URL} - - */ - getFileDownloadURL(bucketId: string, fileId: string, token?: string): URL { - const apiPath = '/storage/buckets/{bucketId}/files/{fileId}/download'.replace('{bucketId}', bucketId).replace('{fileId}', fileId); - const payload: Payload = {}; - - if (typeof token !== 'undefined') { - payload['token'] = token; - } - - const uri = new URL(this.client.config.endpoint + apiPath); - - return uri; - } - - /** - * Get a file preview image. Currently, this method supports preview for image - * files (jpg, png, and gif), other supported formats, like pdf, docs, slides, - * and spreadsheets, will return the file icon image. You can also pass query - * string arguments for cutting and resizing your preview image. Preview is - * supported only for image files smaller than 10MB. - * - * @param {string} bucketId - * @param {string} fileId - * @param {number} width - * @param {number} height - * @param {ImageGravity} gravity - * @param {number} quality - * @param {number} borderWidth - * @param {string} borderColor - * @param {number} borderRadius - * @param {number} opacity - * @param {number} rotation - * @param {string} background - * @param {ImageFormat} output - * @param {string} token - * @throws {AppwriteException} - * @returns {URL} - - */ - getFilePreviewURL(bucketId: string, fileId: string, width?: number, height?: number, gravity?: ImageGravity, quality?: number, borderWidth?: number, borderColor?: string, borderRadius?: number, opacity?: number, rotation?: number, background?: string, output?: ImageFormat, token?: string): URL { - const apiPath = '/storage/buckets/{bucketId}/files/{fileId}/preview'.replace('{bucketId}', bucketId).replace('{fileId}', fileId); - const payload: Payload = {}; - - if (typeof width !== 'undefined') { - payload['width'] = width; - } - - if (typeof height !== 'undefined') { - payload['height'] = height; - } - - if (typeof gravity !== 'undefined') { - payload['gravity'] = gravity; - } - - if (typeof quality !== 'undefined') { - payload['quality'] = quality; - } - - if (typeof borderWidth !== 'undefined') { - payload['borderWidth'] = borderWidth; - } - - if (typeof borderColor !== 'undefined') { - payload['borderColor'] = borderColor; - } - - if (typeof borderRadius !== 'undefined') { - payload['borderRadius'] = borderRadius; - } - - if (typeof opacity !== 'undefined') { - payload['opacity'] = opacity; - } - - if (typeof rotation !== 'undefined') { - payload['rotation'] = rotation; - } - - if (typeof background !== 'undefined') { - payload['background'] = background; - } - - if (typeof output !== 'undefined') { - payload['output'] = output; - } - - if (typeof token !== 'undefined') { - payload['token'] = token; - } - - const uri = new URL(this.client.config.endpoint + apiPath); - - return uri; - } - - /** - * Get a file content by its unique ID. This endpoint is similar to the - * download method but returns with no 'Content-Disposition: attachment' - * header. - * - * @param {string} bucketId - * @param {string} fileId - * @param {string} token - * @throws {AppwriteException} - * @returns {URL} - - */ - getFileViewURL(bucketId: string, fileId: string, token?: string): URL { - const apiPath = '/storage/buckets/{bucketId}/files/{fileId}/view'.replace('{bucketId}', bucketId).replace('{fileId}', fileId); - const payload: Payload = {}; - - if (typeof token !== 'undefined') { - payload['token'] = token; - } - - const uri = new URL(this.client.config.endpoint + apiPath); - return uri; } }; diff --git a/src/services/teams.ts b/src/services/teams.ts index d2a70f98..98e459f6 100644 --- a/src/services/teams.ts +++ b/src/services/teams.ts @@ -455,5 +455,4 @@ export class Teams extends Service { 'content-type': 'application/json', }, payload); } - }; From f63e97186204ec54ede757a34644f9117f5c4c7f Mon Sep 17 00:00:00 2001 From: root Date: Wed, 21 May 2025 05:16:42 +0000 Subject: [PATCH 4/4] chore: add setDevkey and upsertDocument methods --- ...create-documents.md => upsert-document.md} | 8 +-- src/client.ts | 16 ++++++ src/services/databases.ts | 50 +++++++++++-------- 3 files changed, 51 insertions(+), 23 deletions(-) rename docs/examples/databases/{create-documents.md => upsert-document.md} (60%) diff --git a/docs/examples/databases/create-documents.md b/docs/examples/databases/upsert-document.md similarity index 60% rename from docs/examples/databases/create-documents.md rename to docs/examples/databases/upsert-document.md index 08663b6d..ae423d12 100644 --- a/docs/examples/databases/create-documents.md +++ b/docs/examples/databases/upsert-document.md @@ -2,14 +2,16 @@ import { Client, Databases } from "react-native-appwrite"; const client = new Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint - .setKey(''); // + .setProject(''); // Your project ID const databases = new Databases(client); -const result = await databases.createDocuments( +const result = await databases.upsertDocument( '', // databaseId '', // collectionId - [] // documents + '', // documentId + {}, // data + ["read("any")"] // permissions (optional) ); console.log(result); diff --git a/src/client.ts b/src/client.ts index 2d41c2b8..ccddc76d 100644 --- a/src/client.ts +++ b/src/client.ts @@ -108,6 +108,7 @@ class Client { jwt: '', locale: '', session: '', + devkey: '', platform: '', }; headers: Headers = { @@ -226,6 +227,21 @@ class Client { return this; } + /** + * Set DevKey + * + * Your secret dev API key + * + * @param value string + * + * @return {this} + */ + setDevKey(value: string): this { + this.headers['X-Appwrite-Dev-Key'] = value; + this.config.devkey = value; + return this; + } + private realtime: Realtime = { socket: undefined, diff --git a/src/services/databases.ts b/src/services/databases.ts index 84be0215..e8bb0ab8 100644 --- a/src/services/databases.ts +++ b/src/services/databases.ts @@ -97,18 +97,17 @@ export class Databases extends Service { } /** - * Create new Documents. 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. + * Get a document by its unique ID. This endpoint response returns a JSON + * object with the document data. * * @param {string} databaseId * @param {string} collectionId - * @param {object[]} documents + * @param {string} documentId + * @param {string[]} queries * @throws {AppwriteException} * @returns {Promise} */ - createDocuments(databaseId: string, collectionId: string, documents: object[]): Promise> { + getDocument(databaseId: string, collectionId: string, documentId: string, queries?: string[]): Promise { if (typeof databaseId === 'undefined') { throw new AppwriteException('Missing required parameter: "databaseId"'); } @@ -117,35 +116,37 @@ export class Databases extends Service { throw new AppwriteException('Missing required parameter: "collectionId"'); } - if (typeof documents === 'undefined') { - throw new AppwriteException('Missing required parameter: "documents"'); + if (typeof documentId === 'undefined') { + throw new AppwriteException('Missing required parameter: "documentId"'); } - const apiPath = '/databases/{databaseId}/collections/{collectionId}/documents'.replace('{databaseId}', databaseId).replace('{collectionId}', collectionId); + const apiPath = '/databases/{databaseId}/collections/{collectionId}/documents/{documentId}'.replace('{databaseId}', databaseId).replace('{collectionId}', collectionId).replace('{documentId}', documentId); const payload: Payload = {}; - if (typeof documents !== 'undefined') { - payload['documents'] = documents; + if (typeof queries !== 'undefined') { + payload['queries'] = queries; } const uri = new URL(this.client.config.endpoint + apiPath); - return this.client.call('post', uri, { - 'content-type': 'application/json', + return this.client.call('get', uri, { }, payload); } /** - * Get a document by its unique ID. This endpoint response returns a JSON - * object with the document data. + * Create or update a 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 * @param {string} documentId - * @param {string[]} queries + * @param {object} data + * @param {string[]} permissions * @throws {AppwriteException} * @returns {Promise} */ - getDocument(databaseId: string, collectionId: string, documentId: string, queries?: string[]): Promise { + upsertDocument(databaseId: string, collectionId: string, documentId: string, data: object, permissions?: string[]): Promise { if (typeof databaseId === 'undefined') { throw new AppwriteException('Missing required parameter: "databaseId"'); } @@ -158,15 +159,24 @@ export class Databases extends Service { throw new AppwriteException('Missing required parameter: "documentId"'); } + if (typeof data === 'undefined') { + throw new AppwriteException('Missing required parameter: "data"'); + } + const apiPath = '/databases/{databaseId}/collections/{collectionId}/documents/{documentId}'.replace('{databaseId}', databaseId).replace('{collectionId}', collectionId).replace('{documentId}', documentId); const payload: Payload = {}; - if (typeof queries !== 'undefined') { - payload['queries'] = queries; + if (typeof data !== 'undefined') { + payload['data'] = data; + } + + if (typeof permissions !== 'undefined') { + payload['permissions'] = permissions; } const uri = new URL(this.client.config.endpoint + apiPath); - return this.client.call('get', uri, { + return this.client.call('put', uri, { + 'content-type': 'application/json', }, payload); }