diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d2ca22f..1e670e54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Change Log +## 18.2.0 + +* Added: `Avatars.updatePhoto` and `Avatars.deletePhoto` to upload and remove the current user's profile photo; `updatePhoto` returns the new `Account` model +* Added: `Account` model, the `User` model without `password`, `hash` and `hashOptions` +* Added: `Project.updateOAuth2Webflow`, `OAuthProvider.Webflow`, `ProjectOAuthProviderId.Webflow` and the `OAuth2Webflow` model +* Added: `ProjectKeyScopes.AvatarsWrite` (`avatars.write`) +* Added: optional `total` parameter on `Account.listSessions`, `Console.listOAuth2Providers`, `Console.listOrganizationScopes`, `Console.listProjectScopes`, `Databases.listTransactions`, `DocumentsDB.listTransactions`, `TablesDB.listTransactions`, `VectorsDB.listTransactions`, `Functions.listRuntimes`, `Functions.listSpecifications`, `Locale.listCodes`, `Locale.listContinents`, `Locale.listCountries`, `Locale.listCountriesEU`, `Locale.listCountriesPhones`, `Locale.listCurrencies`, `Locale.listLanguages`, `Notifications.list`, `Sites.listFrameworks`, `Sites.listSpecifications`, `Sites.listTemplates`, `VCS.listNamespaces`, `VCS.listRepositories` and `VCS.listRepositoryBranches` +* Added: optional `current` parameter on `Account.deleteSessions` to choose whether the current session is deleted too +* Added: `channelId` on `Messaging.createPush` and `Messaging.updatePush` +* Added: `UsageEventDimension` values `accept`, `acceptLanguage`, `latitude`, `longitude`, `postalCode`, `protocol`, `queryKeys`, `timeZone` and `weatherCode`, `UsageEventMetric.MessagesFailed`, and `latitude`, `longitude`, `postalCode`, `timeZone` and `weatherCode` on `UsageDataPoint` +* Added: `deno-1.21`, `deno-1.24` and `deno-1.35` are back in the `Runtime` and `BuildRuntime` enums +* Changed: `Push` picks a default client id per user and tab that survives reloads, so tabs no longer take over each other's connection + ## 18.1.0 * Breaking: removed `deno-1.21`, `deno-1.24` and `deno-1.35` from `Runtime` and `BuildRuntime` enums diff --git a/README.md b/README.md index 52a1a4c9..5c484ff2 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![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) -**This SDK targets Appwrite server version 2.3.x as shipped on Appwrite Cloud.** Self-hosted releases can lag behind Cloud — if you run an older self-hosted build, use a matching older SDK from [previous releases](https://github.com/appwrite/sdk-for-console/releases) when APIs differ. +**This SDK targets Appwrite server version latest as shipped on Appwrite Cloud.** Self-hosted releases can lag behind Cloud — if you run an older self-hosted build, use a matching older SDK from [previous releases](https://github.com/appwrite/sdk-for-console/releases) when APIs differ. Appwrite is an open-source backend as a service server that abstracts and simplifies complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Console SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs) @@ -33,7 +33,7 @@ import { Client, Account } from '@appwrite.io/console'; 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 - + ``` ## Getting Started diff --git a/docs/examples/account/create-email-password-session.md b/docs/examples/account/create-email-password-session.md index e962d2a5..bf8caaac 100644 --- a/docs/examples/account/create-email-password-session.md +++ b/docs/examples/account/create-email-password-session.md @@ -10,6 +10,7 @@ const account = new Account(client); const result = await account.createEmailPasswordSession({ email: 'email@example.com', password: 'password', + duration: 60, // optional }); console.log(result); diff --git a/docs/examples/account/delete-sessions.md b/docs/examples/account/delete-sessions.md index b363c935..ced40d6d 100644 --- a/docs/examples/account/delete-sessions.md +++ b/docs/examples/account/delete-sessions.md @@ -7,7 +7,9 @@ const client = new Client() const account = new Account(client); -const result = await account.deleteSessions(); +const result = await account.deleteSessions({ + current: false, // optional +}); console.log(result); ``` diff --git a/docs/examples/account/list-sessions.md b/docs/examples/account/list-sessions.md index 2270ddfd..85fc4021 100644 --- a/docs/examples/account/list-sessions.md +++ b/docs/examples/account/list-sessions.md @@ -7,7 +7,9 @@ const client = new Client() const account = new Account(client); -const result = await account.listSessions(); +const result = await account.listSessions({ + total: false, // optional +}); console.log(result); ``` diff --git a/docs/examples/avatars/delete-photo.md b/docs/examples/avatars/delete-photo.md new file mode 100644 index 00000000..da8cc6e2 --- /dev/null +++ b/docs/examples/avatars/delete-photo.md @@ -0,0 +1,13 @@ +```javascript +import { Client, Avatars } from '@appwrite.io/console'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const avatars = new Avatars(client); + +const result = await avatars.deletePhoto(); + +console.log(result); +``` diff --git a/docs/examples/avatars/get-screenshot.md b/docs/examples/avatars/get-screenshot.md index 0869f542..0d243b0d 100644 --- a/docs/examples/avatars/get-screenshot.md +++ b/docs/examples/avatars/get-screenshot.md @@ -17,8 +17,7 @@ const avatars = new Avatars(client); const result = avatars.getScreenshot({ url: 'https://example.com', headers: { - Authorization: 'Bearer token123', - 'X-Custom-Header': 'value', + 'Accept-Language': 'en-US,en;q=0.9', }, // optional viewportWidth: 1920, // optional viewportHeight: 1080, // optional diff --git a/docs/examples/avatars/update-photo.md b/docs/examples/avatars/update-photo.md new file mode 100644 index 00000000..cc9abe10 --- /dev/null +++ b/docs/examples/avatars/update-photo.md @@ -0,0 +1,15 @@ +```javascript +import { Client, Avatars } from '@appwrite.io/console'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const avatars = new Avatars(client); + +const result = await avatars.updatePhoto({ + file: document.getElementById('uploader').files[0], +}); + +console.log(result); +``` diff --git a/docs/examples/console/list-o-auth-2-providers.md b/docs/examples/console/list-o-auth-2-providers.md index 9270d3bb..305b58fa 100644 --- a/docs/examples/console/list-o-auth-2-providers.md +++ b/docs/examples/console/list-o-auth-2-providers.md @@ -7,7 +7,9 @@ const client = new Client() const xconsole = new Console(client); -const result = await xconsole.listOAuth2Providers(); +const result = await xconsole.listOAuth2Providers({ + total: false, // optional +}); console.log(result); ``` diff --git a/docs/examples/console/list-organization-scopes.md b/docs/examples/console/list-organization-scopes.md index e6c927a0..95570113 100644 --- a/docs/examples/console/list-organization-scopes.md +++ b/docs/examples/console/list-organization-scopes.md @@ -7,7 +7,9 @@ const client = new Client() const xconsole = new Console(client); -const result = await xconsole.listOrganizationScopes(); +const result = await xconsole.listOrganizationScopes({ + total: false, // optional +}); console.log(result); ``` diff --git a/docs/examples/console/list-project-scopes.md b/docs/examples/console/list-project-scopes.md index 6ae75783..1e29f7c2 100644 --- a/docs/examples/console/list-project-scopes.md +++ b/docs/examples/console/list-project-scopes.md @@ -7,7 +7,9 @@ const client = new Client() const xconsole = new Console(client); -const result = await xconsole.listProjectScopes(); +const result = await xconsole.listProjectScopes({ + total: false, // optional +}); console.log(result); ``` diff --git a/docs/examples/databases/list-transactions.md b/docs/examples/databases/list-transactions.md index 37f2fde7..192e7aad 100644 --- a/docs/examples/databases/list-transactions.md +++ b/docs/examples/databases/list-transactions.md @@ -9,6 +9,7 @@ const databases = new Databases(client); const result = await databases.listTransactions({ queries: [], // optional + total: false, // optional }); console.log(result); diff --git a/docs/examples/documentsdb/list-transactions.md b/docs/examples/documentsdb/list-transactions.md index cf97fb49..a0c73911 100644 --- a/docs/examples/documentsdb/list-transactions.md +++ b/docs/examples/documentsdb/list-transactions.md @@ -9,6 +9,7 @@ const documentsDB = new DocumentsDB(client); const result = await documentsDB.listTransactions({ queries: [], // optional + total: false, // optional }); console.log(result); diff --git a/docs/examples/functions/list-runtimes.md b/docs/examples/functions/list-runtimes.md index 634305df..c6321101 100644 --- a/docs/examples/functions/list-runtimes.md +++ b/docs/examples/functions/list-runtimes.md @@ -7,7 +7,9 @@ const client = new Client() const functions = new Functions(client); -const result = await functions.listRuntimes(); +const result = await functions.listRuntimes({ + total: false, // optional +}); console.log(result); ``` diff --git a/docs/examples/functions/list-specifications.md b/docs/examples/functions/list-specifications.md index b67d111c..55b3fdb5 100644 --- a/docs/examples/functions/list-specifications.md +++ b/docs/examples/functions/list-specifications.md @@ -9,6 +9,7 @@ const functions = new Functions(client); const result = await functions.listSpecifications({ type: 'runtimes', // optional + total: false, // optional }); console.log(result); diff --git a/docs/examples/locale/list-codes.md b/docs/examples/locale/list-codes.md index 815fc01a..bfa65d2e 100644 --- a/docs/examples/locale/list-codes.md +++ b/docs/examples/locale/list-codes.md @@ -7,7 +7,9 @@ const client = new Client() const locale = new Locale(client); -const result = await locale.listCodes(); +const result = await locale.listCodes({ + total: false, // optional +}); console.log(result); ``` diff --git a/docs/examples/locale/list-continents.md b/docs/examples/locale/list-continents.md index 89bfc10a..bb416b38 100644 --- a/docs/examples/locale/list-continents.md +++ b/docs/examples/locale/list-continents.md @@ -7,7 +7,9 @@ const client = new Client() const locale = new Locale(client); -const result = await locale.listContinents(); +const result = await locale.listContinents({ + total: false, // optional +}); console.log(result); ``` diff --git a/docs/examples/locale/list-countries-eu.md b/docs/examples/locale/list-countries-eu.md index 0223e047..bb0cff5e 100644 --- a/docs/examples/locale/list-countries-eu.md +++ b/docs/examples/locale/list-countries-eu.md @@ -7,7 +7,9 @@ const client = new Client() const locale = new Locale(client); -const result = await locale.listCountriesEU(); +const result = await locale.listCountriesEU({ + total: false, // optional +}); console.log(result); ``` diff --git a/docs/examples/locale/list-countries-phones.md b/docs/examples/locale/list-countries-phones.md index e172ecf1..ba215338 100644 --- a/docs/examples/locale/list-countries-phones.md +++ b/docs/examples/locale/list-countries-phones.md @@ -7,7 +7,9 @@ const client = new Client() const locale = new Locale(client); -const result = await locale.listCountriesPhones(); +const result = await locale.listCountriesPhones({ + total: false, // optional +}); console.log(result); ``` diff --git a/docs/examples/locale/list-countries.md b/docs/examples/locale/list-countries.md index b40c2c64..d8151b6a 100644 --- a/docs/examples/locale/list-countries.md +++ b/docs/examples/locale/list-countries.md @@ -7,7 +7,9 @@ const client = new Client() const locale = new Locale(client); -const result = await locale.listCountries(); +const result = await locale.listCountries({ + total: false, // optional +}); console.log(result); ``` diff --git a/docs/examples/locale/list-currencies.md b/docs/examples/locale/list-currencies.md index ccdceeea..953ee024 100644 --- a/docs/examples/locale/list-currencies.md +++ b/docs/examples/locale/list-currencies.md @@ -7,7 +7,9 @@ const client = new Client() const locale = new Locale(client); -const result = await locale.listCurrencies(); +const result = await locale.listCurrencies({ + total: false, // optional +}); console.log(result); ``` diff --git a/docs/examples/locale/list-languages.md b/docs/examples/locale/list-languages.md index 26688ff7..e53adfaf 100644 --- a/docs/examples/locale/list-languages.md +++ b/docs/examples/locale/list-languages.md @@ -7,7 +7,9 @@ const client = new Client() const locale = new Locale(client); -const result = await locale.listLanguages(); +const result = await locale.listLanguages({ + total: false, // optional +}); console.log(result); ``` diff --git a/docs/examples/messaging/create-push.md b/docs/examples/messaging/create-push.md index 7235c19d..02dc0465 100644 --- a/docs/examples/messaging/create-push.md +++ b/docs/examples/messaging/create-push.md @@ -27,6 +27,7 @@ const result = await messaging.createPush({ contentAvailable: false, // optional critical: false, // optional priority: MessagePriority.Normal, // optional + channelId: '', // optional }); console.log(result); diff --git a/docs/examples/messaging/update-email.md b/docs/examples/messaging/update-email.md index a043d35e..81cda404 100644 --- a/docs/examples/messaging/update-email.md +++ b/docs/examples/messaging/update-email.md @@ -9,19 +9,19 @@ const messaging = new Messaging(client); const result = await messaging.updateEmail({ messageId: '', + subject: '', // optional + content: '', // optional topics: [], // optional users: [], // optional targets: [], // optional - subject: '', // optional - content: '', // optional - draft: false, // optional - html: false, // optional cc: [], // optional bcc: [], // optional + attachments: [], // optional replyToEmail: 'email@example.com', // optional replyToName: '', // optional + draft: false, // optional + html: false, // optional scheduledAt: '2020-10-15T06:38:00.000+00:00', // optional - attachments: [], // optional }); console.log(result); diff --git a/docs/examples/messaging/update-push.md b/docs/examples/messaging/update-push.md index f7c46bcf..fd95175f 100644 --- a/docs/examples/messaging/update-push.md +++ b/docs/examples/messaging/update-push.md @@ -9,11 +9,11 @@ const messaging = new Messaging(client); const result = await messaging.updatePush({ messageId: '', + title: '', // optional + body: '<BODY>', // optional topics: [], // optional users: [], // optional targets: [], // optional - title: '<TITLE>', // optional - body: '<BODY>', // optional data: {}, // optional action: '<ACTION>', // optional image: '<ID1:ID2>', // optional @@ -27,6 +27,7 @@ const result = await messaging.updatePush({ contentAvailable: false, // optional critical: false, // optional priority: MessagePriority.Normal, // optional + channelId: '<CHANNEL_ID>', // optional }); console.log(result); diff --git a/docs/examples/messaging/update-sms.md b/docs/examples/messaging/update-sms.md index a41f3226..68ec42c7 100644 --- a/docs/examples/messaging/update-sms.md +++ b/docs/examples/messaging/update-sms.md @@ -9,10 +9,10 @@ const messaging = new Messaging(client); const result = await messaging.updateSMS({ messageId: '<MESSAGE_ID>', + content: '<CONTENT>', // optional topics: [], // optional users: [], // optional targets: [], // optional - content: '<CONTENT>', // optional draft: false, // optional scheduledAt: '2020-10-15T06:38:00.000+00:00', // optional }); diff --git a/docs/examples/notifications/list.md b/docs/examples/notifications/list.md index 3c657581..3861cf59 100644 --- a/docs/examples/notifications/list.md +++ b/docs/examples/notifications/list.md @@ -9,6 +9,7 @@ const notifications = new Notifications(client); const result = await notifications.list({ queries: [], // optional + total: false, // optional }); console.log(result); diff --git a/docs/examples/project/update-o-auth-2-webflow.md b/docs/examples/project/update-o-auth-2-webflow.md new file mode 100644 index 00000000..7a70451b --- /dev/null +++ b/docs/examples/project/update-o-auth-2-webflow.md @@ -0,0 +1,17 @@ +```javascript +import { Client, Project } from '@appwrite.io/console'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>'); // Your project ID + +const project = new Project(client); + +const result = await project.updateOAuth2Webflow({ + clientId: '<CLIENT_ID>', // optional + clientSecret: '<CLIENT_SECRET>', // optional + enabled: false, // optional +}); + +console.log(result); +``` diff --git a/docs/examples/sites/list-frameworks.md b/docs/examples/sites/list-frameworks.md index 26d0e532..ec1921b2 100644 --- a/docs/examples/sites/list-frameworks.md +++ b/docs/examples/sites/list-frameworks.md @@ -7,7 +7,9 @@ const client = new Client() const sites = new Sites(client); -const result = await sites.listFrameworks(); +const result = await sites.listFrameworks({ + total: false, // optional +}); console.log(result); ``` diff --git a/docs/examples/sites/list-specifications.md b/docs/examples/sites/list-specifications.md index 1d77721c..a29beb0f 100644 --- a/docs/examples/sites/list-specifications.md +++ b/docs/examples/sites/list-specifications.md @@ -9,6 +9,7 @@ const sites = new Sites(client); const result = await sites.listSpecifications({ type: 'runtimes', // optional + total: false, // optional }); console.log(result); diff --git a/docs/examples/sites/list-templates.md b/docs/examples/sites/list-templates.md index 4832803a..4047cf9f 100644 --- a/docs/examples/sites/list-templates.md +++ b/docs/examples/sites/list-templates.md @@ -17,6 +17,7 @@ const result = await sites.listTemplates({ useCases: [SiteTemplateUseCase.Portfolio], // optional limit: 1, // optional offset: 0, // optional + total: false, // optional }); console.log(result); diff --git a/docs/examples/tablesdb/list-transactions.md b/docs/examples/tablesdb/list-transactions.md index 2d616198..9070e54e 100644 --- a/docs/examples/tablesdb/list-transactions.md +++ b/docs/examples/tablesdb/list-transactions.md @@ -9,6 +9,7 @@ const tablesDB = new TablesDB(client); const result = await tablesDB.listTransactions({ queries: [], // optional + total: false, // optional }); console.log(result); diff --git a/docs/examples/vcs/list-namespaces.md b/docs/examples/vcs/list-namespaces.md index a66ffdd0..758a60ab 100644 --- a/docs/examples/vcs/list-namespaces.md +++ b/docs/examples/vcs/list-namespaces.md @@ -11,6 +11,7 @@ const result = await vcs.listNamespaces({ installationId: '<INSTALLATION_ID>', search: '<SEARCH>', // optional queries: [], // optional + total: false, // optional }); console.log(result); diff --git a/docs/examples/vcs/list-repositories.md b/docs/examples/vcs/list-repositories.md index 1661cd8c..dd5ea19f 100644 --- a/docs/examples/vcs/list-repositories.md +++ b/docs/examples/vcs/list-repositories.md @@ -12,6 +12,7 @@ const result = await vcs.listRepositories({ type: VCSDetectionType.Runtime, search: '<SEARCH>', // optional queries: [], // optional + total: false, // optional }); console.log(result); diff --git a/docs/examples/vcs/list-repository-branches.md b/docs/examples/vcs/list-repository-branches.md index 2efd905b..75cc0f23 100644 --- a/docs/examples/vcs/list-repository-branches.md +++ b/docs/examples/vcs/list-repository-branches.md @@ -12,6 +12,7 @@ const result = await vcs.listRepositoryBranches({ providerRepositoryId: '<PROVIDER_REPOSITORY_ID>', search: '<SEARCH>', // optional queries: [], // optional + total: false, // optional }); console.log(result); diff --git a/docs/examples/vectorsdb/list-transactions.md b/docs/examples/vectorsdb/list-transactions.md index 02da7686..4902f3e2 100644 --- a/docs/examples/vectorsdb/list-transactions.md +++ b/docs/examples/vectorsdb/list-transactions.md @@ -9,6 +9,7 @@ const vectorsDB = new VectorsDB(client); const result = await vectorsDB.listTransactions({ queries: [], // optional + total: false, // optional }); console.log(result); diff --git a/package-lock.json b/package-lock.json index 477cd69e..bc930ed4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@appwrite.io/console", - "version": "18.1.0", + "version": "18.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@appwrite.io/console", - "version": "18.1.0", + "version": "18.2.0", "license": "BSD-3-Clause", "dependencies": { "buffer": "6.0.3", @@ -33,7 +33,7 @@ "node": ">=18.0.0" }, "overrides": { - "brace-expansion": "5.0.9" + "brace-expansion": "5.0.12" } }, "node_modules/@babel/runtime": { @@ -302,6 +302,9 @@ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -528,6 +531,9 @@ "arm" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -542,6 +548,9 @@ "arm" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -556,6 +565,9 @@ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -570,6 +582,9 @@ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -584,6 +599,9 @@ "loong64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -598,6 +616,9 @@ "loong64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -612,6 +633,9 @@ "ppc64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -626,6 +650,9 @@ "ppc64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -640,6 +667,9 @@ "riscv64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -654,6 +684,9 @@ "riscv64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -668,6 +701,9 @@ "s390x" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -682,6 +718,9 @@ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -696,6 +735,9 @@ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -815,18 +857,18 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.2.tgz", - "integrity": "sha512-X1P21scMv4zGKLYqjdGjaKa7COa0RKVYYZZN/NfvLQ1JegxFhdhpZG/Lyn8AXx6CDUavKAd11v6BvfpkDByK8g==", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.3.tgz", + "integrity": "sha512-dsqMQQoeTLqu9wynDD00q573mNzso3IdQOAfHRJqLCcmCFPoGo9A1bDpUcv/9tnKpErQWv9uKeGfl37EIS02Yg==", "license": "MIT", "dependencies": { "undici-types": "~8.9.0" } }, "node_modules/@types/readable-stream": { - "version": "4.0.24", - "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.24.tgz", - "integrity": "sha512-NRvUNC/JFGPJvqdAfEve8oginbM6V08u5NzLWpG8MwA2kTPOLnqk+wpwuPT+mp3aUsxyuT6m2gnrPuHYCruzEg==", + "version": "4.0.25", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.25.tgz", + "integrity": "sha512-7GsxL8Wd5X3jh73/qgW7WCnbBvGSdD8U3E4Jiuus3/8I+PN20DtlkJtwFhr/sImXfDDQ2Z03i/9wNiIF3TVSsw==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -840,9 +882,9 @@ "license": "MIT" }, "node_modules/@types/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.2.tgz", + "integrity": "sha512-67MQl+fpWKVTT1NYdnmo3U4sc/xPo/zQBncVnI74qmQa0z/b+1g6iYqNmGCPbxO+zz2aklb08a0oHfegiVd0/w==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -878,9 +920,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.9.tgz", - "integrity": "sha512-brTTsvFRt5C1gGHtPst/281UjPD5t9fBqbgoMPlVWy11ZLTPfu7HxK4ZYqO9H7o/yC9rSTCI85EaQ4OoY12qYw==", + "version": "7.0.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.10.tgz", + "integrity": "sha512-HpbUakT7xp5miBUywCHf36ZEuAJNklBJDDsGpUIjMzOSmM8ELSfA9Sa/QDPeNeqeoN31u+UTCkL4klCOVvRm4Q==", "dev": true, "license": "MIT", "engines": { @@ -1182,9 +1224,9 @@ } }, "node_modules/brace-expansion": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", - "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz", + "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2709,9 +2751,9 @@ } }, "node_modules/ws": { - "version": "8.21.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz", - "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==", + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.22.0.tgz", + "integrity": "sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg==", "license": "MIT", "engines": { "node": ">=10.0.0" diff --git a/package.json b/package.json index ca1cb878..e12b00e4 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@appwrite.io/console", "homepage": "https://appwrite.io/support", "description": "Appwrite is an open-source self-hosted backend server that abstracts and simplifies complex and repetitive development tasks behind a very simple REST API", - "version": "18.1.0", + "version": "18.2.0", "license": "BSD-3-Clause", "main": "dist/cjs/sdk.js", "exports": { @@ -58,7 +58,7 @@ "typescript-eslint": "8.70.0" }, "overrides": { - "brace-expansion": "5.0.9" + "brace-expansion": "5.0.12" }, "jsdelivr": "dist/iife/sdk.js", "unpkg": "dist/iife/sdk.js" diff --git a/rollup.config.mjs b/rollup.config.mjs index 99cecd12..d75817e7 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -42,6 +42,8 @@ export default [ file: pkg.jsdelivr, name: 'Appwrite', extend: true, + // A script tag has no module loader, so the lazy mqtt.js import is inlined here. + inlineDynamicImports: true, }, ], }, diff --git a/src/client.ts b/src/client.ts index 93cb3972..74051f54 100644 --- a/src/client.ts +++ b/src/client.ts @@ -413,7 +413,7 @@ class Client { 'x-sdk-name': 'Console', 'x-sdk-platform': 'console', 'x-sdk-language': 'web', - 'x-sdk-version': '18.1.0', + 'x-sdk-version': '18.2.0', 'X-Appwrite-Response-Format': '2.3.0', }; @@ -515,7 +515,10 @@ class Client { * * A stable client id for the AppwritePush service. The broker keys its * offline-replay cursor on this id, so pass a stable value to resume replay across - * reloads/restarts. Defaults to a per-connection id when unset. + * reloads/restarts. Defaults, when unset, to one per user and tab: stable across reloads of + * the tab, different in every other tab, and distinct for each connection open at the same + * time, so no two connections take over each other's session. An explicit id shared by + * several tabs or connections makes them do that. * * @param {string} pushClientId * diff --git a/src/enums/build-runtime.ts b/src/enums/build-runtime.ts index 2dfd9c61..01558318 100644 --- a/src/enums/build-runtime.ts +++ b/src/enums/build-runtime.ts @@ -31,6 +31,9 @@ export enum BuildRuntime { Pythonml311 = 'python-ml-3.11', Pythonml312 = 'python-ml-3.12', Pythonml313 = 'python-ml-3.13', + Deno121 = 'deno-1.21', + Deno124 = 'deno-1.24', + Deno135 = 'deno-1.35', Deno140 = 'deno-1.40', Deno146 = 'deno-1.46', Deno20 = 'deno-2.0', diff --git a/src/enums/o-auth-provider.ts b/src/enums/o-auth-provider.ts index 92a95970..3dab5fb3 100644 --- a/src/enums/o-auth-provider.ts +++ b/src/enums/o-auth-provider.ts @@ -41,6 +41,7 @@ export enum OAuthProvider { Tradeshift = 'tradeshift', TradeshiftBox = 'tradeshiftBox', Twitch = 'twitch', + Webflow = 'webflow', Wordpress = 'wordpress', X = 'x', Yahoo = 'yahoo', diff --git a/src/enums/project-key-scopes.ts b/src/enums/project-key-scopes.ts index d7cb41cf..48ab459e 100644 --- a/src/enums/project-key-scopes.ts +++ b/src/enums/project-key-scopes.ts @@ -89,6 +89,7 @@ export enum ProjectKeyScopes { WebhooksWrite = 'webhooks.write', LocaleRead = 'locale.read', AvatarsRead = 'avatars.read', + AvatarsWrite = 'avatars.write', HealthRead = 'health.read', AssistantRead = 'assistant.read', MigrationsRead = 'migrations.read', diff --git a/src/enums/project-o-auth-provider-id.ts b/src/enums/project-o-auth-provider-id.ts index 3ab5db15..ddfc17c3 100644 --- a/src/enums/project-o-auth-provider-id.ts +++ b/src/enums/project-o-auth-provider-id.ts @@ -41,6 +41,7 @@ export enum ProjectOAuthProviderId { Tradeshift = 'tradeshift', TradeshiftBox = 'tradeshiftBox', Twitch = 'twitch', + Webflow = 'webflow', Wordpress = 'wordpress', X = 'x', Yahoo = 'yahoo', diff --git a/src/enums/runtime.ts b/src/enums/runtime.ts index 7bbcbb6f..1f3d4823 100644 --- a/src/enums/runtime.ts +++ b/src/enums/runtime.ts @@ -31,6 +31,9 @@ export enum Runtime { Pythonml311 = 'python-ml-3.11', Pythonml312 = 'python-ml-3.12', Pythonml313 = 'python-ml-3.13', + Deno121 = 'deno-1.21', + Deno124 = 'deno-1.24', + Deno135 = 'deno-1.35', Deno140 = 'deno-1.40', Deno146 = 'deno-1.46', Deno20 = 'deno-2.0', diff --git a/src/enums/usage-event-dimension.ts b/src/enums/usage-event-dimension.ts index 7147c229..ac44c78a 100644 --- a/src/enums/usage-event-dimension.ts +++ b/src/enums/usage-event-dimension.ts @@ -18,6 +18,15 @@ export enum UsageEventDimension { SdkVersion = 'sdkVersion', TeamId = 'teamId', ResourceId = 'resourceId', + Protocol = 'protocol', + QueryKeys = 'queryKeys', + Accept = 'accept', + AcceptLanguage = 'acceptLanguage', + PostalCode = 'postalCode', + Latitude = 'latitude', + Longitude = 'longitude', + TimeZone = 'timeZone', + WeatherCode = 'weatherCode', Isp = 'isp', AutonomousSystemNumber = 'autonomousSystemNumber', AutonomousSystemOrganization = 'autonomousSystemOrganization', diff --git a/src/enums/usage-event-metric.ts b/src/enums/usage-event-metric.ts index e62f1b05..d71732d5 100644 --- a/src/enums/usage-event-metric.ts +++ b/src/enums/usage-event-metric.ts @@ -6,6 +6,7 @@ export enum UsageEventMetric { WebhooksEventsFailed = 'webhooks.events.failed', AuthMethodPhone = 'auth.method.phone', MessagesSent = 'messages.sent', + MessagesFailed = 'messages.failed', MessagesSmsSent = 'messages.sms.sent', Executions = 'executions', ExecutionsCompute = 'executions.compute', diff --git a/src/models.ts b/src/models.ts index a6c959af..eb63642c 100644 --- a/src/models.ts +++ b/src/models.ts @@ -3495,6 +3495,110 @@ export namespace Models { threads: number; }; + /** + * Account + */ + export type Account< + Preferences extends Models.Preferences = Models.DefaultPreferences, + > = { + /** + * User ID. + */ + $id: string; + /** + * User creation date in ISO 8601 format. + */ + $createdAt: string; + /** + * User update date in ISO 8601 format. + */ + $updatedAt: string; + /** + * User name. + */ + name: string; + /** + * User registration date in ISO 8601 format. + */ + registration: string; + /** + * User status. Pass `true` for enabled and `false` for disabled. + */ + status: boolean; + /** + * Labels for the user. + */ + labels: string[]; + /** + * Password update time in ISO 8601 format. + */ + passwordUpdate: string; + /** + * User email address. + */ + email: string; + /** + * User phone number in E.164 format. + */ + phone: string; + /** + * Email verification status. + */ + emailVerification: boolean; + /** + * Canonical form of the user email address. + */ + emailCanonical?: string; + /** + * Whether the user email is from a free email provider. + */ + emailIsFree?: boolean; + /** + * Whether the user email is from a disposable email provider. + */ + emailIsDisposable?: boolean; + /** + * Whether the user email is from a corporate domain. + */ + emailIsCorporate?: boolean; + /** + * Whether the user email is in its canonical form. + */ + emailIsCanonical?: boolean; + /** + * Whether the password was found in a known data breach the last time it was checked. Null when the password has never been checked. + */ + passwordPwned?: boolean; + /** + * Phone verification status. + */ + phoneVerification: boolean; + /** + * Multi factor authentication status. + */ + mfa: boolean; + /** + * User preferences as a key-value object + */ + prefs: Preferences; + /** + * A user-owned message receiver. A single user may have multiple e.g. emails, phones, and a browser. Each target is registered with a single provider. + */ + targets: Target[]; + /** + * Most recent access date in ISO 8601 format. This attribute is only updated again after 24 hours. + */ + accessedAt: string; + /** + * Whether the user can impersonate other users. + */ + impersonator?: boolean; + /** + * ID of the original actor performing the impersonation. Present only when the current request is impersonating another user. Internal audit logs attribute the action to this user, while the impersonated target is recorded only in internal audit payload data. + */ + impersonatorUserId?: string; + }; + /** * Preferences */ @@ -5490,7 +5594,7 @@ export namespace Models { */ authUsername: string; /** - * HTTP basic authentication password. + * HTTP basic authentication password. Write-only: always returned empty. */ authPassword: string; /** @@ -5971,6 +6075,28 @@ export namespace Models { clientSecret: string; }; + /** + * OAuth2Webflow + */ + export type OAuth2Webflow = { + /** + * OAuth2 provider ID. + */ + $id: string; + /** + * OAuth2 provider is active and can be used to create sessions. + */ + enabled: boolean; + /** + * Webflow OAuth2 client ID. + */ + clientId: string; + /** + * Webflow OAuth2 client secret. + */ + clientSecret: string; + }; + /** * OAuth2Twitch */ @@ -6776,6 +6902,7 @@ export namespace Models { | Models.OAuth2Yandex | Models.OAuth2X | Models.OAuth2WordPress + | Models.OAuth2Webflow | Models.OAuth2Twitch | Models.OAuth2Stripe | Models.OAuth2Spotify @@ -7562,6 +7689,26 @@ export namespace Models { * Region/state chain when broken down by `subdivisions`. */ subdivisions?: string; + /** + * Postal code when broken down by `postalCode`. + */ + postalCode?: string; + /** + * Latitude when broken down by `latitude`. + */ + latitude?: string; + /** + * Longitude when broken down by `longitude`. + */ + longitude?: string; + /** + * Time zone when broken down by `timeZone`. + */ + timeZone?: string; + /** + * Weather station code when broken down by `weatherCode`. + */ + weatherCode?: string; /** * Internet service provider when broken down by `isp`. */ diff --git a/src/services/account.ts b/src/services/account.ts index 4b1bb611..b931f045 100644 --- a/src/services/account.ts +++ b/src/services/account.ts @@ -3787,12 +3787,45 @@ export class Account { /** * Get the list of active sessions across different devices for the currently logged in user. * + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.SessionList>} */ - listSessions(): Promise<Models.SessionList> { + listSessions(params?: { total?: boolean }): Promise<Models.SessionList>; + /** + * Get the list of active sessions across different devices for the currently logged in user. + * + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. + * @throws {AppwriteException} + * @returns {Promise<Models.SessionList>} + * @deprecated Use the object parameter style method for a better developer experience. + */ + listSessions(total?: boolean): Promise<Models.SessionList>; + listSessions( + paramsOrFirst?: { total?: boolean } | boolean, + ): Promise<Models.SessionList> { + let params: { total?: boolean }; + + if ( + typeof paramsOrFirst === 'undefined' || + (paramsOrFirst && + typeof paramsOrFirst === 'object' && + !Array.isArray(paramsOrFirst)) + ) { + params = (paramsOrFirst || {}) as { total?: boolean }; + } else { + params = { + total: paramsOrFirst as boolean, + }; + } + + const total = params.total; + const apiPath = '/account/sessions'; const apiPayload: Payload = {}; + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -3804,14 +3837,47 @@ export class Account { } /** - * Delete all sessions from the user account and remove any sessions cookies from the end client. + * Delete all sessions from the user account and remove any sessions cookies from the end client. Pass `current` as false to keep the session making the request and sign out of every other session. * + * @param {boolean} params.current - Delete the current session too. Use false to sign out of every other session while staying signed in on this one. * @throws {AppwriteException} * @returns {Promise<{}>} */ - deleteSessions(): Promise<{}> { + deleteSessions(params?: { current?: boolean }): Promise<{}>; + /** + * Delete all sessions from the user account and remove any sessions cookies from the end client. Pass `current` as false to keep the session making the request and sign out of every other session. + * + * @param {boolean} current - Delete the current session too. Use false to sign out of every other session while staying signed in on this one. + * @throws {AppwriteException} + * @returns {Promise<{}>} + * @deprecated Use the object parameter style method for a better developer experience. + */ + deleteSessions(current?: boolean): Promise<{}>; + deleteSessions( + paramsOrFirst?: { current?: boolean } | boolean, + ): Promise<{}> { + let params: { current?: boolean }; + + if ( + typeof paramsOrFirst === 'undefined' || + (paramsOrFirst && + typeof paramsOrFirst === 'object' && + !Array.isArray(paramsOrFirst)) + ) { + params = (paramsOrFirst || {}) as { current?: boolean }; + } else { + params = { + current: paramsOrFirst as boolean, + }; + } + + const current = params.current; + const apiPath = '/account/sessions'; const apiPayload: Payload = {}; + if (typeof current !== 'undefined') { + apiPayload['current'] = current; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -3844,26 +3910,29 @@ export class Account { } /** - * Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user. + * Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user. Use the optional `duration` parameter to create a shorter session, for example when the user doesn't choose "remember me". It must be at least 60 seconds and cannot exceed the project maximum session length. * * A user is limited to 10 active sessions at a time by default. [Learn more about session limits](https://appwrite.io/docs/authentication-security#limits). * * @param {string} params.email - User email. * @param {string} params.password - User password. Must be at least 8 chars. + * @param {number} params.duration - Session length in seconds. Minimum is 60 seconds, and it cannot exceed the project maximum session length. Defaults to the project maximum session length. * @throws {AppwriteException} * @returns {Promise<Models.Session>} */ createEmailPasswordSession(params: { email: string; password: string; + duration?: number; }): Promise<Models.Session>; /** - * Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user. + * Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user. Use the optional `duration` parameter to create a shorter session, for example when the user doesn't choose "remember me". It must be at least 60 seconds and cannot exceed the project maximum session length. * * A user is limited to 10 active sessions at a time by default. [Learn more about session limits](https://appwrite.io/docs/authentication-security#limits). * * @param {string} email - User email. * @param {string} password - User password. Must be at least 8 chars. + * @param {number} duration - Session length in seconds. Minimum is 60 seconds, and it cannot exceed the project maximum session length. Defaults to the project maximum session length. * @throws {AppwriteException} * @returns {Promise<Models.Session>} * @deprecated Use the object parameter style method for a better developer experience. @@ -3871,12 +3940,14 @@ export class Account { createEmailPasswordSession( email: string, password: string, + duration?: number, ): Promise<Models.Session>; createEmailPasswordSession( - paramsOrFirst: { email: string; password: string } | string, - ...rest: [string?] + paramsOrFirst: + { email: string; password: string; duration?: number } | string, + ...rest: [string?, number?] ): Promise<Models.Session> { - let params: { email: string; password: string }; + let params: { email: string; password: string; duration?: number }; if ( paramsOrFirst && @@ -3886,16 +3957,19 @@ export class Account { params = (paramsOrFirst || {}) as { email: string; password: string; + duration?: number; }; } else { params = { email: paramsOrFirst as string, password: rest[0] as string, + duration: rest[1] as number, }; } const email = params.email; const password = params.password; + const duration = params.duration; if (typeof email === 'undefined') { throw new AppwriteException('Missing required parameter: "email"'); @@ -3913,6 +3987,9 @@ export class Account { if (typeof password !== 'undefined') { apiPayload['password'] = password; } + if (typeof duration !== 'undefined') { + apiPayload['duration'] = duration; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -4171,7 +4248,7 @@ export class Account { * A user is limited to 10 active sessions at a time by default. [Learn more about session limits](https://appwrite.io/docs/authentication-security#limits). * * - * @param {OAuthProvider} params.provider - OAuth2 Provider. Currently, supported providers are: amazon, apple, appwrite, auth0, authentik, autodesk, bitbucket, bitly, box, cloudflare, dailymotion, discord, disqus, dropbox, etsy, facebook, figma, fusionauth, github, gitlab, google, huggingface, kakao, keycloak, kick, linkedin, microsoft, notion, oidc, okta, paypal, paypalSandbox, podio, resend, salesforce, slack, spotify, stripe, tiktok, tradeshift, tradeshiftBox, twitch, wordpress, x, yahoo, yammer, yandex, zoho, zoom. + * @param {OAuthProvider} params.provider - OAuth2 Provider. Currently, supported providers are: amazon, apple, appwrite, auth0, authentik, autodesk, bitbucket, bitly, box, cloudflare, dailymotion, discord, disqus, dropbox, etsy, facebook, figma, fusionauth, github, gitlab, google, huggingface, kakao, keycloak, kick, linkedin, microsoft, notion, oidc, okta, paypal, paypalSandbox, podio, resend, salesforce, slack, spotify, stripe, tiktok, tradeshift, tradeshiftBox, twitch, webflow, wordpress, x, yahoo, yammer, yandex, zoho, zoom. * @param {string} params.success - URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project's platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API. * @param {string} params.failure - URL to redirect back to your app after a failed login attempt. Only URLs from hostnames in your project's platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API. * @param {string[]} params.scopes - A list of custom OAuth2 scopes. Check each provider internal docs for a list of supported scopes. Maximum of 100 scopes are allowed, each 4096 characters long. @@ -4192,7 +4269,7 @@ export class Account { * A user is limited to 10 active sessions at a time by default. [Learn more about session limits](https://appwrite.io/docs/authentication-security#limits). * * - * @param {OAuthProvider} provider - OAuth2 Provider. Currently, supported providers are: amazon, apple, appwrite, auth0, authentik, autodesk, bitbucket, bitly, box, cloudflare, dailymotion, discord, disqus, dropbox, etsy, facebook, figma, fusionauth, github, gitlab, google, huggingface, kakao, keycloak, kick, linkedin, microsoft, notion, oidc, okta, paypal, paypalSandbox, podio, resend, salesforce, slack, spotify, stripe, tiktok, tradeshift, tradeshiftBox, twitch, wordpress, x, yahoo, yammer, yandex, zoho, zoom. + * @param {OAuthProvider} provider - OAuth2 Provider. Currently, supported providers are: amazon, apple, appwrite, auth0, authentik, autodesk, bitbucket, bitly, box, cloudflare, dailymotion, discord, disqus, dropbox, etsy, facebook, figma, fusionauth, github, gitlab, google, huggingface, kakao, keycloak, kick, linkedin, microsoft, notion, oidc, okta, paypal, paypalSandbox, podio, resend, salesforce, slack, spotify, stripe, tiktok, tradeshift, tradeshiftBox, twitch, webflow, wordpress, x, yahoo, yammer, yandex, zoho, zoom. * @param {string} success - URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project's platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API. * @param {string} failure - URL to redirect back to your app after a failed login attempt. Only URLs from hostnames in your project's platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API. * @param {string[]} scopes - A list of custom OAuth2 scopes. Check each provider internal docs for a list of supported scopes. Maximum of 100 scopes are allowed, each 4096 characters long. @@ -5065,7 +5142,7 @@ export class Account { * * A user is limited to 10 active sessions at a time by default. [Learn more about session limits](https://appwrite.io/docs/authentication-security#limits). * - * @param {OAuthProvider} params.provider - OAuth2 Provider. Currently, supported providers are: amazon, apple, appwrite, auth0, authentik, autodesk, bitbucket, bitly, box, cloudflare, dailymotion, discord, disqus, dropbox, etsy, facebook, figma, fusionauth, github, gitlab, google, huggingface, kakao, keycloak, kick, linkedin, microsoft, notion, oidc, okta, paypal, paypalSandbox, podio, resend, salesforce, slack, spotify, stripe, tiktok, tradeshift, tradeshiftBox, twitch, wordpress, x, yahoo, yammer, yandex, zoho, zoom. + * @param {OAuthProvider} params.provider - OAuth2 Provider. Currently, supported providers are: amazon, apple, appwrite, auth0, authentik, autodesk, bitbucket, bitly, box, cloudflare, dailymotion, discord, disqus, dropbox, etsy, facebook, figma, fusionauth, github, gitlab, google, huggingface, kakao, keycloak, kick, linkedin, microsoft, notion, oidc, okta, paypal, paypalSandbox, podio, resend, salesforce, slack, spotify, stripe, tiktok, tradeshift, tradeshiftBox, twitch, webflow, wordpress, x, yahoo, yammer, yandex, zoho, zoom. * @param {string} params.success - URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project's platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API. * @param {string} params.failure - URL to redirect back to your app after a failed login attempt. Only URLs from hostnames in your project's platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API. * @param {string[]} params.scopes - A list of custom OAuth2 scopes. Check each provider internal docs for a list of supported scopes. Maximum of 100 scopes are allowed, each 4096 characters long. @@ -5087,7 +5164,7 @@ export class Account { * * A user is limited to 10 active sessions at a time by default. [Learn more about session limits](https://appwrite.io/docs/authentication-security#limits). * - * @param {OAuthProvider} provider - OAuth2 Provider. Currently, supported providers are: amazon, apple, appwrite, auth0, authentik, autodesk, bitbucket, bitly, box, cloudflare, dailymotion, discord, disqus, dropbox, etsy, facebook, figma, fusionauth, github, gitlab, google, huggingface, kakao, keycloak, kick, linkedin, microsoft, notion, oidc, okta, paypal, paypalSandbox, podio, resend, salesforce, slack, spotify, stripe, tiktok, tradeshift, tradeshiftBox, twitch, wordpress, x, yahoo, yammer, yandex, zoho, zoom. + * @param {OAuthProvider} provider - OAuth2 Provider. Currently, supported providers are: amazon, apple, appwrite, auth0, authentik, autodesk, bitbucket, bitly, box, cloudflare, dailymotion, discord, disqus, dropbox, etsy, facebook, figma, fusionauth, github, gitlab, google, huggingface, kakao, keycloak, kick, linkedin, microsoft, notion, oidc, okta, paypal, paypalSandbox, podio, resend, salesforce, slack, spotify, stripe, tiktok, tradeshift, tradeshiftBox, twitch, webflow, wordpress, x, yahoo, yammer, yandex, zoho, zoom. * @param {string} success - URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project's platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API. * @param {string} failure - URL to redirect back to your app after a failed login attempt. Only URLs from hostnames in your project's platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API. * @param {string[]} scopes - A list of custom OAuth2 scopes. Check each provider internal docs for a list of supported scopes. Maximum of 100 scopes are allowed, each 4096 characters long. diff --git a/src/services/avatars.ts b/src/services/avatars.ts index 60679320..7242deed 100644 --- a/src/services/avatars.ts +++ b/src/services/avatars.ts @@ -1,5 +1,11 @@ import { Service } from '../service'; -import { AppwriteException, Client, type Payload } from '../client'; +import { + AppwriteException, + Client, + type Payload, + UploadProgress, +} from '../client'; +import type { Models } from '../models'; import { Browser } from '../enums/browser'; import { CreditCard } from '../enums/credit-card'; @@ -621,7 +627,7 @@ export class Avatars { } /** - * Returns the best available profile photo for a user. The endpoint tries each source in priority order and returns the first successful result: OAuth2 identity photo, Gravatar, Libravatar, Appwrite Initials, built-in static fallback. + * Returns the best available profile photo for a user. The endpoint tries each source in priority order and returns the first successful result: a custom uploaded photo (see avatars.updatePhoto), OAuth2 identity photo, Gravatar, Libravatar, Appwrite Initials, built-in static fallback. * * Passing `userId` — `current()` for the authenticated user — resolves the photo from everything known about that user: identity photos, email, and name. An explicit `emailHash` or `name` then overrides just that value, and the user's remaining sources stay in the chain. Without `userId`, passing `emailHash` and/or `name` resolves the avatar from those values alone: the hash is looked up on Gravatar and Libravatar, the name is rendered as initials, and the session user stays out of the chain so their own photo never shadows the avatar being asked for. When nothing is passed, the photo resolves for the currently authenticated user. Emails are only ever accepted pre-hashed, so no address ends up in a URL. * @@ -647,7 +653,7 @@ export class Avatars { name?: string; }): string; /** - * Returns the best available profile photo for a user. The endpoint tries each source in priority order and returns the first successful result: OAuth2 identity photo, Gravatar, Libravatar, Appwrite Initials, built-in static fallback. + * Returns the best available profile photo for a user. The endpoint tries each source in priority order and returns the first successful result: a custom uploaded photo (see avatars.updatePhoto), OAuth2 identity photo, Gravatar, Libravatar, Appwrite Initials, built-in static fallback. * * Passing `userId` — `current()` for the authenticated user — resolves the photo from everything known about that user: identity photos, email, and name. An explicit `emailHash` or `name` then overrides just that value, and the user's remaining sources stay in the chain. Without `userId`, passing `emailHash` and/or `name` resolves the avatar from those values alone: the hash is looked up on Gravatar and Libravatar, the name is rendered as initials, and the session user stays out of the chain so their own photo never shadows the avatar being asked for. When nothing is passed, the photo resolves for the currently authenticated user. Emails are only ever accepted pre-hashed, so no address ends up in a URL. * @@ -777,6 +783,108 @@ export class Avatars { return uri.toString(); } + /** + * Update the profile photo of the currently authenticated user. The uploaded image takes priority over every other photo source, including OAuth2 identity photos, Gravatar, and Libravatar. Updating an already customized photo replaces it. The image must be at most 5MB and is sent in a single request. + * + * @param {File} params.file - Binary image file of at most 5MB. Allowed file types are png, jpg, jpeg, and webp. + * @throws {AppwriteException} + * @returns {Promise<Models.Account<Preferences>>} + */ + updatePhoto< + Preferences extends Models.Preferences = Models.DefaultPreferences, + >(params: { + file: File; + onProgress?: (progress: UploadProgress) => void; + }): Promise<Models.Account<Preferences>>; + /** + * Update the profile photo of the currently authenticated user. The uploaded image takes priority over every other photo source, including OAuth2 identity photos, Gravatar, and Libravatar. Updating an already customized photo replaces it. The image must be at most 5MB and is sent in a single request. + * + * @param {File} file - Binary image file of at most 5MB. Allowed file types are png, jpg, jpeg, and webp. + * @throws {AppwriteException} + * @returns {Promise<Models.Account<Preferences>>} + * @deprecated Use the object parameter style method for a better developer experience. + */ + updatePhoto< + Preferences extends Models.Preferences = Models.DefaultPreferences, + >( + file: File, + onProgress?: (progress: UploadProgress) => void, + ): Promise<Models.Account<Preferences>>; + updatePhoto< + Preferences extends Models.Preferences = Models.DefaultPreferences, + >( + paramsOrFirst: + | { file: File; onProgress?: (progress: UploadProgress) => void } + | File, + ...rest: [((progress: UploadProgress) => void)?] + ): Promise<Models.Account<Preferences>> { + let params: { file: File }; + let onProgress: (progress: UploadProgress) => void; + + if ( + paramsOrFirst && + typeof paramsOrFirst === 'object' && + !Array.isArray(paramsOrFirst) && + ('file' in paramsOrFirst || 'onProgress' in paramsOrFirst) + ) { + params = (paramsOrFirst || {}) as { file: File }; + onProgress = paramsOrFirst?.onProgress as ( + progress: UploadProgress, + ) => void; + } else { + params = { + file: paramsOrFirst as File, + }; + onProgress = rest[0] as (progress: UploadProgress) => void; + } + + const file = params.file; + + if (typeof file === 'undefined') { + throw new AppwriteException('Missing required parameter: "file"'); + } + const apiPath = '/avatars/photo'; + const apiPayload: Payload = {}; + if (typeof file !== 'undefined') { + apiPayload['file'] = file; + } + const uri = new URL(this.client.config.endpoint + apiPath); + + const apiHeaders: { [header: string]: string } = { + 'X-Appwrite-Project': this.client.config.project, + 'content-type': 'multipart/form-data', + accept: 'application/json', + }; + + return this.client.chunkedUpload( + 'put', + uri, + apiHeaders, + apiPayload, + onProgress, + ); + } + + /** + * Delete the profile photo of the currently authenticated user and store the built-in static placeholder in its place. The placeholder is the user's photo from then on, so it takes priority over every other photo source — OAuth2 identity photos, Gravatar, Libravatar, and initials — until a new photo is uploaded with avatars.updatePhoto. + * + * @throws {AppwriteException} + * @returns {Promise<{}>} + */ + deletePhoto(): Promise<{}> { + const apiPath = '/avatars/photo'; + const apiPayload: Payload = {}; + const uri = new URL(this.client.config.endpoint + apiPath); + + const apiHeaders: { [header: string]: string } = { + 'X-Appwrite-Project': this.client.config.project, + 'content-type': 'application/json', + accept: 'application/json', + }; + + return this.client.call('delete', uri, apiHeaders, apiPayload); + } + /** * 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. * @@ -894,7 +1002,7 @@ export class Avatars { * When width and height are specified, the image is resized accordingly. If both dimensions are 0, the API provides an image at original size. If dimensions are not specified, the default viewport size is 1280x720px. * * @param {string} params.url - Website URL which you want to capture. - * @param {object} params.headers - HTTP headers to send with the browser request. Defaults to empty. + * @param {object} params.headers - HTTP headers to send with the browser request. Only Accept and Accept-Language are allowed. Defaults to empty. * @param {number} params.viewportWidth - Browser viewport width. Pass an integer between 1 to 1920. Defaults to 1280. * @param {number} params.viewportHeight - Browser viewport height. Pass an integer between 1 to 1080. Defaults to 720. * @param {number} params.scale - Browser scale factor. Pass a number between 0.1 to 3. Defaults to 1. @@ -946,7 +1054,7 @@ export class Avatars { * When width and height are specified, the image is resized accordingly. If both dimensions are 0, the API provides an image at original size. If dimensions are not specified, the default viewport size is 1280x720px. * * @param {string} url - Website URL which you want to capture. - * @param {object} headers - HTTP headers to send with the browser request. Defaults to empty. + * @param {object} headers - HTTP headers to send with the browser request. Only Accept and Accept-Language are allowed. Defaults to empty. * @param {number} viewportWidth - Browser viewport width. Pass an integer between 1 to 1920. Defaults to 1280. * @param {number} viewportHeight - Browser viewport height. Pass an integer between 1 to 1080. Defaults to 720. * @param {number} scale - Browser scale factor. Pass a number between 0.1 to 3. Defaults to 1. diff --git a/src/services/console.ts b/src/services/console.ts index 6da29237..8e28091b 100644 --- a/src/services/console.ts +++ b/src/services/console.ts @@ -210,12 +210,49 @@ export class Console { /** * List all OAuth2 providers supported by the Appwrite server, along with the parameters required to configure each provider. The response excludes mock providers but includes sandbox providers. * + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.ConsoleOAuth2ProviderList>} */ - listOAuth2Providers(): Promise<Models.ConsoleOAuth2ProviderList> { + listOAuth2Providers(params?: { + total?: boolean; + }): Promise<Models.ConsoleOAuth2ProviderList>; + /** + * List all OAuth2 providers supported by the Appwrite server, along with the parameters required to configure each provider. The response excludes mock providers but includes sandbox providers. + * + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. + * @throws {AppwriteException} + * @returns {Promise<Models.ConsoleOAuth2ProviderList>} + * @deprecated Use the object parameter style method for a better developer experience. + */ + listOAuth2Providers( + total?: boolean, + ): Promise<Models.ConsoleOAuth2ProviderList>; + listOAuth2Providers( + paramsOrFirst?: { total?: boolean } | boolean, + ): Promise<Models.ConsoleOAuth2ProviderList> { + let params: { total?: boolean }; + + if ( + typeof paramsOrFirst === 'undefined' || + (paramsOrFirst && + typeof paramsOrFirst === 'object' && + !Array.isArray(paramsOrFirst)) + ) { + params = (paramsOrFirst || {}) as { total?: boolean }; + } else { + params = { + total: paramsOrFirst as boolean, + }; + } + + const total = params.total; + const apiPath = '/console/oauth2-providers'; const apiPayload: Payload = {}; + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -565,12 +602,49 @@ export class Console { /** * List all scopes available for organization API keys, along with a description for each scope. * + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.ConsoleKeyScopeList>} */ - listOrganizationScopes(): Promise<Models.ConsoleKeyScopeList> { + listOrganizationScopes(params?: { + total?: boolean; + }): Promise<Models.ConsoleKeyScopeList>; + /** + * List all scopes available for organization API keys, along with a description for each scope. + * + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. + * @throws {AppwriteException} + * @returns {Promise<Models.ConsoleKeyScopeList>} + * @deprecated Use the object parameter style method for a better developer experience. + */ + listOrganizationScopes( + total?: boolean, + ): Promise<Models.ConsoleKeyScopeList>; + listOrganizationScopes( + paramsOrFirst?: { total?: boolean } | boolean, + ): Promise<Models.ConsoleKeyScopeList> { + let params: { total?: boolean }; + + if ( + typeof paramsOrFirst === 'undefined' || + (paramsOrFirst && + typeof paramsOrFirst === 'object' && + !Array.isArray(paramsOrFirst)) + ) { + params = (paramsOrFirst || {}) as { total?: boolean }; + } else { + params = { + total: paramsOrFirst as boolean, + }; + } + + const total = params.total; + const apiPath = '/console/scopes/organization'; const apiPayload: Payload = {}; + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -584,12 +658,47 @@ export class Console { /** * List all scopes available for project API keys, along with a description for each scope. * + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.ConsoleKeyScopeList>} */ - listProjectScopes(): Promise<Models.ConsoleKeyScopeList> { + listProjectScopes(params?: { + total?: boolean; + }): Promise<Models.ConsoleKeyScopeList>; + /** + * List all scopes available for project API keys, along with a description for each scope. + * + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. + * @throws {AppwriteException} + * @returns {Promise<Models.ConsoleKeyScopeList>} + * @deprecated Use the object parameter style method for a better developer experience. + */ + listProjectScopes(total?: boolean): Promise<Models.ConsoleKeyScopeList>; + listProjectScopes( + paramsOrFirst?: { total?: boolean } | boolean, + ): Promise<Models.ConsoleKeyScopeList> { + let params: { total?: boolean }; + + if ( + typeof paramsOrFirst === 'undefined' || + (paramsOrFirst && + typeof paramsOrFirst === 'object' && + !Array.isArray(paramsOrFirst)) + ) { + params = (paramsOrFirst || {}) as { total?: boolean }; + } else { + params = { + total: paramsOrFirst as boolean, + }; + } + + const total = params.total; + const apiPath = '/console/scopes/project'; const apiPayload: Payload = {}; + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { diff --git a/src/services/databases.ts b/src/services/databases.ts index 59f64676..bb0b50e8 100644 --- a/src/services/databases.ts +++ b/src/services/databases.ts @@ -188,47 +188,62 @@ export class Databases { * List transactions across all databases. * * @param {string[]} params.queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.TransactionList>} * @deprecated This API has been deprecated since 1.8.0. Please use `TablesDB.listTransactions` instead. */ listTransactions(params?: { queries?: string[]; + total?: boolean; }): Promise<Models.TransactionList>; /** * List transactions across all databases. * * @param {string[]} queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.TransactionList>} * @deprecated Use the object parameter style method for a better developer experience. */ - listTransactions(queries?: string[]): Promise<Models.TransactionList>; listTransactions( - paramsOrFirst?: { queries?: string[] } | string[], + queries?: string[], + total?: boolean, + ): Promise<Models.TransactionList>; + listTransactions( + paramsOrFirst?: { queries?: string[]; total?: boolean } | string[], + ...rest: [boolean?] ): Promise<Models.TransactionList> { - let params: { queries?: string[] }; + let params: { queries?: string[]; total?: boolean }; if ( - typeof paramsOrFirst === 'undefined' || + (typeof paramsOrFirst === 'undefined' && rest.length === 0) || (paramsOrFirst && typeof paramsOrFirst === 'object' && !Array.isArray(paramsOrFirst)) ) { - params = (paramsOrFirst || {}) as { queries?: string[] }; + params = (paramsOrFirst || {}) as { + queries?: string[]; + total?: boolean; + }; } else { params = { queries: paramsOrFirst as string[], + total: rest[0] as boolean, }; } const queries = params.queries; + const total = params.total; const apiPath = '/databases/transactions'; const apiPayload: Payload = {}; if (typeof queries !== 'undefined') { apiPayload['queries'] = queries; } + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { diff --git a/src/services/documents-db.ts b/src/services/documents-db.ts index bfae6d27..d3d7b57e 100644 --- a/src/services/documents-db.ts +++ b/src/services/documents-db.ts @@ -234,46 +234,61 @@ export class DocumentsDB { * List transactions across all databases. * * @param {string[]} params.queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.TransactionList>} */ listTransactions(params?: { queries?: string[]; + total?: boolean; }): Promise<Models.TransactionList>; /** * List transactions across all databases. * * @param {string[]} queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.TransactionList>} * @deprecated Use the object parameter style method for a better developer experience. */ - listTransactions(queries?: string[]): Promise<Models.TransactionList>; listTransactions( - paramsOrFirst?: { queries?: string[] } | string[], + queries?: string[], + total?: boolean, + ): Promise<Models.TransactionList>; + listTransactions( + paramsOrFirst?: { queries?: string[]; total?: boolean } | string[], + ...rest: [boolean?] ): Promise<Models.TransactionList> { - let params: { queries?: string[] }; + let params: { queries?: string[]; total?: boolean }; if ( - typeof paramsOrFirst === 'undefined' || + (typeof paramsOrFirst === 'undefined' && rest.length === 0) || (paramsOrFirst && typeof paramsOrFirst === 'object' && !Array.isArray(paramsOrFirst)) ) { - params = (paramsOrFirst || {}) as { queries?: string[] }; + params = (paramsOrFirst || {}) as { + queries?: string[]; + total?: boolean; + }; } else { params = { queries: paramsOrFirst as string[], + total: rest[0] as boolean, }; } const queries = params.queries; + const total = params.total; const apiPath = '/documentsdb/transactions'; const apiPayload: Payload = {}; if (typeof queries !== 'undefined') { apiPayload['queries'] = queries; } + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { diff --git a/src/services/functions.ts b/src/services/functions.ts index c802cf58..d0bb37d9 100644 --- a/src/services/functions.ts +++ b/src/services/functions.ts @@ -456,12 +456,45 @@ export class Functions { /** * Get a list of all runtimes that are currently active on your instance. * + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. + * @throws {AppwriteException} + * @returns {Promise<Models.RuntimeList>} + */ + listRuntimes(params?: { total?: boolean }): Promise<Models.RuntimeList>; + /** + * Get a list of all runtimes that are currently active on your instance. + * + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.RuntimeList>} + * @deprecated Use the object parameter style method for a better developer experience. */ - listRuntimes(): Promise<Models.RuntimeList> { + listRuntimes(total?: boolean): Promise<Models.RuntimeList>; + listRuntimes( + paramsOrFirst?: { total?: boolean } | boolean, + ): Promise<Models.RuntimeList> { + let params: { total?: boolean }; + + if ( + typeof paramsOrFirst === 'undefined' || + (paramsOrFirst && + typeof paramsOrFirst === 'object' && + !Array.isArray(paramsOrFirst)) + ) { + params = (paramsOrFirst || {}) as { total?: boolean }; + } else { + params = { + total: paramsOrFirst as boolean, + }; + } + + const total = params.total; + const apiPath = '/functions/runtimes'; const apiPayload: Payload = {}; + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -476,46 +509,61 @@ export class Functions { * List allowed function specifications for this instance. * * @param {string} params.type - Specification type to list. Can be one of: runtimes, builds. Defaults to runtimes. + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.SpecificationList>} */ listSpecifications(params?: { type?: string; + total?: boolean; }): Promise<Models.SpecificationList>; /** * List allowed function specifications for this instance. * * @param {string} type - Specification type to list. Can be one of: runtimes, builds. Defaults to runtimes. + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.SpecificationList>} * @deprecated Use the object parameter style method for a better developer experience. */ - listSpecifications(type?: string): Promise<Models.SpecificationList>; listSpecifications( - paramsOrFirst?: { type?: string } | string, + type?: string, + total?: boolean, + ): Promise<Models.SpecificationList>; + listSpecifications( + paramsOrFirst?: { type?: string; total?: boolean } | string, + ...rest: [boolean?] ): Promise<Models.SpecificationList> { - let params: { type?: string }; + let params: { type?: string; total?: boolean }; if ( - typeof paramsOrFirst === 'undefined' || + (typeof paramsOrFirst === 'undefined' && rest.length === 0) || (paramsOrFirst && typeof paramsOrFirst === 'object' && !Array.isArray(paramsOrFirst)) ) { - params = (paramsOrFirst || {}) as { type?: string }; + params = (paramsOrFirst || {}) as { + type?: string; + total?: boolean; + }; } else { params = { type: paramsOrFirst as string, + total: rest[0] as boolean, }; } const type = params.type; + const total = params.total; const apiPath = '/functions/specifications'; const apiPayload: Payload = {}; if (typeof type !== 'undefined') { apiPayload['type'] = type; } + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { diff --git a/src/services/locale.ts b/src/services/locale.ts index 85b80390..d7e6a828 100644 --- a/src/services/locale.ts +++ b/src/services/locale.ts @@ -32,12 +32,45 @@ export class Locale { /** * List of all locale codes in [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). * + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.LocaleCodeList>} */ - listCodes(): Promise<Models.LocaleCodeList> { + listCodes(params?: { total?: boolean }): Promise<Models.LocaleCodeList>; + /** + * List of all locale codes in [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). + * + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. + * @throws {AppwriteException} + * @returns {Promise<Models.LocaleCodeList>} + * @deprecated Use the object parameter style method for a better developer experience. + */ + listCodes(total?: boolean): Promise<Models.LocaleCodeList>; + listCodes( + paramsOrFirst?: { total?: boolean } | boolean, + ): Promise<Models.LocaleCodeList> { + let params: { total?: boolean }; + + if ( + typeof paramsOrFirst === 'undefined' || + (paramsOrFirst && + typeof paramsOrFirst === 'object' && + !Array.isArray(paramsOrFirst)) + ) { + params = (paramsOrFirst || {}) as { total?: boolean }; + } else { + params = { + total: paramsOrFirst as boolean, + }; + } + + const total = params.total; + const apiPath = '/locale/codes'; const apiPayload: Payload = {}; + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -51,12 +84,45 @@ export class Locale { /** * List of all continents. You can use the locale header to get the data in a supported language. * + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. + * @throws {AppwriteException} + * @returns {Promise<Models.ContinentList>} + */ + listContinents(params?: { total?: boolean }): Promise<Models.ContinentList>; + /** + * List of all continents. You can use the locale header to get the data in a supported language. + * + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.ContinentList>} + * @deprecated Use the object parameter style method for a better developer experience. */ - listContinents(): Promise<Models.ContinentList> { + listContinents(total?: boolean): Promise<Models.ContinentList>; + listContinents( + paramsOrFirst?: { total?: boolean } | boolean, + ): Promise<Models.ContinentList> { + let params: { total?: boolean }; + + if ( + typeof paramsOrFirst === 'undefined' || + (paramsOrFirst && + typeof paramsOrFirst === 'object' && + !Array.isArray(paramsOrFirst)) + ) { + params = (paramsOrFirst || {}) as { total?: boolean }; + } else { + params = { + total: paramsOrFirst as boolean, + }; + } + + const total = params.total; + const apiPath = '/locale/continents'; const apiPayload: Payload = {}; + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -70,12 +136,45 @@ export class Locale { /** * List of all countries. You can use the locale header to get the data in a supported language. * + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. + * @throws {AppwriteException} + * @returns {Promise<Models.CountryList>} + */ + listCountries(params?: { total?: boolean }): Promise<Models.CountryList>; + /** + * List of all countries. You can use the locale header to get the data in a supported language. + * + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.CountryList>} + * @deprecated Use the object parameter style method for a better developer experience. */ - listCountries(): Promise<Models.CountryList> { + listCountries(total?: boolean): Promise<Models.CountryList>; + listCountries( + paramsOrFirst?: { total?: boolean } | boolean, + ): Promise<Models.CountryList> { + let params: { total?: boolean }; + + if ( + typeof paramsOrFirst === 'undefined' || + (paramsOrFirst && + typeof paramsOrFirst === 'object' && + !Array.isArray(paramsOrFirst)) + ) { + params = (paramsOrFirst || {}) as { total?: boolean }; + } else { + params = { + total: paramsOrFirst as boolean, + }; + } + + const total = params.total; + const apiPath = '/locale/countries'; const apiPayload: Payload = {}; + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -89,12 +188,45 @@ export class Locale { /** * List of all countries that are currently members of the EU. You can use the locale header to get the data in a supported language. * + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.CountryList>} */ - listCountriesEU(): Promise<Models.CountryList> { + listCountriesEU(params?: { total?: boolean }): Promise<Models.CountryList>; + /** + * List of all countries that are currently members of the EU. You can use the locale header to get the data in a supported language. + * + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. + * @throws {AppwriteException} + * @returns {Promise<Models.CountryList>} + * @deprecated Use the object parameter style method for a better developer experience. + */ + listCountriesEU(total?: boolean): Promise<Models.CountryList>; + listCountriesEU( + paramsOrFirst?: { total?: boolean } | boolean, + ): Promise<Models.CountryList> { + let params: { total?: boolean }; + + if ( + typeof paramsOrFirst === 'undefined' || + (paramsOrFirst && + typeof paramsOrFirst === 'object' && + !Array.isArray(paramsOrFirst)) + ) { + params = (paramsOrFirst || {}) as { total?: boolean }; + } else { + params = { + total: paramsOrFirst as boolean, + }; + } + + const total = params.total; + const apiPath = '/locale/countries/eu'; const apiPayload: Payload = {}; + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -108,12 +240,47 @@ export class Locale { /** * List of all countries phone codes. You can use the locale header to get the data in a supported language. * + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. + * @throws {AppwriteException} + * @returns {Promise<Models.PhoneList>} + */ + listCountriesPhones(params?: { + total?: boolean; + }): Promise<Models.PhoneList>; + /** + * List of all countries phone codes. You can use the locale header to get the data in a supported language. + * + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.PhoneList>} + * @deprecated Use the object parameter style method for a better developer experience. */ - listCountriesPhones(): Promise<Models.PhoneList> { + listCountriesPhones(total?: boolean): Promise<Models.PhoneList>; + listCountriesPhones( + paramsOrFirst?: { total?: boolean } | boolean, + ): Promise<Models.PhoneList> { + let params: { total?: boolean }; + + if ( + typeof paramsOrFirst === 'undefined' || + (paramsOrFirst && + typeof paramsOrFirst === 'object' && + !Array.isArray(paramsOrFirst)) + ) { + params = (paramsOrFirst || {}) as { total?: boolean }; + } else { + params = { + total: paramsOrFirst as boolean, + }; + } + + const total = params.total; + const apiPath = '/locale/countries/phones'; const apiPayload: Payload = {}; + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -127,12 +294,45 @@ export class Locale { /** * List of all currencies, including currency symbol, name, plural, and decimal digits for all major and minor currencies. You can use the locale header to get the data in a supported language. * + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.CurrencyList>} */ - listCurrencies(): Promise<Models.CurrencyList> { + listCurrencies(params?: { total?: boolean }): Promise<Models.CurrencyList>; + /** + * List of all currencies, including currency symbol, name, plural, and decimal digits for all major and minor currencies. You can use the locale header to get the data in a supported language. + * + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. + * @throws {AppwriteException} + * @returns {Promise<Models.CurrencyList>} + * @deprecated Use the object parameter style method for a better developer experience. + */ + listCurrencies(total?: boolean): Promise<Models.CurrencyList>; + listCurrencies( + paramsOrFirst?: { total?: boolean } | boolean, + ): Promise<Models.CurrencyList> { + let params: { total?: boolean }; + + if ( + typeof paramsOrFirst === 'undefined' || + (paramsOrFirst && + typeof paramsOrFirst === 'object' && + !Array.isArray(paramsOrFirst)) + ) { + params = (paramsOrFirst || {}) as { total?: boolean }; + } else { + params = { + total: paramsOrFirst as boolean, + }; + } + + const total = params.total; + const apiPath = '/locale/currencies'; const apiPayload: Payload = {}; + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -146,12 +346,45 @@ export class Locale { /** * List of all languages classified by ISO 639-1 including 2-letter code, name in English, and name in the respective language. * + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.LanguageList>} */ - listLanguages(): Promise<Models.LanguageList> { + listLanguages(params?: { total?: boolean }): Promise<Models.LanguageList>; + /** + * List of all languages classified by ISO 639-1 including 2-letter code, name in English, and name in the respective language. + * + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. + * @throws {AppwriteException} + * @returns {Promise<Models.LanguageList>} + * @deprecated Use the object parameter style method for a better developer experience. + */ + listLanguages(total?: boolean): Promise<Models.LanguageList>; + listLanguages( + paramsOrFirst?: { total?: boolean } | boolean, + ): Promise<Models.LanguageList> { + let params: { total?: boolean }; + + if ( + typeof paramsOrFirst === 'undefined' || + (paramsOrFirst && + typeof paramsOrFirst === 'object' && + !Array.isArray(paramsOrFirst)) + ) { + params = (paramsOrFirst || {}) as { total?: boolean }; + } else { + params = { + total: paramsOrFirst as boolean, + }; + } + + const total = params.total; + const apiPath = '/locale/languages'; const apiPayload: Payload = {}; + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { diff --git a/src/services/messaging.ts b/src/services/messaging.ts index dba54d51..56c5812b 100644 --- a/src/services/messaging.ts +++ b/src/services/messaging.ts @@ -13,7 +13,7 @@ export class Messaging { /** * Get a list of all messages from the current Appwrite project. * - * @param {string[]} params.queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: scheduledAt, deliveredAt, deliveredTotal, status, description, providerType + * @param {string[]} params.queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: scheduledAt, deliveredAt, deliveredTotal, status, description, providerType, users, targets * @param {string} params.search - Search term to filter your list results. Max length: 256 chars. * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} @@ -27,7 +27,7 @@ export class Messaging { /** * Get a list of all messages from the current Appwrite project. * - * @param {string[]} queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: scheduledAt, deliveredAt, deliveredTotal, status, description, providerType + * @param {string[]} queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: scheduledAt, deliveredAt, deliveredTotal, status, description, providerType, users, targets * @param {string} search - Search term to filter your list results. Max length: 256 chars. * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} @@ -345,126 +345,126 @@ export class Messaging { * * * @param {string} params.messageId - Message ID. + * @param {string} params.subject - Email Subject. + * @param {string} params.content - Email Content. * @param {string[]} params.topics - List of Topic IDs. * @param {string[]} params.users - List of User IDs. * @param {string[]} params.targets - List of Targets IDs. - * @param {string} params.subject - Email Subject. - * @param {string} params.content - Email Content. - * @param {boolean} params.draft - Is message a draft - * @param {boolean} params.html - Is content of type HTML * @param {string[]} params.cc - Array of target IDs to be added as CC. * @param {string[]} params.bcc - Array of target IDs to be added as BCC. + * @param {string[]} params.attachments - Array of compound ID strings of bucket IDs and file IDs to be attached to the email. They should be formatted as <BUCKET_ID>:<FILE_ID>. * @param {string} params.replyToEmail - Email address to reply to. Pass an empty string to restore the provider or sender default. * @param {string} params.replyToName - Name of the reply to recipient. Pass an empty string to restore the provider or sender default. + * @param {boolean} params.draft - Is message a draft + * @param {boolean} params.html - Is content of type HTML * @param {string} params.scheduledAt - Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future. - * @param {string[]} params.attachments - Array of compound ID strings of bucket IDs and file IDs to be attached to the email. They should be formatted as <BUCKET_ID>:<FILE_ID>. * @throws {AppwriteException} * @returns {Promise<Models.Message>} */ updateEmail(params: { messageId: string; + subject?: string; + content?: string; topics?: string[]; users?: string[]; targets?: string[]; - subject?: string; - content?: string; - draft?: boolean; - html?: boolean; cc?: string[]; bcc?: string[]; + attachments?: string[]; replyToEmail?: string; replyToName?: string; + draft?: boolean; + html?: boolean; scheduledAt?: string; - attachments?: string[]; }): Promise<Models.Message>; /** * Update an email message by its unique ID. This endpoint only works on messages that are in draft status. Messages that are already processing, sent, or failed cannot be updated. * * * @param {string} messageId - Message ID. + * @param {string} subject - Email Subject. + * @param {string} content - Email Content. * @param {string[]} topics - List of Topic IDs. * @param {string[]} users - List of User IDs. * @param {string[]} targets - List of Targets IDs. - * @param {string} subject - Email Subject. - * @param {string} content - Email Content. - * @param {boolean} draft - Is message a draft - * @param {boolean} html - Is content of type HTML * @param {string[]} cc - Array of target IDs to be added as CC. * @param {string[]} bcc - Array of target IDs to be added as BCC. + * @param {string[]} attachments - Array of compound ID strings of bucket IDs and file IDs to be attached to the email. They should be formatted as <BUCKET_ID>:<FILE_ID>. * @param {string} replyToEmail - Email address to reply to. Pass an empty string to restore the provider or sender default. * @param {string} replyToName - Name of the reply to recipient. Pass an empty string to restore the provider or sender default. + * @param {boolean} draft - Is message a draft + * @param {boolean} html - Is content of type HTML * @param {string} scheduledAt - Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future. - * @param {string[]} attachments - Array of compound ID strings of bucket IDs and file IDs to be attached to the email. They should be formatted as <BUCKET_ID>:<FILE_ID>. * @throws {AppwriteException} * @returns {Promise<Models.Message>} * @deprecated Use the object parameter style method for a better developer experience. */ updateEmail( messageId: string, + subject?: string, + content?: string, topics?: string[], users?: string[], targets?: string[], - subject?: string, - content?: string, - draft?: boolean, - html?: boolean, cc?: string[], bcc?: string[], + attachments?: string[], replyToEmail?: string, replyToName?: string, + draft?: boolean, + html?: boolean, scheduledAt?: string, - attachments?: string[], ): Promise<Models.Message>; updateEmail( paramsOrFirst: | { messageId: string; + subject?: string; + content?: string; topics?: string[]; users?: string[]; targets?: string[]; - subject?: string; - content?: string; - draft?: boolean; - html?: boolean; cc?: string[]; bcc?: string[]; + attachments?: string[]; replyToEmail?: string; replyToName?: string; + draft?: boolean; + html?: boolean; scheduledAt?: string; - attachments?: string[]; } | string, ...rest: [ + string?, + string?, + string[]?, string[]?, string[]?, string[]?, - string?, - string?, - boolean?, - boolean?, string[]?, string[]?, string?, string?, + boolean?, + boolean?, string?, - string[]?, ] ): Promise<Models.Message> { let params: { messageId: string; + subject?: string; + content?: string; topics?: string[]; users?: string[]; targets?: string[]; - subject?: string; - content?: string; - draft?: boolean; - html?: boolean; cc?: string[]; bcc?: string[]; + attachments?: string[]; replyToEmail?: string; replyToName?: string; + draft?: boolean; + html?: boolean; scheduledAt?: string; - attachments?: string[]; }; if ( @@ -474,53 +474,53 @@ export class Messaging { ) { params = (paramsOrFirst || {}) as { messageId: string; + subject?: string; + content?: string; topics?: string[]; users?: string[]; targets?: string[]; - subject?: string; - content?: string; - draft?: boolean; - html?: boolean; cc?: string[]; bcc?: string[]; + attachments?: string[]; replyToEmail?: string; replyToName?: string; + draft?: boolean; + html?: boolean; scheduledAt?: string; - attachments?: string[]; }; } else { params = { messageId: paramsOrFirst as string, - topics: rest[0] as string[], - users: rest[1] as string[], - targets: rest[2] as string[], - subject: rest[3] as string, - content: rest[4] as string, - draft: rest[5] as boolean, - html: rest[6] as boolean, - cc: rest[7] as string[], - bcc: rest[8] as string[], - replyToEmail: rest[9] as string, - replyToName: rest[10] as string, - scheduledAt: rest[11] as string, - attachments: rest[12] as string[], + subject: rest[0] as string, + content: rest[1] as string, + topics: rest[2] as string[], + users: rest[3] as string[], + targets: rest[4] as string[], + cc: rest[5] as string[], + bcc: rest[6] as string[], + attachments: rest[7] as string[], + replyToEmail: rest[8] as string, + replyToName: rest[9] as string, + draft: rest[10] as boolean, + html: rest[11] as boolean, + scheduledAt: rest[12] as string, }; } const messageId = params.messageId; + const subject = params.subject; + const content = params.content; const topics = params.topics; const users = params.users; const targets = params.targets; - const subject = params.subject; - const content = params.content; - const draft = params.draft; - const html = params.html; const cc = params.cc; const bcc = params.bcc; + const attachments = params.attachments; const replyToEmail = params.replyToEmail; const replyToName = params.replyToName; + const draft = params.draft; + const html = params.html; const scheduledAt = params.scheduledAt; - const attachments = params.attachments; if (typeof messageId === 'undefined' || messageId === '') { throw new AppwriteException( @@ -532,6 +532,12 @@ export class Messaging { encodeURIComponent(String(messageId)), ); const apiPayload: Payload = {}; + if (typeof subject !== 'undefined') { + apiPayload['subject'] = subject; + } + if (typeof content !== 'undefined') { + apiPayload['content'] = content; + } if (typeof topics !== 'undefined') { apiPayload['topics'] = topics; } @@ -541,36 +547,30 @@ export class Messaging { if (typeof targets !== 'undefined') { apiPayload['targets'] = targets; } - if (typeof subject !== 'undefined') { - apiPayload['subject'] = subject; - } - if (typeof content !== 'undefined') { - apiPayload['content'] = content; - } - if (typeof draft !== 'undefined') { - apiPayload['draft'] = draft; - } - if (typeof html !== 'undefined') { - apiPayload['html'] = html; - } if (typeof cc !== 'undefined') { apiPayload['cc'] = cc; } if (typeof bcc !== 'undefined') { apiPayload['bcc'] = bcc; } + if (typeof attachments !== 'undefined') { + apiPayload['attachments'] = attachments; + } if (typeof replyToEmail !== 'undefined') { apiPayload['replyToEmail'] = replyToEmail; } if (typeof replyToName !== 'undefined') { apiPayload['replyToName'] = replyToName; } + if (typeof draft !== 'undefined') { + apiPayload['draft'] = draft; + } + if (typeof html !== 'undefined') { + apiPayload['html'] = html; + } if (typeof scheduledAt !== 'undefined') { apiPayload['scheduledAt'] = scheduledAt; } - if (typeof attachments !== 'undefined') { - apiPayload['attachments'] = attachments; - } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -604,6 +604,7 @@ export class Messaging { * @param {boolean} params.contentAvailable - If set to true, the notification will be delivered in the background. Available only for iOS Platform. * @param {boolean} params.critical - If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform. * @param {MessagePriority} params.priority - Set the notification priority. "normal" will consider device state and may not deliver notifications immediately. "high" will always attempt to immediately deliver the notification. + * @param {string} params.channelId - ID of the notification channel to deliver the notification on. The app must have already created a channel with this ID, otherwise the channel from the app manifest is used. Available only for Android Platform. * @throws {AppwriteException} * @returns {Promise<Models.Message>} */ @@ -627,6 +628,7 @@ export class Messaging { contentAvailable?: boolean; critical?: boolean; priority?: MessagePriority; + channelId?: string; }): Promise<Models.Message>; /** * Create a new push notification. @@ -650,6 +652,7 @@ export class Messaging { * @param {boolean} contentAvailable - If set to true, the notification will be delivered in the background. Available only for iOS Platform. * @param {boolean} critical - If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform. * @param {MessagePriority} priority - Set the notification priority. "normal" will consider device state and may not deliver notifications immediately. "high" will always attempt to immediately deliver the notification. + * @param {string} channelId - ID of the notification channel to deliver the notification on. The app must have already created a channel with this ID, otherwise the channel from the app manifest is used. Available only for Android Platform. * @throws {AppwriteException} * @returns {Promise<Models.Message>} * @deprecated Use the object parameter style method for a better developer experience. @@ -674,6 +677,7 @@ export class Messaging { contentAvailable?: boolean, critical?: boolean, priority?: MessagePriority, + channelId?: string, ): Promise<Models.Message>; createPush( paramsOrFirst: @@ -697,6 +701,7 @@ export class Messaging { contentAvailable?: boolean; critical?: boolean; priority?: MessagePriority; + channelId?: string; } | string, ...rest: [ @@ -718,6 +723,7 @@ export class Messaging { boolean?, boolean?, MessagePriority?, + string?, ] ): Promise<Models.Message> { let params: { @@ -740,6 +746,7 @@ export class Messaging { contentAvailable?: boolean; critical?: boolean; priority?: MessagePriority; + channelId?: string; }; if ( @@ -767,6 +774,7 @@ export class Messaging { contentAvailable?: boolean; critical?: boolean; priority?: MessagePriority; + channelId?: string; }; } else { params = { @@ -789,6 +797,7 @@ export class Messaging { contentAvailable: rest[15] as boolean, critical: rest[16] as boolean, priority: rest[17] as MessagePriority, + channelId: rest[18] as string, }; } @@ -811,6 +820,7 @@ export class Messaging { const contentAvailable = params.contentAvailable; const critical = params.critical; const priority = params.priority; + const channelId = params.channelId; if (typeof messageId === 'undefined') { throw new AppwriteException( @@ -876,6 +886,9 @@ export class Messaging { if (typeof priority !== 'undefined') { apiPayload['priority'] = priority; } + if (typeof channelId !== 'undefined') { + apiPayload['channelId'] = channelId; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -892,11 +905,11 @@ export class Messaging { * * * @param {string} params.messageId - Message ID. + * @param {string} params.title - Title for push notification. + * @param {string} params.body - Body for push notification. * @param {string[]} params.topics - List of Topic IDs. * @param {string[]} params.users - List of User IDs. * @param {string[]} params.targets - List of Targets IDs. - * @param {string} params.title - Title for push notification. - * @param {string} params.body - Body for push notification. * @param {object} params.data - Additional Data for push notification. * @param {string} params.action - Action for push notification. * @param {string} params.image - Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as <BUCKET_ID>:<FILE_ID>. @@ -910,16 +923,17 @@ export class Messaging { * @param {boolean} params.contentAvailable - If set to true, the notification will be delivered in the background. Available only for iOS Platform. * @param {boolean} params.critical - If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform. * @param {MessagePriority} params.priority - Set the notification priority. "normal" will consider device battery state and may send notifications later. "high" will always attempt to immediately deliver the notification. + * @param {string} params.channelId - ID of the notification channel to deliver the notification on. The app must have already created a channel with this ID, otherwise the channel from the app manifest is used. Pass an empty string to clear it. Available only for Android platforms. * @throws {AppwriteException} * @returns {Promise<Models.Message>} */ updatePush(params: { messageId: string; + title?: string; + body?: string; topics?: string[]; users?: string[]; targets?: string[]; - title?: string; - body?: string; data?: object; action?: string; image?: string; @@ -933,17 +947,18 @@ export class Messaging { contentAvailable?: boolean; critical?: boolean; priority?: MessagePriority; + channelId?: string; }): Promise<Models.Message>; /** * Update a push notification by its unique ID. This endpoint only works on messages that are in draft status. Messages that are already processing, sent, or failed cannot be updated. * * * @param {string} messageId - Message ID. + * @param {string} title - Title for push notification. + * @param {string} body - Body for push notification. * @param {string[]} topics - List of Topic IDs. * @param {string[]} users - List of User IDs. * @param {string[]} targets - List of Targets IDs. - * @param {string} title - Title for push notification. - * @param {string} body - Body for push notification. * @param {object} data - Additional Data for push notification. * @param {string} action - Action for push notification. * @param {string} image - Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as <BUCKET_ID>:<FILE_ID>. @@ -957,17 +972,18 @@ export class Messaging { * @param {boolean} contentAvailable - If set to true, the notification will be delivered in the background. Available only for iOS Platform. * @param {boolean} critical - If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform. * @param {MessagePriority} priority - Set the notification priority. "normal" will consider device battery state and may send notifications later. "high" will always attempt to immediately deliver the notification. + * @param {string} channelId - ID of the notification channel to deliver the notification on. The app must have already created a channel with this ID, otherwise the channel from the app manifest is used. Pass an empty string to clear it. Available only for Android platforms. * @throws {AppwriteException} * @returns {Promise<Models.Message>} * @deprecated Use the object parameter style method for a better developer experience. */ updatePush( messageId: string, + title?: string, + body?: string, topics?: string[], users?: string[], targets?: string[], - title?: string, - body?: string, data?: object, action?: string, image?: string, @@ -981,16 +997,17 @@ export class Messaging { contentAvailable?: boolean, critical?: boolean, priority?: MessagePriority, + channelId?: string, ): Promise<Models.Message>; updatePush( paramsOrFirst: | { messageId: string; + title?: string; + body?: string; topics?: string[]; users?: string[]; targets?: string[]; - title?: string; - body?: string; data?: object; action?: string; image?: string; @@ -1004,14 +1021,15 @@ export class Messaging { contentAvailable?: boolean; critical?: boolean; priority?: MessagePriority; + channelId?: string; } | string, ...rest: [ + string?, + string?, string[]?, string[]?, string[]?, - string?, - string?, object?, string?, string?, @@ -1025,15 +1043,16 @@ export class Messaging { boolean?, boolean?, MessagePriority?, + string?, ] ): Promise<Models.Message> { let params: { messageId: string; + title?: string; + body?: string; topics?: string[]; users?: string[]; targets?: string[]; - title?: string; - body?: string; data?: object; action?: string; image?: string; @@ -1047,6 +1066,7 @@ export class Messaging { contentAvailable?: boolean; critical?: boolean; priority?: MessagePriority; + channelId?: string; }; if ( @@ -1056,11 +1076,11 @@ export class Messaging { ) { params = (paramsOrFirst || {}) as { messageId: string; + title?: string; + body?: string; topics?: string[]; users?: string[]; targets?: string[]; - title?: string; - body?: string; data?: object; action?: string; image?: string; @@ -1074,15 +1094,16 @@ export class Messaging { contentAvailable?: boolean; critical?: boolean; priority?: MessagePriority; + channelId?: string; }; } else { params = { messageId: paramsOrFirst as string, - topics: rest[0] as string[], - users: rest[1] as string[], - targets: rest[2] as string[], - title: rest[3] as string, - body: rest[4] as string, + title: rest[0] as string, + body: rest[1] as string, + topics: rest[2] as string[], + users: rest[3] as string[], + targets: rest[4] as string[], data: rest[5] as object, action: rest[6] as string, image: rest[7] as string, @@ -1096,15 +1117,16 @@ export class Messaging { contentAvailable: rest[15] as boolean, critical: rest[16] as boolean, priority: rest[17] as MessagePriority, + channelId: rest[18] as string, }; } const messageId = params.messageId; + const title = params.title; + const body = params.body; const topics = params.topics; const users = params.users; const targets = params.targets; - const title = params.title; - const body = params.body; const data = params.data; const action = params.action; const image = params.image; @@ -1118,6 +1140,7 @@ export class Messaging { const contentAvailable = params.contentAvailable; const critical = params.critical; const priority = params.priority; + const channelId = params.channelId; if (typeof messageId === 'undefined' || messageId === '') { throw new AppwriteException( @@ -1129,6 +1152,12 @@ export class Messaging { encodeURIComponent(String(messageId)), ); const apiPayload: Payload = {}; + if (typeof title !== 'undefined') { + apiPayload['title'] = title; + } + if (typeof body !== 'undefined') { + apiPayload['body'] = body; + } if (typeof topics !== 'undefined') { apiPayload['topics'] = topics; } @@ -1138,12 +1167,6 @@ export class Messaging { if (typeof targets !== 'undefined') { apiPayload['targets'] = targets; } - if (typeof title !== 'undefined') { - apiPayload['title'] = title; - } - if (typeof body !== 'undefined') { - apiPayload['body'] = body; - } if (typeof data !== 'undefined') { apiPayload['data'] = data; } @@ -1183,6 +1206,9 @@ export class Messaging { if (typeof priority !== 'undefined') { apiPayload['priority'] = priority; } + if (typeof channelId !== 'undefined') { + apiPayload['channelId'] = channelId; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -1494,10 +1520,10 @@ export class Messaging { * * * @param {string} params.messageId - Message ID. + * @param {string} params.content - Email Content. * @param {string[]} params.topics - List of Topic IDs. * @param {string[]} params.users - List of User IDs. * @param {string[]} params.targets - List of Targets IDs. - * @param {string} params.content - Email Content. * @param {boolean} params.draft - Is message a draft * @param {string} params.scheduledAt - Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future. * @throws {AppwriteException} @@ -1506,10 +1532,10 @@ export class Messaging { */ updateSms(params: { messageId: string; + content?: string; topics?: string[]; users?: string[]; targets?: string[]; - content?: string; draft?: boolean; scheduledAt?: string; }): Promise<Models.Message>; @@ -1518,10 +1544,10 @@ export class Messaging { * * * @param {string} messageId - Message ID. + * @param {string} content - Email Content. * @param {string[]} topics - List of Topic IDs. * @param {string[]} users - List of User IDs. * @param {string[]} targets - List of Targets IDs. - * @param {string} content - Email Content. * @param {boolean} draft - Is message a draft * @param {string} scheduledAt - Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future. * @throws {AppwriteException} @@ -1530,10 +1556,10 @@ export class Messaging { */ updateSms( messageId: string, + content?: string, topics?: string[], users?: string[], targets?: string[], - content?: string, draft?: boolean, scheduledAt?: string, ): Promise<Models.Message>; @@ -1541,22 +1567,22 @@ export class Messaging { paramsOrFirst: | { messageId: string; + content?: string; topics?: string[]; users?: string[]; targets?: string[]; - content?: string; draft?: boolean; scheduledAt?: string; } | string, - ...rest: [string[]?, string[]?, string[]?, string?, boolean?, string?] + ...rest: [string?, string[]?, string[]?, string[]?, boolean?, string?] ): Promise<Models.Message> { let params: { messageId: string; + content?: string; topics?: string[]; users?: string[]; targets?: string[]; - content?: string; draft?: boolean; scheduledAt?: string; }; @@ -1568,30 +1594,30 @@ export class Messaging { ) { params = (paramsOrFirst || {}) as { messageId: string; + content?: string; topics?: string[]; users?: string[]; targets?: string[]; - content?: string; draft?: boolean; scheduledAt?: string; }; } else { params = { messageId: paramsOrFirst as string, - topics: rest[0] as string[], - users: rest[1] as string[], - targets: rest[2] as string[], - content: rest[3] as string, + content: rest[0] as string, + topics: rest[1] as string[], + users: rest[2] as string[], + targets: rest[3] as string[], draft: rest[4] as boolean, scheduledAt: rest[5] as string, }; } const messageId = params.messageId; + const content = params.content; const topics = params.topics; const users = params.users; const targets = params.targets; - const content = params.content; const draft = params.draft; const scheduledAt = params.scheduledAt; @@ -1605,6 +1631,9 @@ export class Messaging { encodeURIComponent(String(messageId)), ); const apiPayload: Payload = {}; + if (typeof content !== 'undefined') { + apiPayload['content'] = content; + } if (typeof topics !== 'undefined') { apiPayload['topics'] = topics; } @@ -1614,9 +1643,6 @@ export class Messaging { if (typeof targets !== 'undefined') { apiPayload['targets'] = targets; } - if (typeof content !== 'undefined') { - apiPayload['content'] = content; - } if (typeof draft !== 'undefined') { apiPayload['draft'] = draft; } @@ -1639,10 +1665,10 @@ export class Messaging { * * * @param {string} params.messageId - Message ID. + * @param {string} params.content - Email Content. * @param {string[]} params.topics - List of Topic IDs. * @param {string[]} params.users - List of User IDs. * @param {string[]} params.targets - List of Targets IDs. - * @param {string} params.content - Email Content. * @param {boolean} params.draft - Is message a draft * @param {string} params.scheduledAt - Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future. * @throws {AppwriteException} @@ -1650,10 +1676,10 @@ export class Messaging { */ updateSMS(params: { messageId: string; + content?: string; topics?: string[]; users?: string[]; targets?: string[]; - content?: string; draft?: boolean; scheduledAt?: string; }): Promise<Models.Message>; @@ -1662,10 +1688,10 @@ export class Messaging { * * * @param {string} messageId - Message ID. + * @param {string} content - Email Content. * @param {string[]} topics - List of Topic IDs. * @param {string[]} users - List of User IDs. * @param {string[]} targets - List of Targets IDs. - * @param {string} content - Email Content. * @param {boolean} draft - Is message a draft * @param {string} scheduledAt - Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future. * @throws {AppwriteException} @@ -1674,10 +1700,10 @@ export class Messaging { */ updateSMS( messageId: string, + content?: string, topics?: string[], users?: string[], targets?: string[], - content?: string, draft?: boolean, scheduledAt?: string, ): Promise<Models.Message>; @@ -1685,22 +1711,22 @@ export class Messaging { paramsOrFirst: | { messageId: string; + content?: string; topics?: string[]; users?: string[]; targets?: string[]; - content?: string; draft?: boolean; scheduledAt?: string; } | string, - ...rest: [string[]?, string[]?, string[]?, string?, boolean?, string?] + ...rest: [string?, string[]?, string[]?, string[]?, boolean?, string?] ): Promise<Models.Message> { let params: { messageId: string; + content?: string; topics?: string[]; users?: string[]; targets?: string[]; - content?: string; draft?: boolean; scheduledAt?: string; }; @@ -1712,30 +1738,30 @@ export class Messaging { ) { params = (paramsOrFirst || {}) as { messageId: string; + content?: string; topics?: string[]; users?: string[]; targets?: string[]; - content?: string; draft?: boolean; scheduledAt?: string; }; } else { params = { messageId: paramsOrFirst as string, - topics: rest[0] as string[], - users: rest[1] as string[], - targets: rest[2] as string[], - content: rest[3] as string, + content: rest[0] as string, + topics: rest[1] as string[], + users: rest[2] as string[], + targets: rest[3] as string[], draft: rest[4] as boolean, scheduledAt: rest[5] as string, }; } const messageId = params.messageId; + const content = params.content; const topics = params.topics; const users = params.users; const targets = params.targets; - const content = params.content; const draft = params.draft; const scheduledAt = params.scheduledAt; @@ -1749,6 +1775,9 @@ export class Messaging { encodeURIComponent(String(messageId)), ); const apiPayload: Payload = {}; + if (typeof content !== 'undefined') { + apiPayload['content'] = content; + } if (typeof topics !== 'undefined') { apiPayload['topics'] = topics; } @@ -1758,9 +1787,6 @@ export class Messaging { if (typeof targets !== 'undefined') { apiPayload['targets'] = targets; } - if (typeof content !== 'undefined') { - apiPayload['content'] = content; - } if (typeof draft !== 'undefined') { apiPayload['draft'] = draft; } diff --git a/src/services/notifications.ts b/src/services/notifications.ts index 861d532f..065d0cdc 100644 --- a/src/services/notifications.ts +++ b/src/services/notifications.ts @@ -13,45 +13,59 @@ export class Notifications { * * * @param {string[]} params.queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: read, type, channel, messageId, projectId, resourceType, resourceId, parentResourceType, parentResourceId, firstSeen, lastSeen + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.NotificationList>} */ - list(params?: { queries?: string[] }): Promise<Models.NotificationList>; + list(params?: { + queries?: string[]; + total?: boolean; + }): Promise<Models.NotificationList>; /** * Get the list of notifications for the currently logged in console user. Use queries to filter the results by attributes such as read status, view timestamps, or creation date. * * * @param {string[]} queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: read, type, channel, messageId, projectId, resourceType, resourceId, parentResourceType, parentResourceId, firstSeen, lastSeen + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.NotificationList>} * @deprecated Use the object parameter style method for a better developer experience. */ - list(queries?: string[]): Promise<Models.NotificationList>; + list(queries?: string[], total?: boolean): Promise<Models.NotificationList>; list( - paramsOrFirst?: { queries?: string[] } | string[], + paramsOrFirst?: { queries?: string[]; total?: boolean } | string[], + ...rest: [boolean?] ): Promise<Models.NotificationList> { - let params: { queries?: string[] }; + let params: { queries?: string[]; total?: boolean }; if ( - typeof paramsOrFirst === 'undefined' || + (typeof paramsOrFirst === 'undefined' && rest.length === 0) || (paramsOrFirst && typeof paramsOrFirst === 'object' && !Array.isArray(paramsOrFirst)) ) { - params = (paramsOrFirst || {}) as { queries?: string[] }; + params = (paramsOrFirst || {}) as { + queries?: string[]; + total?: boolean; + }; } else { params = { queries: paramsOrFirst as string[], + total: rest[0] as boolean, }; } const queries = params.queries; + const total = params.total; const apiPath = '/notifications'; const apiPayload: Payload = {}; if (typeof queries !== 'undefined') { apiPayload['queries'] = queries; } + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { diff --git a/src/services/project.ts b/src/services/project.ts index 6d02017e..c787e092 100644 --- a/src/services/project.ts +++ b/src/services/project.ts @@ -5372,6 +5372,92 @@ export class Project { return this.client.call('patch', uri, apiHeaders, apiPayload); } + /** + * Update the project OAuth2 Webflow configuration. + * + * @param {string} params.clientId - 'Client ID' of Webflow OAuth2 app. For example: 8bb20000000000000000000000000000000000000000000000000000000040dd + * @param {string} params.clientSecret - 'Client Secret' of Webflow OAuth2 app. For example: 59bf00000000000000000000000000000000000000000000000000000000fe59 + * @param {boolean} params.enabled - OAuth2 sign-in method status. Set to true to enable new session creation. Setting to true will trigger end-to-end credentials validation, and will throw if the credentials are invalid. + * @throws {AppwriteException} + * @returns {Promise<Models.OAuth2Webflow>} + */ + updateOAuth2Webflow(params?: { + clientId?: string; + clientSecret?: string; + enabled?: boolean; + }): Promise<Models.OAuth2Webflow>; + /** + * Update the project OAuth2 Webflow configuration. + * + * @param {string} clientId - 'Client ID' of Webflow OAuth2 app. For example: 8bb20000000000000000000000000000000000000000000000000000000040dd + * @param {string} clientSecret - 'Client Secret' of Webflow OAuth2 app. For example: 59bf00000000000000000000000000000000000000000000000000000000fe59 + * @param {boolean} enabled - OAuth2 sign-in method status. Set to true to enable new session creation. Setting to true will trigger end-to-end credentials validation, and will throw if the credentials are invalid. + * @throws {AppwriteException} + * @returns {Promise<Models.OAuth2Webflow>} + * @deprecated Use the object parameter style method for a better developer experience. + */ + updateOAuth2Webflow( + clientId?: string, + clientSecret?: string, + enabled?: boolean, + ): Promise<Models.OAuth2Webflow>; + updateOAuth2Webflow( + paramsOrFirst?: + | { clientId?: string; clientSecret?: string; enabled?: boolean } + | string, + ...rest: [string?, boolean?] + ): Promise<Models.OAuth2Webflow> { + let params: { + clientId?: string; + clientSecret?: string; + enabled?: boolean; + }; + + if ( + (typeof paramsOrFirst === 'undefined' && rest.length === 0) || + (paramsOrFirst && + typeof paramsOrFirst === 'object' && + !Array.isArray(paramsOrFirst)) + ) { + params = (paramsOrFirst || {}) as { + clientId?: string; + clientSecret?: string; + enabled?: boolean; + }; + } else { + params = { + clientId: paramsOrFirst as string, + clientSecret: rest[0] as string, + enabled: rest[1] as boolean, + }; + } + + const clientId = params.clientId; + const clientSecret = params.clientSecret; + const enabled = params.enabled; + + const apiPath = '/project/oauth2/webflow'; + const apiPayload: Payload = {}; + if (typeof clientId !== 'undefined') { + apiPayload['clientId'] = clientId; + } + if (typeof clientSecret !== 'undefined') { + apiPayload['clientSecret'] = clientSecret; + } + if (typeof enabled !== 'undefined') { + apiPayload['enabled'] = enabled; + } + const uri = new URL(this.client.config.endpoint + apiPath); + + const apiHeaders: { [header: string]: string } = { + 'X-Appwrite-Project': this.client.config.project, + 'content-type': 'application/json', + accept: 'application/json', + }; + + return this.client.call('patch', uri, apiHeaders, apiPayload); + } + /** * Update the project OAuth2 WordPress configuration. * @@ -5909,7 +5995,7 @@ export class Project { * * @param {ProjectOAuthProviderId} params.providerId - OAuth2 provider key. For example: github, google, apple. * @throws {AppwriteException} - * @returns {Promise<Models.OAuth2Github | Models.OAuth2Discord | Models.OAuth2Figma | Models.OAuth2Dropbox | Models.OAuth2Dailymotion | Models.OAuth2Bitbucket | Models.OAuth2Bitly | Models.OAuth2Box | Models.OAuth2Autodesk | Models.OAuth2Google | Models.OAuth2Zoom | Models.OAuth2Zoho | Models.OAuth2Yandex | Models.OAuth2X | Models.OAuth2WordPress | Models.OAuth2Twitch | Models.OAuth2Stripe | Models.OAuth2Spotify | Models.OAuth2Slack | Models.OAuth2Podio | Models.OAuth2Notion | Models.OAuth2Salesforce | Models.OAuth2Yahoo | Models.OAuth2HuggingFace | Models.OAuth2Resend | Models.OAuth2Cloudflare | Models.OAuth2Linkedin | Models.OAuth2Disqus | Models.OAuth2Amazon | Models.OAuth2Etsy | Models.OAuth2Facebook | Models.OAuth2Tradeshift | Models.OAuth2Paypal | Models.OAuth2Gitlab | Models.OAuth2Authentik | Models.OAuth2Auth0 | Models.OAuth2FusionAuth | Models.OAuth2Keycloak | Models.OAuth2Oidc | Models.OAuth2Apple | Models.OAuth2Okta | Models.OAuth2Kick | Models.OAuth2Microsoft | Models.OAuth2TikTok | Models.OAuth2Kakao>} + * @returns {Promise<Models.OAuth2Github | Models.OAuth2Discord | Models.OAuth2Figma | Models.OAuth2Dropbox | Models.OAuth2Dailymotion | Models.OAuth2Bitbucket | Models.OAuth2Bitly | Models.OAuth2Box | Models.OAuth2Autodesk | Models.OAuth2Google | Models.OAuth2Zoom | Models.OAuth2Zoho | Models.OAuth2Yandex | Models.OAuth2X | Models.OAuth2WordPress | Models.OAuth2Webflow | Models.OAuth2Twitch | Models.OAuth2Stripe | Models.OAuth2Spotify | Models.OAuth2Slack | Models.OAuth2Podio | Models.OAuth2Notion | Models.OAuth2Salesforce | Models.OAuth2Yahoo | Models.OAuth2HuggingFace | Models.OAuth2Resend | Models.OAuth2Cloudflare | Models.OAuth2Linkedin | Models.OAuth2Disqus | Models.OAuth2Amazon | Models.OAuth2Etsy | Models.OAuth2Facebook | Models.OAuth2Tradeshift | Models.OAuth2Paypal | Models.OAuth2Gitlab | Models.OAuth2Authentik | Models.OAuth2Auth0 | Models.OAuth2FusionAuth | Models.OAuth2Keycloak | Models.OAuth2Oidc | Models.OAuth2Apple | Models.OAuth2Okta | Models.OAuth2Kick | Models.OAuth2Microsoft | Models.OAuth2TikTok | Models.OAuth2Kakao>} */ getOAuth2Provider(params: { providerId: ProjectOAuthProviderId; @@ -5929,6 +6015,7 @@ export class Project { | Models.OAuth2Yandex | Models.OAuth2X | Models.OAuth2WordPress + | Models.OAuth2Webflow | Models.OAuth2Twitch | Models.OAuth2Stripe | Models.OAuth2Spotify @@ -5965,7 +6052,7 @@ export class Project { * * @param {ProjectOAuthProviderId} providerId - OAuth2 provider key. For example: github, google, apple. * @throws {AppwriteException} - * @returns {Promise<Models.OAuth2Github | Models.OAuth2Discord | Models.OAuth2Figma | Models.OAuth2Dropbox | Models.OAuth2Dailymotion | Models.OAuth2Bitbucket | Models.OAuth2Bitly | Models.OAuth2Box | Models.OAuth2Autodesk | Models.OAuth2Google | Models.OAuth2Zoom | Models.OAuth2Zoho | Models.OAuth2Yandex | Models.OAuth2X | Models.OAuth2WordPress | Models.OAuth2Twitch | Models.OAuth2Stripe | Models.OAuth2Spotify | Models.OAuth2Slack | Models.OAuth2Podio | Models.OAuth2Notion | Models.OAuth2Salesforce | Models.OAuth2Yahoo | Models.OAuth2HuggingFace | Models.OAuth2Resend | Models.OAuth2Cloudflare | Models.OAuth2Linkedin | Models.OAuth2Disqus | Models.OAuth2Amazon | Models.OAuth2Etsy | Models.OAuth2Facebook | Models.OAuth2Tradeshift | Models.OAuth2Paypal | Models.OAuth2Gitlab | Models.OAuth2Authentik | Models.OAuth2Auth0 | Models.OAuth2FusionAuth | Models.OAuth2Keycloak | Models.OAuth2Oidc | Models.OAuth2Apple | Models.OAuth2Okta | Models.OAuth2Kick | Models.OAuth2Microsoft | Models.OAuth2TikTok | Models.OAuth2Kakao>} + * @returns {Promise<Models.OAuth2Github | Models.OAuth2Discord | Models.OAuth2Figma | Models.OAuth2Dropbox | Models.OAuth2Dailymotion | Models.OAuth2Bitbucket | Models.OAuth2Bitly | Models.OAuth2Box | Models.OAuth2Autodesk | Models.OAuth2Google | Models.OAuth2Zoom | Models.OAuth2Zoho | Models.OAuth2Yandex | Models.OAuth2X | Models.OAuth2WordPress | Models.OAuth2Webflow | Models.OAuth2Twitch | Models.OAuth2Stripe | Models.OAuth2Spotify | Models.OAuth2Slack | Models.OAuth2Podio | Models.OAuth2Notion | Models.OAuth2Salesforce | Models.OAuth2Yahoo | Models.OAuth2HuggingFace | Models.OAuth2Resend | Models.OAuth2Cloudflare | Models.OAuth2Linkedin | Models.OAuth2Disqus | Models.OAuth2Amazon | Models.OAuth2Etsy | Models.OAuth2Facebook | Models.OAuth2Tradeshift | Models.OAuth2Paypal | Models.OAuth2Gitlab | Models.OAuth2Authentik | Models.OAuth2Auth0 | Models.OAuth2FusionAuth | Models.OAuth2Keycloak | Models.OAuth2Oidc | Models.OAuth2Apple | Models.OAuth2Okta | Models.OAuth2Kick | Models.OAuth2Microsoft | Models.OAuth2TikTok | Models.OAuth2Kakao>} * @deprecated Use the object parameter style method for a better developer experience. */ getOAuth2Provider( @@ -5986,6 +6073,7 @@ export class Project { | Models.OAuth2Yandex | Models.OAuth2X | Models.OAuth2WordPress + | Models.OAuth2Webflow | Models.OAuth2Twitch | Models.OAuth2Stripe | Models.OAuth2Spotify @@ -6036,6 +6124,7 @@ export class Project { | Models.OAuth2Yandex | Models.OAuth2X | Models.OAuth2WordPress + | Models.OAuth2Webflow | Models.OAuth2Twitch | Models.OAuth2Stripe | Models.OAuth2Spotify diff --git a/src/services/proxy.ts b/src/services/proxy.ts index bd63c43a..917167c5 100644 --- a/src/services/proxy.ts +++ b/src/services/proxy.ts @@ -16,6 +16,8 @@ export class Proxy { * * Depending on type, the invalidation purges a single cache tag, a single URL path, or all cached content for the domain. * + * Domains that route to a function do not support cache invalidation. + * * @param {string} params.domain - Domain name. * @param {InvalidationType} params.type - Type of reference passed. Allowed values are: tag, path, all * @param {string} params.reference - Reference to invalidate. Depending on type this can be: cache tag name (up to 128 characters), URL path (up to 2048 characters). Not required when type is all. @@ -32,6 +34,8 @@ export class Proxy { * * Depending on type, the invalidation purges a single cache tag, a single URL path, or all cached content for the domain. * + * Domains that route to a function do not support cache invalidation. + * * @param {string} domain - Domain name. * @param {InvalidationType} type - Type of reference passed. Allowed values are: tag, path, all * @param {string} reference - Reference to invalidate. Depending on type this can be: cache tag name (up to 128 characters), URL path (up to 2048 characters). Not required when type is all. diff --git a/src/services/push.ts b/src/services/push.ts index 2d197c90..7037936b 100644 --- a/src/services/push.ts +++ b/src/services/push.ts @@ -1,9 +1,8 @@ -import { Buffer } from 'buffer'; -import mqtt, { - type IClientOptions, - type IConnackPacket, - type IPublishPacket, - type MqttClient, +import type { + IClientOptions, + IConnackPacket, + IPublishPacket, + MqttClient, } from 'mqtt'; import { Client } from '../client'; @@ -52,6 +51,33 @@ export interface PushSubscription { type AuthMethod = 'appwrite-jwt' | 'appwrite-session' | ''; +const TAB_ID_KEY = 'appwrite-push-client-id'; + +interface Transport { + connect: typeof import('mqtt').connect; + Buffer: typeof import('buffer').Buffer; +} + +// Loaded on first connect, so an app that never uses Push does not bundle mqtt.js. +let transport: Promise<Transport> | null = null; + +function loadTransport(): Promise<Transport> { + if (!transport) { + transport = Promise.all([import('mqtt'), import('buffer')]).then( + // The browser build of mqtt.js (dist/mqtt.esm.js) exports only a default. + ([mqtt, buffer]) => ({ + connect: (mqtt.default ?? mqtt).connect, + Buffer: buffer.Buffer, + }), + ); + // A failed load must not poison later connects. + transport.catch(() => { + transport = null; + }); + } + return transport; +} + // Fixed connection tuning — not exposed as options. const KEEP_ALIVE_SECONDS = 60; const RECONNECT_PERIOD_MS = 2000; @@ -80,6 +106,9 @@ const RECONNECT_PERIOD_MS = 2000; export class Push extends Service { private mqtt: MqttClient | null = null; private connecting: Promise<void> | null = null; + private Buffer: Transport['Buffer'] | null = null; + /** Bumped by close(), so a connect still loading mqtt.js knows to stop. */ + private generation = 0; /** Set once the first CONNACK lands, so 'connect' events after are reconnects. */ private everConnected = false; @@ -96,10 +125,18 @@ export class Push extends Service { // Local id -> subscription state. The id is never sent to the broker; it only lets // the same topic carry more than one callback (each with its own options). /** - * The client id when the credential names no user (and none was set): random, but kept for - * this instance so reconnects resume the same broker session. + * This tab's part of the default client id when the tab has none yet (see claimTabId): + * random, but kept for this instance so reconnects resume the same broker session. */ private readonly fallbackClientId = randomId(); + /** The default client id claimed for this instance's connection, released on close(). */ + private tabId = ''; + /** In-flight claim of {@link tabId}, memoized per generation: a credential switch (same + * generation) shares the one claim; a close/reopen (new generation) chains a fresh claim. */ + private tabIdClaim: Promise<string> | null = null; + private tabIdClaimGeneration = -1; + private connectedKey = ''; + private connectionEpoch = 0; private readonly subscriptions = new Map< string, @@ -281,7 +318,20 @@ export class Push extends Service { this.requestNotificationPermission(); } - const client = await this.connect(); + let client: MqttClient; + try { + client = await this.connect(); + } catch (err) { + if (err instanceof SupersededError) { + return this.subscribeWith( + topicsOrCallback, + callbackOrOptions, + topicOptions, + ); + } + throw err; + } + const epoch = this.connectionEpoch; const ids: string[] = []; const acks: Promise<void>[] = []; @@ -351,6 +401,16 @@ export class Push extends Service { try { await Promise.all(acks); } catch (err) { + if (epoch !== this.connectionEpoch) { + for (const id of ids) { + this.subscriptions.delete(id); + } + return this.subscribeWith( + topicsOrCallback, + callbackOrOptions, + topicOptions, + ); + } unsubscribe(); throw err; } @@ -416,7 +476,14 @@ export class Push extends Service { this.mqtt.end(true); this.mqtt = null; } + if (this.tabId !== '') { + releaseTabId(this.tabId); + this.tabId = ''; + } this.connecting = null; + // Bumping the generation ends the current claim: one still in flight releases its id when + // it resolves, and the next open() chains a fresh claim after it (see claimClientId). + this.generation++; this.everConnected = false; this.subscriptions.clear(); } @@ -450,20 +517,66 @@ export class Push extends Service { // --- internals --- private connect(): Promise<MqttClient> { - if (this.mqtt) { + if ( + (this.mqtt || this.connecting) && + this.connectedKey !== this.credentialKey() + ) { + this.connectionEpoch++; + this.mqtt?.end(true); + this.mqtt = null; + this.connecting = null; + this.everConnected = this.subscriptions.size > 0; + } + if (this.mqtt && !this.connecting) { return Promise.resolve(this.mqtt); } if (!this.connecting) { - this.connecting = this.open(); + const connecting = this.open(); + this.connecting = connecting; // A failed open must not poison future attempts — clear the cached // in-flight promise so a later subscribe/publish can retry. - this.connecting.catch(() => { - this.connecting = null; + connecting.catch(() => { + if (this.connecting === connecting) { + this.connecting = null; + } }); } return this.connecting.then(() => this.mqtt!); } + private credential(): { authMethod: AuthMethod; credential: string } { + if (this.client.config.jwt) { + return { + authMethod: 'appwrite-jwt', + credential: this.client.config.jwt, + }; + } + if (this.client.config.session) { + return { + authMethod: 'appwrite-session', + credential: this.client.config.session, + }; + } + throw new Error( + 'No credential set on the client; call Client.setJWT() or Client.setSession() first.', + ); + } + + private credentialKey(): string { + try { + const { authMethod, credential } = this.credential(); + return [ + this.endpointUrl(), + this.client.config.project ?? '', + this.client.config.pushClientId ?? '', + authMethod, + credential, + ].join('|'); + } catch { + return ''; + } + } + private endpointUrl(): string { // The push endpoint set on the client (Client.setPushEndpoint) wins. if (this.client.config.endpointPush !== '') { @@ -482,35 +595,80 @@ export class Push extends Service { : `${wsEndpoint.slice(0, at + separator.length)}push.${wsEndpoint.slice(at + separator.length)}`; } - private async open(): Promise<void> { - // Read the credential set on the client (via Client.setJWT / setSession). - let authMethod: AuthMethod; - let credential: string; - if (this.client.config.jwt) { - authMethod = 'appwrite-jwt'; - credential = this.client.config.jwt; - } else if (this.client.config.session) { - authMethod = 'appwrite-session'; - credential = this.client.config.session; - } else { - throw new Error( - 'No credential set on the client; call Client.setJWT() or Client.setSession() first.', - ); + /** + * Claim this connection's default client id, memoized per generation. A credential switch (same + * generation) shares the one claim, so concurrent open() calls never each claim. A close/reopen + * (a new generation) chains a fresh claim after the previous one has settled and released its + * id, so the reopened connection can take the tab's stored id back rather than a fallback. A + * claim that resolves after its generation has ended releases its id instead of keeping it, so + * a stale open connects with nothing reserved and the stored id is never stranded. + */ + private claimClientId(): Promise<string> { + const generation = this.generation; + if ( + this.tabIdClaim === null || + this.tabIdClaimGeneration !== generation + ) { + const previous = this.tabIdClaim ?? Promise.resolve(''); + this.tabIdClaimGeneration = generation; + const claim = previous + .catch(() => '') + .then(() => claimTabId(this.fallbackClientId)) + .then((id) => { + if (this.generation !== generation) { + releaseTabId(id); + return ''; + } + this.tabId = id; + return id; + }); + this.tabIdClaim = claim; + return claim; } + return this.tabIdClaim; + } + + private async open(): Promise<void> { + const { authMethod, credential } = this.credential(); + this.connectedKey = this.credentialKey(); + const epoch = this.connectionEpoch; + const generation = this.generation; const project = this.client.config.project ?? ''; // Client id, when the app did not set one with Client.setPushClientId(). Unlike the // native SDKs (which send an empty id and let the broker derive a stable one), mqtt.js - // rejects an empty id with clean start off, so derive a stable per-user id here from the - // credential this connection authenticates with: the JWT's userId, or the session's user - // id. A stable id keeps the broker's replay cursor resuming across reloads. The - // credential itself is never used as the id. + // rejects an empty id with clean start off, so derive one per user and tab from the + // credential this connection authenticates with (the JWT's userId, or the session's user + // id) and an id kept in the tab's sessionStorage. It stays the same across reloads, so + // the broker's replay cursor resumes, and differs between tabs and browsers, so two of + // them do not take over each other's session. The credential itself is never used. + const userId = + authMethod === 'appwrite-jwt' + ? userIdFromJwt(credential) + : userIdFromSession(credential); + // Claim once per instance (memoized) and reuse it across reconnects and credential + // switches, so concurrent open() calls never each claim and strand the tab's stored id. + // Concurrent instances still get distinct ids. If close() ran while the claim was pending + // this open is stale, so stop before connecting (the claim releases its own id). + if (!this.client.config.pushClientId) { + await this.claimClientId(); + if (generation !== this.generation) { + throw new Error('Push was closed while connecting.'); + } + } + const tabId = this.tabId; const clientId = this.client.config.pushClientId || - (authMethod === 'appwrite-jwt' - ? userIdFromJwt(credential) - : userIdFromSession(credential)) || - this.fallbackClientId; + (userId ? `${userId}-${tabId}` : tabId); + + const { connect, Buffer } = await loadTransport(); + if (generation !== this.generation) { + throw new Error('Push was closed while connecting.'); + } + if (epoch !== this.connectionEpoch) { + throw new SupersededError(); + } + this.Buffer = Buffer; const options: IClientOptions = { clientId, @@ -527,7 +685,7 @@ export class Push extends Service { }, }; - const client = mqtt.connect(this.endpointUrl(), options); + const client = connect(this.endpointUrl(), options); this.mqtt = client; client.on('message', (_topic, _payload, packet) => { @@ -559,6 +717,9 @@ export class Push extends Service { } }); client.on('error', (err) => { + if (epoch !== this.connectionEpoch) { + return; + } const error = this.connectError(err, refusedReason); // While the first connect is pending its caller receives the error (and reports it // through fail()); afterwards, e.g. on reconnect, report it here. @@ -581,6 +742,10 @@ export class Push extends Service { await new Promise<void>((resolve, reject) => { const onConnect = (packet: IConnackPacket) => { cleanup(); + if (epoch !== this.connectionEpoch) { + reject(new SupersededError()); + return; + } const rc = packet.reasonCode ?? packet.returnCode ?? 0; if (rc !== 0) { this.close(); @@ -596,16 +761,30 @@ export class Push extends Service { }; const onError = (err: Error) => { cleanup(); + if (epoch !== this.connectionEpoch) { + reject(new SupersededError()); + return; + } this.close(); reject(this.connectError(err, refusedReason)); }; + const onClose = () => { + if (epoch !== this.connectionEpoch) { + cleanup(); + reject(new SupersededError()); + } + }; const cleanup = () => { - this.opening = false; + if (epoch === this.connectionEpoch) { + this.opening = false; + } client.removeListener('connect', onConnect); client.removeListener('error', onError); + client.removeListener('close', onClose); }; client.on('connect', onConnect); client.on('error', onError); + client.on('close', onClose); client.connect(); }); } @@ -627,6 +806,7 @@ export class Push extends Service { /** Fan a delivered packet out to every subscription whose filter matches. */ private async dispatch(packet: IPublishPacket): Promise<void> { + const Buffer = this.Buffer!; const payload = Buffer.isBuffer(packet.payload) ? packet.payload : Buffer.from(packet.payload); @@ -677,6 +857,12 @@ export class Push extends Service { } } +class SupersededError extends Error { + constructor() { + super('The push connection was superseded'); + } +} + /** Normalize anything thrown or passed to an error handler into an `Error`. */ function toError(error: unknown): Error { return error instanceof Error ? error : new Error(String(error)); @@ -696,11 +882,9 @@ function userIdFromJwt(jwt?: string): string { return ''; } try { - const json = Buffer.from( - parts[1].replace(/-/g, '+').replace(/_/g, '/'), - 'base64', - ).toString('utf-8'); - const payload = JSON.parse(json); + const payload = JSON.parse( + decodeBase64(parts[1].replace(/-/g, '+').replace(/_/g, '/')), + ); return typeof payload.userId === 'string' ? payload.userId : ''; } catch { return ''; @@ -716,15 +900,105 @@ function userIdFromSession(session?: string): string { return ''; } try { - const payload = JSON.parse( - Buffer.from(session, 'base64').toString('utf-8'), - ); + const payload = JSON.parse(decodeBase64(session)); return typeof payload.id === 'string' ? payload.id : ''; } catch { return ''; } } +/** Ids in use by live connections in this page, so two Push instances never share a client id. */ +const claimedTabIds = new Set<string>(); +/** The tab's stored id, resolved and locked once per page (see claimStoredTabId). */ +let storedTabIdClaim: Promise<string> | null = null; + +/** + * A default client id for one Push connection in this page. The first connection alive takes the + * tab's stored id (kept in sessionStorage and locked for the page's lifetime, so it stays the same + * across reloads and the broker's replay cursor resumes). Any connection alive at the same time + * takes a distinct locked id instead, so simultaneous Push instances never share a client id and + * so cannot take over each other's broker session. `fallback` is this instance's own random id. + */ +async function claimTabId(fallback: string): Promise<string> { + const stored = await claimStoredTabId(fallback); + if (stored !== '' && !claimedTabIds.has(stored)) { + claimedTabIds.add(stored); + return stored; + } + // The tab's id is taken by another live connection here: take a distinct, locked id without + // touching the tab's stored cursor. + let id = fallback; + while (claimedTabIds.has(id)) { + id = randomId(); + } + const locks = + typeof navigator === 'undefined' ? undefined : navigator.locks; + if (locks) { + await holdTabId(locks, id); + } + claimedTabIds.add(id); + return id; +} + +/** Free an id when its connection closes, so a later connection can reuse it (e.g. the stored id). */ +function releaseTabId(id: string): void { + claimedTabIds.delete(id); +} + +/** + * The tab's stored id, resolved and locked once per page: the value in sessionStorage when a lock + * on it is free (this tab owns it), else a fresh id that is locked and stored. Without Web Locks + * (or when locking fails) a copied id cannot be told apart from another tab's, so the page uses a + * fresh id and leaves sessionStorage alone. '' when sessionStorage cannot be read, so the caller + * falls back to its own id. + */ +function claimStoredTabId(fallback: string): Promise<string> { + storedTabIdClaim ??= (async () => { + const locks = + typeof navigator === 'undefined' ? undefined : navigator.locks; + if (!locks) { + return fallback; + } + let stored: string | null; + try { + stored = window.sessionStorage.getItem(TAB_ID_KEY); + } catch { + return ''; + } + if (stored && (await holdTabId(locks, stored))) { + return stored; + } + if (!(await holdTabId(locks, fallback))) { + return fallback; + } + try { + window.sessionStorage.setItem(TAB_ID_KEY, fallback); + } catch { + // Not persisted, but still usable as this page's stored id for this session. + } + return fallback; + })(); + return storedTabIdClaim; +} + +function holdTabId(locks: LockManager, id: string): Promise<boolean> { + return new Promise((resolve) => { + locks + .request(`${TAB_ID_KEY}:${id}`, { ifAvailable: true }, (lock) => { + resolve(lock !== null); + return lock ? new Promise<void>(() => {}) : undefined; + }) + .catch(() => resolve(false)); + }); +} + +/** Base64 to UTF-8 text without `buffer`, which only loads once Push connects. */ +function decodeBase64(value: string): string { + return new TextDecoder().decode( + Uint8Array.from(atob(value), (char) => char.charCodeAt(0)), + ); +} + /** A hex id, uuid4-like enough for a client-generated client id suffix. */ function randomId(): string { let out = ''; diff --git a/src/services/sites.ts b/src/services/sites.ts index fa850f11..8f6ae8a3 100644 --- a/src/services/sites.ts +++ b/src/services/sites.ts @@ -486,12 +486,45 @@ export class Sites { /** * Get a list of all frameworks that are currently available on the server instance. * + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.FrameworkList>} */ - listFrameworks(): Promise<Models.FrameworkList> { + listFrameworks(params?: { total?: boolean }): Promise<Models.FrameworkList>; + /** + * Get a list of all frameworks that are currently available on the server instance. + * + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. + * @throws {AppwriteException} + * @returns {Promise<Models.FrameworkList>} + * @deprecated Use the object parameter style method for a better developer experience. + */ + listFrameworks(total?: boolean): Promise<Models.FrameworkList>; + listFrameworks( + paramsOrFirst?: { total?: boolean } | boolean, + ): Promise<Models.FrameworkList> { + let params: { total?: boolean }; + + if ( + typeof paramsOrFirst === 'undefined' || + (paramsOrFirst && + typeof paramsOrFirst === 'object' && + !Array.isArray(paramsOrFirst)) + ) { + params = (paramsOrFirst || {}) as { total?: boolean }; + } else { + params = { + total: paramsOrFirst as boolean, + }; + } + + const total = params.total; + const apiPath = '/sites/frameworks'; const apiPayload: Payload = {}; + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -506,46 +539,61 @@ export class Sites { * List allowed site specifications for this instance. * * @param {string} params.type - Specification type to list. Can be one of: runtimes, builds. Defaults to runtimes. + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.SpecificationList>} */ listSpecifications(params?: { type?: string; + total?: boolean; }): Promise<Models.SpecificationList>; /** * List allowed site specifications for this instance. * * @param {string} type - Specification type to list. Can be one of: runtimes, builds. Defaults to runtimes. + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.SpecificationList>} * @deprecated Use the object parameter style method for a better developer experience. */ - listSpecifications(type?: string): Promise<Models.SpecificationList>; listSpecifications( - paramsOrFirst?: { type?: string } | string, + type?: string, + total?: boolean, + ): Promise<Models.SpecificationList>; + listSpecifications( + paramsOrFirst?: { type?: string; total?: boolean } | string, + ...rest: [boolean?] ): Promise<Models.SpecificationList> { - let params: { type?: string }; + let params: { type?: string; total?: boolean }; if ( - typeof paramsOrFirst === 'undefined' || + (typeof paramsOrFirst === 'undefined' && rest.length === 0) || (paramsOrFirst && typeof paramsOrFirst === 'object' && !Array.isArray(paramsOrFirst)) ) { - params = (paramsOrFirst || {}) as { type?: string }; + params = (paramsOrFirst || {}) as { + type?: string; + total?: boolean; + }; } else { params = { type: paramsOrFirst as string, + total: rest[0] as boolean, }; } const type = params.type; + const total = params.total; const apiPath = '/sites/specifications'; const apiPayload: Payload = {}; if (typeof type !== 'undefined') { apiPayload['type'] = type; } + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -563,6 +611,7 @@ export class Sites { * @param {SiteTemplateUseCase[]} params.useCases - List of use cases allowed for filtering site templates. Maximum of 100 use cases are allowed. * @param {number} params.limit - Limit the number of templates returned in the response. Default limit is 25, and maximum limit is 5000. * @param {number} params.offset - Offset the list of returned templates. Maximum offset is 5000. + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.TemplateSiteList>} */ @@ -571,6 +620,7 @@ export class Sites { useCases?: SiteTemplateUseCase[]; limit?: number; offset?: number; + total?: boolean; }): Promise<Models.TemplateSiteList>; /** * List available site templates. You can use template details in [createSite](/docs/references/cloud/server-nodejs/sites#create) method. @@ -579,6 +629,7 @@ export class Sites { * @param {SiteTemplateUseCase[]} useCases - List of use cases allowed for filtering site templates. Maximum of 100 use cases are allowed. * @param {number} limit - Limit the number of templates returned in the response. Default limit is 25, and maximum limit is 5000. * @param {number} offset - Offset the list of returned templates. Maximum offset is 5000. + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.TemplateSiteList>} * @deprecated Use the object parameter style method for a better developer experience. @@ -588,6 +639,7 @@ export class Sites { useCases?: SiteTemplateUseCase[], limit?: number, offset?: number, + total?: boolean, ): Promise<Models.TemplateSiteList>; listTemplates( paramsOrFirst?: @@ -596,15 +648,17 @@ export class Sites { useCases?: SiteTemplateUseCase[]; limit?: number; offset?: number; + total?: boolean; } | Framework[], - ...rest: [SiteTemplateUseCase[]?, number?, number?] + ...rest: [SiteTemplateUseCase[]?, number?, number?, boolean?] ): Promise<Models.TemplateSiteList> { let params: { frameworks?: Framework[]; useCases?: SiteTemplateUseCase[]; limit?: number; offset?: number; + total?: boolean; }; if ( @@ -615,13 +669,15 @@ export class Sites { ('frameworks' in paramsOrFirst || 'useCases' in paramsOrFirst || 'limit' in paramsOrFirst || - 'offset' in paramsOrFirst)) + 'offset' in paramsOrFirst || + 'total' in paramsOrFirst)) ) { params = (paramsOrFirst || {}) as { frameworks?: Framework[]; useCases?: SiteTemplateUseCase[]; limit?: number; offset?: number; + total?: boolean; }; } else { params = { @@ -629,6 +685,7 @@ export class Sites { useCases: rest[0] as SiteTemplateUseCase[], limit: rest[1] as number, offset: rest[2] as number, + total: rest[3] as boolean, }; } @@ -636,6 +693,7 @@ export class Sites { const useCases = params.useCases; const limit = params.limit; const offset = params.offset; + const total = params.total; const apiPath = '/sites/templates'; const apiPayload: Payload = {}; @@ -651,6 +709,9 @@ export class Sites { if (typeof offset !== 'undefined') { apiPayload['offset'] = offset; } + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { diff --git a/src/services/tables-db.ts b/src/services/tables-db.ts index a472f937..6d4bfe25 100644 --- a/src/services/tables-db.ts +++ b/src/services/tables-db.ts @@ -250,46 +250,61 @@ export class TablesDB { * List transactions across all databases. * * @param {string[]} params.queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.TransactionList>} */ listTransactions(params?: { queries?: string[]; + total?: boolean; }): Promise<Models.TransactionList>; /** * List transactions across all databases. * * @param {string[]} queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.TransactionList>} * @deprecated Use the object parameter style method for a better developer experience. */ - listTransactions(queries?: string[]): Promise<Models.TransactionList>; listTransactions( - paramsOrFirst?: { queries?: string[] } | string[], + queries?: string[], + total?: boolean, + ): Promise<Models.TransactionList>; + listTransactions( + paramsOrFirst?: { queries?: string[]; total?: boolean } | string[], + ...rest: [boolean?] ): Promise<Models.TransactionList> { - let params: { queries?: string[] }; + let params: { queries?: string[]; total?: boolean }; if ( - typeof paramsOrFirst === 'undefined' || + (typeof paramsOrFirst === 'undefined' && rest.length === 0) || (paramsOrFirst && typeof paramsOrFirst === 'object' && !Array.isArray(paramsOrFirst)) ) { - params = (paramsOrFirst || {}) as { queries?: string[] }; + params = (paramsOrFirst || {}) as { + queries?: string[]; + total?: boolean; + }; } else { params = { queries: paramsOrFirst as string[], + total: rest[0] as boolean, }; } const queries = params.queries; + const total = params.total; const apiPath = '/tablesdb/transactions'; const apiPayload: Payload = {}; if (typeof queries !== 'undefined') { apiPayload['queries'] = queries; } + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { diff --git a/src/services/teams.ts b/src/services/teams.ts index 34ff9368..692cb2b2 100644 --- a/src/services/teams.ts +++ b/src/services/teams.ts @@ -95,7 +95,7 @@ export class Teams { * * @param {string} params.teamId - Team ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. * @param {string} params.name - Team name. Max length: 128 chars. - * @param {string[]} params.roles - Array of strings. Use this param to set the roles in the team for the user who created it. The default role is **owner**. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Maximum of 100 roles are allowed, each 32 characters long. + * @param {string[]} params.roles - Array of strings. Use this param to set the roles in the team for the user who created it. The default role is **owner**. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Maximum of 100 roles are allowed, each 81 characters long. * @throws {AppwriteException} * @returns {Promise<Models.Team<Preferences>>} */ @@ -111,7 +111,7 @@ export class Teams { * * @param {string} teamId - Team ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. * @param {string} name - Team name. Max length: 128 chars. - * @param {string[]} roles - Array of strings. Use this param to set the roles in the team for the user who created it. The default role is **owner**. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Maximum of 100 roles are allowed, each 32 characters long. + * @param {string[]} roles - Array of strings. Use this param to set the roles in the team for the user who created it. The default role is **owner**. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Maximum of 100 roles are allowed, each 81 characters long. * @throws {AppwriteException} * @returns {Promise<Models.Team<Preferences>>} * @deprecated Use the object parameter style method for a better developer experience. diff --git a/src/services/usage.ts b/src/services/usage.ts index a4de85b9..b68cf643 100644 --- a/src/services/usage.ts +++ b/src/services/usage.ts @@ -25,9 +25,9 @@ export class Usage { * `dimensions[]` breaks each point down by one or more attributes (service, path, status, country, …). `queries[]` filters the underlying events using the standard Utopia query syntax — `equal("path", ["/v1/storage/files"])`, `equal("resourceType", ["bucket"])`, `equal("resourceId", ["abc123"])`, `startsWith("path", ["/v1/storage"])`, `equal("status", ["200", "201"])`, `isNotNull("resourceId")`. Supported attributes: see `queries[]` param. Supported methods: `equal`, `notEqual`, `contains`, `startsWith`, `endsWith`, `isNull`, `isNotNull`. Pass multiple metrics to render stacked charts in one round-trip. `orderBy=value`+`orderDir=desc`+`limit=N` returns the top-N by aggregated value. When `startAt` is omitted, the default window adapts to `interval` (or 7d when interval is omitted). * * @param {(UsageEventMetric | (string & {}))[]} params.metrics - One to ten metric names. Single-metric callers pass a one-element array. Example: `metrics[]=executions` or `metrics[]=executions&metrics[]=executions.compute` for stacked charts. On console: `metrics[]=affiliates.clicks`. - * @param {string[]} params.queries - Up to 10 filter queries in Utopia syntax. Allowed attributes, also published as the `UsageEventDimension` enum: path, method, status, service, resourceType, resourceId, teamId, country, continentCode, city, region, hostname, ip, osName, clientType, clientName, deviceName, sdk, sdkVersion, isp, autonomousSystemNumber, autonomousSystemOrganization, connectionType, connectionUsageType, connectionOrganization. Allowed methods: equal, notEqual, contains, startsWith, endsWith, isNull, isNotNull. Example: `queries[]=equal("resourceType", ["bucket"])`. + * @param {string[]} params.queries - Up to 10 filter queries in Utopia syntax. Allowed attributes, also published as the `UsageEventDimension` enum: path, method, status, service, resourceType, resourceId, teamId, country, continentCode, city, region, hostname, ip, osName, clientType, clientName, deviceName, sdk, sdkVersion, protocol, queryKeys, accept, acceptLanguage, postalCode, latitude, longitude, timeZone, weatherCode, isp, autonomousSystemNumber, autonomousSystemOrganization, connectionType, connectionUsageType, connectionOrganization. Allowed methods: equal, notEqual, contains, startsWith, endsWith, isNull, isNotNull. Example: `queries[]=equal("resourceType", ["bucket"])`. * @param {UsageInterval} params.interval - Time interval size. Omit (null) for a flat aggregate over the whole window. Allowed: 1m, 15m, 30m, 1h, 1d. - * @param {UsageEventDimension[]} params.dimensions - Break-down dimensions (max 10). Allowed: path, method, status, service, resourceType, country, continentCode, city, region, hostname, ip, osName, clientType, clientName, deviceName, sdk, sdkVersion, teamId, resourceId, isp, autonomousSystemNumber, autonomousSystemOrganization, connectionType, connectionUsageType, connectionOrganization. + * @param {UsageEventDimension[]} params.dimensions - Break-down dimensions (max 10). Allowed: path, method, status, service, resourceType, country, continentCode, city, region, hostname, ip, osName, clientType, clientName, deviceName, sdk, sdkVersion, teamId, resourceId, protocol, queryKeys, accept, acceptLanguage, postalCode, latitude, longitude, timeZone, weatherCode, isp, autonomousSystemNumber, autonomousSystemOrganization, connectionType, connectionUsageType, connectionOrganization. * @param {string} params.startAt - Range start in ISO 8601. Defaults adapt to interval (7d for the no-interval aggregate). * @param {string} params.endAt - Range end in ISO 8601. Defaults to the current time. * @param {UsageOrderBy} params.orderBy - Column to order by. Allowed: time, value. Default time when an interval is set; otherwise value. @@ -59,9 +59,9 @@ export class Usage { * `dimensions[]` breaks each point down by one or more attributes (service, path, status, country, …). `queries[]` filters the underlying events using the standard Utopia query syntax — `equal("path", ["/v1/storage/files"])`, `equal("resourceType", ["bucket"])`, `equal("resourceId", ["abc123"])`, `startsWith("path", ["/v1/storage"])`, `equal("status", ["200", "201"])`, `isNotNull("resourceId")`. Supported attributes: see `queries[]` param. Supported methods: `equal`, `notEqual`, `contains`, `startsWith`, `endsWith`, `isNull`, `isNotNull`. Pass multiple metrics to render stacked charts in one round-trip. `orderBy=value`+`orderDir=desc`+`limit=N` returns the top-N by aggregated value. When `startAt` is omitted, the default window adapts to `interval` (or 7d when interval is omitted). * * @param {(UsageEventMetric | (string & {}))[]} metrics - One to ten metric names. Single-metric callers pass a one-element array. Example: `metrics[]=executions` or `metrics[]=executions&metrics[]=executions.compute` for stacked charts. On console: `metrics[]=affiliates.clicks`. - * @param {string[]} queries - Up to 10 filter queries in Utopia syntax. Allowed attributes, also published as the `UsageEventDimension` enum: path, method, status, service, resourceType, resourceId, teamId, country, continentCode, city, region, hostname, ip, osName, clientType, clientName, deviceName, sdk, sdkVersion, isp, autonomousSystemNumber, autonomousSystemOrganization, connectionType, connectionUsageType, connectionOrganization. Allowed methods: equal, notEqual, contains, startsWith, endsWith, isNull, isNotNull. Example: `queries[]=equal("resourceType", ["bucket"])`. + * @param {string[]} queries - Up to 10 filter queries in Utopia syntax. Allowed attributes, also published as the `UsageEventDimension` enum: path, method, status, service, resourceType, resourceId, teamId, country, continentCode, city, region, hostname, ip, osName, clientType, clientName, deviceName, sdk, sdkVersion, protocol, queryKeys, accept, acceptLanguage, postalCode, latitude, longitude, timeZone, weatherCode, isp, autonomousSystemNumber, autonomousSystemOrganization, connectionType, connectionUsageType, connectionOrganization. Allowed methods: equal, notEqual, contains, startsWith, endsWith, isNull, isNotNull. Example: `queries[]=equal("resourceType", ["bucket"])`. * @param {UsageInterval} interval - Time interval size. Omit (null) for a flat aggregate over the whole window. Allowed: 1m, 15m, 30m, 1h, 1d. - * @param {UsageEventDimension[]} dimensions - Break-down dimensions (max 10). Allowed: path, method, status, service, resourceType, country, continentCode, city, region, hostname, ip, osName, clientType, clientName, deviceName, sdk, sdkVersion, teamId, resourceId, isp, autonomousSystemNumber, autonomousSystemOrganization, connectionType, connectionUsageType, connectionOrganization. + * @param {UsageEventDimension[]} dimensions - Break-down dimensions (max 10). Allowed: path, method, status, service, resourceType, country, continentCode, city, region, hostname, ip, osName, clientType, clientName, deviceName, sdk, sdkVersion, teamId, resourceId, protocol, queryKeys, accept, acceptLanguage, postalCode, latitude, longitude, timeZone, weatherCode, isp, autonomousSystemNumber, autonomousSystemOrganization, connectionType, connectionUsageType, connectionOrganization. * @param {string} startAt - Range start in ISO 8601. Defaults adapt to interval (7d for the no-interval aggregate). * @param {string} endAt - Range end in ISO 8601. Defaults to the current time. * @param {UsageOrderBy} orderBy - Column to order by. Allowed: time, value. Default time when an interval is set; otherwise value. diff --git a/src/services/vcs.ts b/src/services/vcs.ts index 8dc843fe..58c475ee 100644 --- a/src/services/vcs.ts +++ b/src/services/vcs.ts @@ -131,6 +131,7 @@ export class Vcs { * @param {VCSDetectionType} params.type - Detector type. Must be one of the following: runtime, framework * @param {string} params.search - Search term to filter your list results. Max length: 256 chars. * @param {string[]} params.queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit, offset, and equal on namespace. + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.ProviderRepositoryRuntimeList | Models.ProviderRepositoryFrameworkList>} */ @@ -139,6 +140,7 @@ export class Vcs { type: VCSDetectionType; search?: string; queries?: string[]; + total?: boolean; }): Promise< | Models.ProviderRepositoryRuntimeList | Models.ProviderRepositoryFrameworkList @@ -150,6 +152,7 @@ export class Vcs { * @param {VCSDetectionType} type - Detector type. Must be one of the following: runtime, framework * @param {string} search - Search term to filter your list results. Max length: 256 chars. * @param {string[]} queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit, offset, and equal on namespace. + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.ProviderRepositoryRuntimeList | Models.ProviderRepositoryFrameworkList>} * @deprecated Use the object parameter style method for a better developer experience. @@ -159,6 +162,7 @@ export class Vcs { type: VCSDetectionType, search?: string, queries?: string[], + total?: boolean, ): Promise< | Models.ProviderRepositoryRuntimeList | Models.ProviderRepositoryFrameworkList @@ -170,9 +174,10 @@ export class Vcs { type: VCSDetectionType; search?: string; queries?: string[]; + total?: boolean; } | string, - ...rest: [VCSDetectionType?, string?, string[]?] + ...rest: [VCSDetectionType?, string?, string[]?, boolean?] ): Promise< | Models.ProviderRepositoryRuntimeList | Models.ProviderRepositoryFrameworkList @@ -182,6 +187,7 @@ export class Vcs { type: VCSDetectionType; search?: string; queries?: string[]; + total?: boolean; }; if ( @@ -194,6 +200,7 @@ export class Vcs { type: VCSDetectionType; search?: string; queries?: string[]; + total?: boolean; }; } else { params = { @@ -201,6 +208,7 @@ export class Vcs { type: rest[0] as VCSDetectionType, search: rest[1] as string, queries: rest[2] as string[], + total: rest[3] as boolean, }; } @@ -208,6 +216,7 @@ export class Vcs { const type = params.type; const search = params.search; const queries = params.queries; + const total = params.total; if (typeof installationId === 'undefined' || installationId === '') { throw new AppwriteException( @@ -232,6 +241,9 @@ export class Vcs { if (typeof queries !== 'undefined') { apiPayload['queries'] = queries; } + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -450,6 +462,7 @@ export class Vcs { * @param {string} params.providerRepositoryId - Repository Id * @param {string} params.search - Search term to filter your list results. Max length: 256 chars. * @param {string[]} params.queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit, offset, cursorAfter, and cursorBefore + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.BranchList>} */ @@ -458,6 +471,7 @@ export class Vcs { providerRepositoryId: string; search?: string; queries?: string[]; + total?: boolean; }): Promise<Models.BranchList>; /** * Get a list of branches from a GitHub repository in your installation. This endpoint supports filtering by a search term and pagination using query strings such as `Query.limit()`, `Query.offset()`, `Query.cursorAfter()`, and `Query.cursorBefore()`. It returns branch names along with the total number of matches. The GitHub installation must be properly configured and have access to the requested repository for this endpoint to work. @@ -467,6 +481,7 @@ export class Vcs { * @param {string} providerRepositoryId - Repository Id * @param {string} search - Search term to filter your list results. Max length: 256 chars. * @param {string[]} queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit, offset, cursorAfter, and cursorBefore + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.BranchList>} * @deprecated Use the object parameter style method for a better developer experience. @@ -476,6 +491,7 @@ export class Vcs { providerRepositoryId: string, search?: string, queries?: string[], + total?: boolean, ): Promise<Models.BranchList>; listRepositoryBranches( paramsOrFirst: @@ -484,15 +500,17 @@ export class Vcs { providerRepositoryId: string; search?: string; queries?: string[]; + total?: boolean; } | string, - ...rest: [string?, string?, string[]?] + ...rest: [string?, string?, string[]?, boolean?] ): Promise<Models.BranchList> { let params: { installationId: string; providerRepositoryId: string; search?: string; queries?: string[]; + total?: boolean; }; if ( @@ -505,6 +523,7 @@ export class Vcs { providerRepositoryId: string; search?: string; queries?: string[]; + total?: boolean; }; } else { params = { @@ -512,6 +531,7 @@ export class Vcs { providerRepositoryId: rest[0] as string, search: rest[1] as string, queries: rest[2] as string[], + total: rest[3] as boolean, }; } @@ -519,6 +539,7 @@ export class Vcs { const providerRepositoryId = params.providerRepositoryId; const search = params.search; const queries = params.queries; + const total = params.total; if (typeof installationId === 'undefined' || installationId === '') { throw new AppwriteException( @@ -550,6 +571,9 @@ export class Vcs { if (typeof queries !== 'undefined') { apiPayload['queries'] = queries; } + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { @@ -986,6 +1010,7 @@ export class Vcs { * @param {string} params.installationId - Installation Id * @param {string} params.search - Search term to filter your list results. Max length: 256 chars. * @param {string[]} params.queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.VcsNamespaceList>} */ @@ -993,6 +1018,7 @@ export class Vcs { installationId: string; search?: string; queries?: string[]; + total?: boolean; }): Promise<Models.VcsNamespaceList>; /** * List provider namespaces available to a VCS installation. This can include the user personal namespace and any groups or organizations the installation can browse. @@ -1000,6 +1026,7 @@ export class Vcs { * @param {string} installationId - Installation Id * @param {string} search - Search term to filter your list results. Max length: 256 chars. * @param {string[]} queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.VcsNamespaceList>} * @deprecated Use the object parameter style method for a better developer experience. @@ -1008,17 +1035,24 @@ export class Vcs { installationId: string, search?: string, queries?: string[], + total?: boolean, ): Promise<Models.VcsNamespaceList>; listNamespaces( paramsOrFirst: - | { installationId: string; search?: string; queries?: string[] } + | { + installationId: string; + search?: string; + queries?: string[]; + total?: boolean; + } | string, - ...rest: [string?, string[]?] + ...rest: [string?, string[]?, boolean?] ): Promise<Models.VcsNamespaceList> { let params: { installationId: string; search?: string; queries?: string[]; + total?: boolean; }; if ( @@ -1030,18 +1064,21 @@ export class Vcs { installationId: string; search?: string; queries?: string[]; + total?: boolean; }; } else { params = { installationId: paramsOrFirst as string, search: rest[0] as string, queries: rest[1] as string[], + total: rest[2] as boolean, }; } const installationId = params.installationId; const search = params.search; const queries = params.queries; + const total = params.total; if (typeof installationId === 'undefined' || installationId === '') { throw new AppwriteException( @@ -1060,6 +1097,9 @@ export class Vcs { if (typeof queries !== 'undefined') { apiPayload['queries'] = queries; } + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { diff --git a/src/services/vectors-db.ts b/src/services/vectors-db.ts index 113c5288..0fbef33f 100644 --- a/src/services/vectors-db.ts +++ b/src/services/vectors-db.ts @@ -234,46 +234,61 @@ export class VectorsDB { * List transactions across all databases. * * @param {string[]} params.queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). + * @param {boolean} params.total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.TransactionList>} */ listTransactions(params?: { queries?: string[]; + total?: boolean; }): Promise<Models.TransactionList>; /** * List transactions across all databases. * * @param {string[]} queries - Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). + * @param {boolean} total - When set to false, the total count returned will be 0 and will not be calculated. * @throws {AppwriteException} * @returns {Promise<Models.TransactionList>} * @deprecated Use the object parameter style method for a better developer experience. */ - listTransactions(queries?: string[]): Promise<Models.TransactionList>; listTransactions( - paramsOrFirst?: { queries?: string[] } | string[], + queries?: string[], + total?: boolean, + ): Promise<Models.TransactionList>; + listTransactions( + paramsOrFirst?: { queries?: string[]; total?: boolean } | string[], + ...rest: [boolean?] ): Promise<Models.TransactionList> { - let params: { queries?: string[] }; + let params: { queries?: string[]; total?: boolean }; if ( - typeof paramsOrFirst === 'undefined' || + (typeof paramsOrFirst === 'undefined' && rest.length === 0) || (paramsOrFirst && typeof paramsOrFirst === 'object' && !Array.isArray(paramsOrFirst)) ) { - params = (paramsOrFirst || {}) as { queries?: string[] }; + params = (paramsOrFirst || {}) as { + queries?: string[]; + total?: boolean; + }; } else { params = { queries: paramsOrFirst as string[], + total: rest[0] as boolean, }; } const queries = params.queries; + const total = params.total; const apiPath = '/vectorsdb/transactions'; const apiPayload: Payload = {}; if (typeof queries !== 'undefined') { apiPayload['queries'] = queries; } + if (typeof total !== 'undefined') { + apiPayload['total'] = total; + } const uri = new URL(this.client.config.endpoint + apiPath); const apiHeaders: { [header: string]: string } = { diff --git a/src/services/webhooks.ts b/src/services/webhooks.ts index c4a505ca..8ad36930 100644 --- a/src/services/webhooks.ts +++ b/src/services/webhooks.ts @@ -324,7 +324,7 @@ export class Webhooks { * @param {boolean} params.enabled - Enable or disable a webhook. * @param {boolean} params.tls - Certificate verification, false for disabled or true for enabled. * @param {string} params.authUsername - Webhook HTTP user. Max length: 256 chars. - * @param {string} params.authPassword - Webhook HTTP password. Max length: 256 chars. + * @param {string} params.authPassword - Webhook HTTP password. Max length: 256 chars. Omit to keep the current password; it is cleared when the URL changes or TLS verification is disabled. * @throws {AppwriteException} * @returns {Promise<Models.Webhook>} */ @@ -348,7 +348,7 @@ export class Webhooks { * @param {boolean} enabled - Enable or disable a webhook. * @param {boolean} tls - Certificate verification, false for disabled or true for enabled. * @param {string} authUsername - Webhook HTTP user. Max length: 256 chars. - * @param {string} authPassword - Webhook HTTP password. Max length: 256 chars. + * @param {string} authPassword - Webhook HTTP password. Max length: 256 chars. Omit to keep the current password; it is cleared when the URL changes or TLS verification is disabled. * @throws {AppwriteException} * @returns {Promise<Models.Webhook>} * @deprecated Use the object parameter style method for a better developer experience. diff --git a/tsconfig.json b/tsconfig.json index c7292aa8..a89200ce 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,6 +9,7 @@ "lib": ["ESNext", "DOM"], "listEmittedFiles": false, "listFiles": false, + "module": "ES2020", "moduleResolution": "node", "noFallthroughCasesInSwitch": true, "pretty": true,