Skip to content

Conversation

@ChiragAgg5k
Copy link
Member

@ChiragAgg5k ChiragAgg5k commented Feb 12, 2026

This PR contains updates to the React Native SDK for version 0.21.0.

Summary by CodeRabbit

  • New Features

    • Realtime subscriptions can be filtered with queries.
    • New Organizations, billing, keys, payment methods, and related models added.
    • New Scopes and OAuth provider options exposed.
  • Breaking Changes

    • Roles enum removed; team membership methods now accept roles as string[].
  • Bug Fixes

    • Improved parameter detection for overloaded APIs.
  • Documentation

    • Numerous new examples and updated team membership docs.
  • Chores

    • Release bumped to 0.21.0 and compatibility note updated.

@coderabbitai
Copy link

coderabbitai bot commented Feb 12, 2026

Walkthrough

This PR removes the exported Roles enum and updates Teams APIs to accept string[] for roles, adds realtime query support to the Client (tracks queries, includes queries in socket URL, and updates subscribe/unsubscribe/cleanup signatures), expands Account service surface with billing addresses, keys, payment methods and many object-style overloads, adds Models types for keys/billing/payment/invoices/etc., introduces a new Organizations service, adds Scopes and new OAuthProvider members, adjusts Channel API (execution factory and account signature), broadens object-parameter detection in Avatars and other services, tweaks GraphQL conditionals, updates docs/examples, bumps version to 0.21.0, and updates CHANGELOG.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (14 files):

⚔️ CHANGELOG.md (content)
⚔️ README.md (content)
⚔️ docs/examples/teams/create-membership.md (content)
⚔️ docs/examples/teams/update-membership.md (content)
⚔️ package.json (content)
⚔️ src/channel.ts (content)
⚔️ src/client.ts (content)
⚔️ src/enums/o-auth-provider.ts (content)
⚔️ src/index.ts (content)
⚔️ src/models.ts (content)
⚔️ src/services/account.ts (content)
⚔️ src/services/avatars.ts (content)
⚔️ src/services/graphql.ts (content)
⚔️ src/services/teams.ts (content)

These conflicts must be resolved before merging into main.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main purpose of the changeset: a comprehensive React Native SDK update with version bump to 0.21.0, including feature additions and bug fixes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch dev
  • Create stacked PR with resolved conflicts
  • Post resolved changes as copyable diffs in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@docs/examples/teams/create-membership.md`:
- Line 12: The example uses an empty roles array which doesn't show the new
string-based usage; update the example's payload (the object with the roles
property) to include a realistic string role like "owner" (e.g., set roles to
['owner'] or another meaningful role) to demonstrate free-form string roles
instead of leaving roles: [] in the create-membership example.

In `@docs/examples/teams/update-membership.md`:
- Line 13: The example uses an empty roles array which doesn't demonstrate
string-based roles; update the example in update-membership.md by replacing
roles: [] with a concrete role string like roles: ["member"] (or ["admin"] as
appropriate) so readers see the expected string-based role format; ensure the
same pattern is applied consistently where the roles property is shown (e.g.,
create-membership examples).
🧹 Nitpick comments (1)
src/client.ts (1)

478-479: Static analysis: implicit return value from forEach callback.

Line 479 (Set.add returns the Set) triggers a Biome lint error. Line 476 has the same pre-existing pattern, but since line 479 is new code, consider wrapping it in braces for consistency with the linter.

Suggested fix
-        queryStrings.forEach(query => this.realtime.queries.add(query));
+        queryStrings.forEach(query => { this.realtime.queries.add(query); });

const result = await teams.createMembership({
teamId: '<TEAM_ID>',
roles: [Roles.Admin],
roles: [],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Example with empty roles array doesn't demonstrate the new string-based usage.

Since the Roles enum was removed in favor of free-form strings, the example should show a realistic role value (e.g., ['owner']) rather than an empty array. An empty array may confuse users into thinking roles are no longer needed or supported.

-    roles: [],
+    roles: ['owner'],
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
roles: [],
roles: ['owner'],
🤖 Prompt for AI Agents
In `@docs/examples/teams/create-membership.md` at line 12, The example uses an
empty roles array which doesn't show the new string-based usage; update the
example's payload (the object with the roles property) to include a realistic
string role like "owner" (e.g., set roles to ['owner'] or another meaningful
role) to demonstrate free-form string roles instead of leaving roles: [] in the
create-membership example.

teamId: '<TEAM_ID>',
membershipId: '<MEMBERSHIP_ID>',
roles: [Roles.Admin]
roles: []
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Same concern: empty roles array doesn't illustrate string-based roles.

Same as in create-membership.md — showing a concrete role string would make the example more useful.

-    roles: []
+    roles: ['owner']
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
roles: []
roles: ['owner']
🤖 Prompt for AI Agents
In `@docs/examples/teams/update-membership.md` at line 13, The example uses an
empty roles array which doesn't demonstrate string-based roles; update the
example in update-membership.md by replacing roles: [] with a concrete role
string like roles: ["member"] (or ["admin"] as appropriate) so readers see the
expected string-based role format; ensure the same pattern is applied
consistently where the roles property is shown (e.g., create-membership
examples).

@ChiragAgg5k ChiragAgg5k changed the title feat: React Native SDK update for version 0.20.0 feat: React Native SDK update for version 0.21.0 Feb 12, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
README.md (1)

4-9: ⚠️ Potential issue | 🟡 Minor

Version inconsistency between badge and compatibility statement.

Line 4 badge still references api version-1.8.1, while Line 9 now states compatibility with "Appwrite server version latest." These should be aligned. Additionally, "version latest" is vague — users need a concrete server version (or range) to determine compatibility. Consider specifying the actual minimum compatible server version.

🤖 Fix all issues with AI agents
In `@src/models.ts`:
- Around line 1644-1646: The JSDoc for the property userId is incorrect—update
the comment for the userId field to accurately state that it represents the ID
of the user who owns the payment method (or, if the server model actually uses a
team owner, rename the field to teamId and adjust the types accordingly); verify
against the server-side model and make the JSDoc match the actual semantics used
by the PaymentMethod model (reference the userId property to locate where to
change the comment).
- Around line 1437-1440: The JSDoc for the $id property is incorrect (it
currently reads "Region ID"); update the comment for the $id field to "Billing
Address ID" to match the entity semantics and generated docs—locate the $id
declaration in the same model (the property named $id) and replace the JSDoc
text only so consumers see "Billing Address ID".

In `@src/services/account.ts`:
- Around line 680-705: The guard in listKeys(...) incorrectly treats falsy
primitives like false as "no argument", causing calls like listKeys(false) to
drop total; update the presence check in listKeys to explicitly detect undefined
(e.g., use typeof paramsOrFirst === 'undefined' or arguments.length === 0)
instead of using !paramsOrFirst so that boolean false is preserved; apply the
same pattern to the similar overload in createJWT(...) to avoid dropping falsy
numeric/boolean arguments when callers pass 0 or false.

In `@src/services/organizations.ts`:
- Around line 16-32: Update the JSDoc `@param` descriptions that incorrectly say
"Team ID" to "Organization ID" for methods dealing with organizationId (notably
the overloaded delete signatures and estimationDeleteOrganization); search for
occurrences of the string "Team ID" in src/services/organizations.ts and replace
the `@param` text for organizationId with "Organization ID" so the docs are
consistent with other methods like createDowngradeFeedback and getPaymentMethod.
- Around line 61-78: Fix the possessive typo in the JSDoc comments for
getBillingAddress and getPaymentMethod by replacing "it's" with "its" in the
description strings; update the comment for getBillingAddress (method name:
getBillingAddress) from "Get a billing address using it's ID" to "Get a billing
address using its ID" and likewise update the comment for getPaymentMethod
(method name: getPaymentMethod) from "Get an organization's payment method using
it's payment method ID" to "Get an organization's payment method using its
payment method ID".
🧹 Nitpick comments (8)
src/channel.ts (2)

16-16: ActionableChannel still includes Channel<Execution> after Execution was removed from Actionable.

Actionable no longer includes Execution (Line 16), so .create(), .update(), .delete() cannot be called on a Channel<Execution>. However, ActionableChannel (Line 131) still lists Channel<Execution>, which is misleading—the name implies these channels are "actionable."

If ActionableChannel is purely a convenience union for realtime subscription types (not tied to the terminal actions), consider renaming it to something like SubscribableChannel to avoid confusion. Otherwise, if it should mirror Actionable, remove Channel<Execution> from it.

Also applies to: 131-131


108-110: account() return type changed from Channel to plain string.

This is consistent with the other global event helpers (documents, rows, files, executions) that also return string. However, unlike those (which are static get accessors), account is a regular static method. Consider making it a getter for consistency:

-  static account(): string {
-    return "account";
-  }
+  static get account(): string {
+    return "account";
+  }

This would align the calling convention (Channel.account vs Channel.account()) with the other string-returning statics like Channel.documents, Channel.files, etc.

src/enums/o-auth-provider.ts (1)

41-42: New entries break the alphabetical ordering of enum members.

The existing members are alphabetically sorted (Amazon → Zoom), but GithubImagine and GoogleImagine are appended at the end. Since this SDK is auto-generated, this is likely a generator concern rather than something to fix here, but worth noting if the generator ordering logic needs attention.

src/models.ts (3)

1457-1468: Inconsistent capitalization in JSDoc comments for city, state, and postalCode.

Other field descriptions in this file use title-case (e.g., "Street address", "Address country"), but these three are all lowercase. Minor nit for consistency.

📝 Suggested fix
         /**
-         * city
+         * City
          */
         city: string;
         /**
-         * state
+         * State
          */
         state: string;
         /**
-         * postal code
+         * Postal code
          */
         postalCode: string;

1611-1612: JSDoc type label uses lowercase "paymentMethod".

TypeScript convention and the pattern in this file use PascalCase for type names in JSDoc headers (e.g., "BillingAddress", "Key"). This should be "PaymentMethod".

📝 Suggested fix
     /**
-     * paymentMethod
+     * PaymentMethod
      */

1697-1725: Type name UsageResources (plural) represents a single resource entry.

The JSDoc header says "UsageResource" (singular), but the exported type is UsageResources. Since Invoice.usage is already typed as UsageResources[], the plural name causes a confusing UsageResources[] ("resources-list of resources"). Consider renaming the type to UsageResource (singular) for clarity.

Note: this would also require updating the Invoice.usage field type reference.

src/services/organizations.ts (1)

1-6: Unused imports: FileSystem, Platform, and UploadProgress.

These imports (expo-file-system, react-native's Platform, and UploadProgress) are not referenced anywhere in this service file. They appear to be boilerplate from code generation. If this is auto-generated, this is fine, but if hand-maintained, consider removing them to reduce unnecessary dependencies.

src/services/account.ts (1)

2629-2678: Object-detection guard for createOAuth2Session is fragile with plain objects.

Line 2635: The guard checks 'provider' in paramsOrFirst || 'success' in paramsOrFirst || 'failure' in paramsOrFirst || 'scopes' in paramsOrFirst. If a caller passes a plain object without any of these keys (e.g., an empty object {}), it falls through to the else branch and casts the object as OAuthProvider. This is a minor edge case since TypeScript types would prevent it in well-typed code, and the provider required-check at line 2651 would catch it at runtime.

Same pattern applies to createOAuth2Token at line 3325.

Comment on lines +1437 to +1440
/**
* Region ID
*/
$id: string;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

JSDoc for $id says "Region ID" — likely a copy-paste error.

This should read "Billing Address ID" to match the entity type. The current comment is misleading for consumers reading the type docs.

📝 Suggested fix
     export type BillingAddress = {
         /**
-         * Region ID
+         * Billing Address ID.
          */
         $id: string;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* Region ID
*/
$id: string;
/**
* Billing Address ID.
*/
$id: string;
🤖 Prompt for AI Agents
In `@src/models.ts` around lines 1437 - 1440, The JSDoc for the $id property is
incorrect (it currently reads "Region ID"); update the comment for the $id field
to "Billing Address ID" to match the entity semantics and generated docs—locate
the $id declaration in the same model (the property named $id) and replace the
JSDoc text only so consumers see "Billing Address ID".

Comment on lines +1644 to +1646
* ID of the Team.
*/
userId: string;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Misleading JSDoc: userId documented as "ID of the Team."

The field name is userId but the doc says "ID of the Team." This is confusing and likely a copy-paste error from the server-side definition. It should clarify whether this is the user or the team that owns the payment method.

🤖 Prompt for AI Agents
In `@src/models.ts` around lines 1644 - 1646, The JSDoc for the property userId is
incorrect—update the comment for the userId field to accurately state that it
represents the ID of the user who owns the payment method (or, if the server
model actually uses a team owner, rename the field to teamId and adjust the
types accordingly); verify against the server-side model and make the JSDoc
match the actual semantics used by the PaymentMethod model (reference the userId
property to locate where to change the comment).

Comment on lines +680 to +705
listKeys(
paramsOrFirst?: { total?: boolean } | boolean
): Promise<Models.KeyList> {
let params: { total?: boolean };

if (!paramsOrFirst || (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/keys';
const payload: Payload = {};

if (typeof total !== 'undefined') {
payload['total'] = total;
}

const uri = new URL(this.client.config.endpoint + apiPath);
return this.client.call('get', uri, {
}, payload);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Bug: listKeys(false) silently drops the total parameter.

Line 685: the guard !paramsOrFirst || (...) treats falsy primitives (false, 0) as "no argument provided." When a consumer calls the deprecated overload listKeys(false), the !false check is true, so it enters the object-parameter branch with params = (false || {}){}, silently discarding total = false. This defeats the purpose of the total parameter (which exists specifically to be set to false).

The same root cause affects createJWT(0) at line 640 (though duration=0 is likely an invalid value, the pattern is still incorrect).

Since this appears to be auto-generated SDK code, the fix should be applied in the code generator. The guard should distinguish "not provided" from "falsy primitive" — e.g., check arguments.length === 0 or use typeof paramsOrFirst === 'undefined' instead of !paramsOrFirst.

Suggested fix for listKeys
-        if (!paramsOrFirst || (paramsOrFirst && typeof paramsOrFirst === 'object' && !Array.isArray(paramsOrFirst))) {
+        if (typeof paramsOrFirst === 'undefined' || (paramsOrFirst !== null && typeof paramsOrFirst === 'object' && !Array.isArray(paramsOrFirst))) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
listKeys(
paramsOrFirst?: { total?: boolean } | boolean
): Promise<Models.KeyList> {
let params: { total?: boolean };
if (!paramsOrFirst || (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/keys';
const payload: Payload = {};
if (typeof total !== 'undefined') {
payload['total'] = total;
}
const uri = new URL(this.client.config.endpoint + apiPath);
return this.client.call('get', uri, {
}, payload);
}
listKeys(
paramsOrFirst?: { total?: boolean } | boolean
): Promise<Models.KeyList> {
let params: { total?: boolean };
if (typeof paramsOrFirst === 'undefined' || (paramsOrFirst !== null && typeof paramsOrFirst === 'object' && !Array.isArray(paramsOrFirst))) {
params = (paramsOrFirst || {}) as { total?: boolean };
} else {
params = {
total: paramsOrFirst as boolean
};
}
const total = params.total;
const apiPath = '/account/keys';
const payload: Payload = {};
if (typeof total !== 'undefined') {
payload['total'] = total;
}
const uri = new URL(this.client.config.endpoint + apiPath);
return this.client.call('get', uri, {
}, payload);
}
🤖 Prompt for AI Agents
In `@src/services/account.ts` around lines 680 - 705, The guard in listKeys(...)
incorrectly treats falsy primitives like false as "no argument", causing calls
like listKeys(false) to drop total; update the presence check in listKeys to
explicitly detect undefined (e.g., use typeof paramsOrFirst === 'undefined' or
arguments.length === 0) instead of using !paramsOrFirst so that boolean false is
preserved; apply the same pattern to the similar overload in createJWT(...) to
avoid dropping falsy numeric/boolean arguments when callers pass 0 or false.

Comment on lines +16 to +32
/**
* Delete an organization.
*
* @param {string} params.organizationId - Team ID.
* @throws {AppwriteException}
* @returns {Promise}
*/
delete(params: { organizationId: string }): Promise<{}>;
/**
* Delete an organization.
*
* @param {string} organizationId - Team ID.
* @throws {AppwriteException}
* @returns {Promise<{}>}
* @deprecated Use the object parameter style method for a better developer experience.
*/
delete(organizationId: string): Promise<{}>;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

JSDoc inconsistency: organizationId documented as "Team ID" in delete and estimationDeleteOrganization.

The @param descriptions for organizationId say "Team ID" in the delete (lines 19, 27) and estimationDeleteOrganization (lines 117, 125) methods, while other methods like createDowngradeFeedback (line 163) and getPaymentMethod (line 258) correctly say "Organization ID". This inconsistency could confuse consumers of the API docs.

Also applies to: 114-130

🤖 Prompt for AI Agents
In `@src/services/organizations.ts` around lines 16 - 32, Update the JSDoc `@param`
descriptions that incorrectly say "Team ID" to "Organization ID" for methods
dealing with organizationId (notably the overloaded delete signatures and
estimationDeleteOrganization); search for occurrences of the string "Team ID" in
src/services/organizations.ts and replace the `@param` text for organizationId
with "Organization ID" so the docs are consistent with other methods like
createDowngradeFeedback and getPaymentMethod.

Comment on lines +61 to +78
/**
* Get a billing address using it's ID.
*
* @param {string} params.organizationId - Organization ID
* @param {string} params.billingAddressId - Unique ID of billing address
* @throws {AppwriteException}
* @returns {Promise}
*/
getBillingAddress(params: { organizationId: string, billingAddressId: string }): Promise<Models.BillingAddress>;
/**
* Get a billing address using it's ID.
*
* @param {string} organizationId - Organization ID
* @param {string} billingAddressId - Unique ID of billing address
* @throws {AppwriteException}
* @returns {Promise<Models.BillingAddress>}
* @deprecated Use the object parameter style method for a better developer experience.
*/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Typo: "it's" → "its" (possessive) in getBillingAddress and getPaymentMethod JSDoc.

"it's" is a contraction of "it is", whereas the possessive form "its" is correct here.

  • Line 62/71: "Get a billing address using it's ID" → "using its ID"
  • Line 256/265: "Get an organization's payment method using it's payment method ID" → "using its payment method ID"

Also applies to: 255-272

🤖 Prompt for AI Agents
In `@src/services/organizations.ts` around lines 61 - 78, Fix the possessive typo
in the JSDoc comments for getBillingAddress and getPaymentMethod by replacing
"it's" with "its" in the description strings; update the comment for
getBillingAddress (method name: getBillingAddress) from "Get a billing address
using it's ID" to "Get a billing address using its ID" and likewise update the
comment for getPaymentMethod (method name: getPaymentMethod) from "Get an
organization's payment method using it's payment method ID" to "Get an
organization's payment method using its payment method ID".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants