Skip to content

Conversation

abnegate
Copy link
Member

@abnegate abnegate commented Sep 4, 2025

What does this PR do?

(Provide a description of what this PR does.)

Test Plan

(Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work.)

Related PRs and Issues

(If this PR is related to any other PR or resolves any issue or related to any issue link all related PR and issues here.)

Have you read the Contributing Guidelines on issues?

(Write your answer here.)

Summary by CodeRabbit

  • New Features
    • Added Point, Line, and Polygon attribute/column support and new geometry/distance plus createdBetween/updatedBetween query builders.
  • Breaking Changes
    • Credit card enum value renamed to unionPay (now serialized as "unionpay").
  • Documentation
    • New Dart examples for spatial attributes/columns; README installation snippet updated to ^18.0.0 and changelog entry for 18.0.0.
  • Chores
    • SDK bumped to 18.0.0; headers/user-agent and deprecation messages clarified.
  • Tests
    • Added unit tests for new models, queries, and service APIs (some duplicate test blocks included).

Copy link

coderabbitai bot commented Sep 4, 2025

Walkthrough

Bumps SDK version to 18.0.0 (pubspec, client headers, README). Adds geometry models and registers them in models.dart: AttributePoint/Line/Polygon and ColumnPoint/Line/Polygon. Adds Databases create/update attribute wrappers (line/point/polygon, deprecated) and TablesDB create/update column APIs (line/point/polygon) — TablesDB methods are duplicated. Extends Query with createdBetween/updatedBetween plus distance and spatial geometry builders. Enum updates: CreditCard.unionPay, ExecutionMethod.HEAD, IndexType.spatial. Expands Account deprecation annotations. Adds documentation examples and many unit tests (some duplicated).

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The description is merely the repository’s default PR template with placeholder sections and contains no information about the actual changes introduced in this pull request. Please replace the template placeholders with a concise summary of the changes, include a clear test plan, and list any related issues or pull requests to help reviewers understand and verify your work.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title “Add time between queries” accurately describes one aspect of the changeset—namely the new createdBetween and updatedBetween query builders—but it does not convey the broader scope of this release, which also includes geometry query support, SDK version bumps, new models, and extensive documentation examples. Despite being too narrow, it is directly related to a real part of the changes.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e6ff0c and dbecf1e.

📒 Files selected for processing (1)
  • CHANGELOG.md (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • CHANGELOG.md
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev

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: 27

Caution

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

⚠️ Outside diff range comments (1)
lib/services/account.dart (1)

28-31: Fix user-facing typos and phrasing in docs.

These appear in public SDK docs and should be corrected.

- [/account/verfication](https://appwrite.io/docs/...)
+ [/account/verification](https://appwrite.io/docs/...)
- List the factors ... MFA challange.
+ List the factors ... MFA challenge.
- generate and show then immediately after user successfully adds their authehticator.
+ generate and show them immediately after the user successfully adds their authenticator.
- An OTP challenge is required to regenreate recovery codes.
+ An OTP challenge is required to regenerate recovery codes.
- If the provided user ID has not be registered, a new user will be created.
+ If the provided user ID has not been registered, a new user will be created.
- verify the user email ownership. If confirmed this route will return a 200 status code.
+ verify the user phone ownership. If confirmed, this route will return a 200 status code.

Also applies to: 449-452, 533-563, 580-607, 1193-1203, 1304-1307

🧹 Nitpick comments (30)
lib/src/client_io.dart (1)

39-39: Centralize SDK version and user-agent formatting

Replace all hard-coded ‘17.1.0’ literals with the sdkVersion constant and update user-agent construction in both client_io.dart and client_browser.dart. For example:

lib/src/client_io.dart

-import 'package:appwrite/src/client_io.dart';
+import 'package:appwrite/src/version.dart';-      'x-sdk-version': '17.1.0',
+      'x-sdk-version': sdkVersion,-          'AppwriteDartSDK/17.1.0 (${Platform.operatingSystem}; ${Platform.operatingSystemVersion})',
+          'AppwriteDartSDK/$sdkVersion (${Platform.operatingSystem}; ${Platform.operatingSystemVersion})',

lib/src/client_browser.dart

-import 'package:appwrite/src/client_browser.dart';
+import 'package:appwrite/src/version.dart';-      'x-sdk-version': '17.1.0',
+      'x-sdk-version': sdkVersion,

And add lib/src/version.dart if missing:

// lib/src/version.dart
const String sdkVersion = '17.1.0';
lib/src/enums/index_type.dart (1)

6-8: Add spatial index type—looks good; add a quick round-trip test.

Enum wiring and toJson are correct. Consider adding a unit test to guard the serialized value:

test('IndexType.spatial -> "spatial"', () {
  expect(IndexType.spatial.toJson(), 'spatial');
});
lib/src/enums/execution_method.dart (1)

9-11: HEAD/OPTIONS added—serialization OK; verify downstream usage.

Values map to 'OPTIONS' and 'HEAD' via toJson. Please confirm any consumers (e.g., function execution APIs) accept these without additional handling.

Optionally, in a future major release, consider normalizing enum constant casing (currently gET/pOST/…/hEAD) to standard style for readability.

lib/src/models/attribute_polygon.dart (2)

58-70: Omit nulls when serializing.

Dropping nulls keeps payloads tidy and avoids sending explicit nulls downstream.

-  Map<String, dynamic> toMap() {
-    return {
-      "key": key,
-      "type": type,
-      "status": status,
-      "error": error,
-      "required": xrequired,
-      "array": array,
-      "\$createdAt": $createdAt,
-      "\$updatedAt": $updatedAt,
-      "default": xdefault,
-    };
-  }
+  Map<String, dynamic> toMap() {
+    final map = <String, dynamic>{
+      'key': key,
+      'type': type,
+      'status': status,
+      'error': error,
+      'required': xrequired,
+      'array': array,
+      '\$createdAt': $createdAt,
+      '\$updatedAt': $updatedAt,
+      'default': xdefault,
+    };
+    map.removeWhere((_, v) => v == null);
+    return map;
+  }

29-31: Confirm default’s shape.

If polygon defaults are not Map<String, dynamic> (e.g., GeoJSON-like structure), align the model and docs accordingly.

test/src/models/attribute_line_test.dart (1)

20-27: Tighten formatting for readability.

Normalize indent of expectations.

-            expect(result.key, 'fullName');
-                  expect(result.type, 'string');
-                  expect(result.status, 'available');
-                  expect(result.error, 'string');
-                  expect(result.xrequired, true);
-                  expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
-                  expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');
+      expect(result.key, 'fullName');
+      expect(result.type, 'string');
+      expect(result.status, 'available');
+      expect(result.error, 'string');
+      expect(result.xrequired, true);
+      expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
+      expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');
test/src/models/column_point_test.dart (2)

17-19: Add a full-map equality check to catch missed fields/regressions.

       final map = model.toMap();
       final result = ColumnPoint.fromMap(map);
 
+      expect(result.toMap(), equals(map));

20-27: Fix irregular indentation for readability.

-            expect(result.key, 'fullName');
-                  expect(result.type, 'string');
-                  expect(result.status, 'available');
-                  expect(result.error, 'string');
-                  expect(result.xrequired, true);
-                  expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
-                  expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');
+      expect(result.key, 'fullName');
+      expect(result.type, 'string');
+      expect(result.status, 'available');
+      expect(result.error, 'string');
+      expect(result.xrequired, true);
+      expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
+      expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');
test/src/models/attribute_polygon_test.dart (3)

9-9: Use the correct type literal for AttributePolygon.

For clarity and future-proofing, set type to 'polygon' (not 'string').

-        type: 'string',
+        type: 'polygon',

20-26: Fix inconsistent indentation in expectations.

Re-indent for readability and to match surrounding style.

-            expect(result.key, 'fullName');
-                  expect(result.type, 'string');
-                  expect(result.status, 'available');
-                  expect(result.error, 'string');
-                  expect(result.xrequired, true);
-                  expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
-                  expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');
+      expect(result.key, 'fullName');
+      expect(result.type, 'polygon');
+      expect(result.status, 'available');
+      expect(result.error, 'string');
+      expect(result.xrequired, true);
+      expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
+      expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');

17-19: Add a round-trip map equality assertion.

Ensures no fields are lost/renamed during serialization.

       final map = model.toMap();
       final result = AttributePolygon.fromMap(map);
+      expect(result.toMap(), map);
docs/examples/databases/create-point-attribute.md (1)

3-16: Wrap in an async entrypoint to avoid top-level await pitfalls.

Improves copy-paste reliability in most Dart/Flutter setups; also use a non-empty key.

-Client client = Client()
-    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
-    .setProject('<YOUR_PROJECT_ID>') // Your project ID
-    .setKey('<YOUR_API_KEY>'); // Your secret API key
-
-Databases databases = Databases(client);
-
-AttributePoint result = await databases.createPointAttribute(
-    databaseId: '<DATABASE_ID>',
-    collectionId: '<COLLECTION_ID>',
-    key: '',
-    xrequired: false,
-    xdefault: '', // (optional)
-);
+void main() async {
+  final client = Client()
+      .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
+      .setProject('<YOUR_PROJECT_ID>') // Your project ID
+      .setKey('<YOUR_API_KEY>'); // Your secret API key
+
+  final databases = Databases(client);
+
+  final result = await databases.createPointAttribute(
+    databaseId: '<DATABASE_ID>',
+    collectionId: '<COLLECTION_ID>',
+    key: 'location',
+    xrequired: false,
+    // xdefault: <provide a valid Point default or omit>, // (optional)
+  );
+}
test/src/models/column_line_test.dart (3)

9-9: Prefer the matching type literal for ColumnLine.

Use 'line' to reflect the model semantics.

-        type: 'string',
+        type: 'line',

20-26: Normalize indentation and expected values.

Tighten formatting and align with the type change above.

-            expect(result.key, 'fullName');
-                  expect(result.type, 'string');
-                  expect(result.status, 'available');
-                  expect(result.error, 'string');
-                  expect(result.xrequired, true);
-                  expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
-                  expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');
+      expect(result.key, 'fullName');
+      expect(result.type, 'line');
+      expect(result.status, 'available');
+      expect(result.error, 'string');
+      expect(result.xrequired, true);
+      expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
+      expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');

17-19: Add a map round-trip assertion.

Catches accidental field drops or key changes.

       final map = model.toMap();
       final result = ColumnLine.fromMap(map);
+      expect(result.toMap(), map);
docs/examples/tablesdb/create-line-column.md (1)

3-16: Wrap in an async entrypoint and use a meaningful key; reconsider xdefault.

Improves usability and prevents confusion over default value types.

-Client client = Client()
-    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
-    .setProject('<YOUR_PROJECT_ID>') // Your project ID
-    .setKey('<YOUR_API_KEY>'); // Your secret API key
-
-TablesDB tablesDB = TablesDB(client);
-
-ColumnLine result = await tablesDB.createLineColumn(
-    databaseId: '<DATABASE_ID>',
-    tableId: '<TABLE_ID>',
-    key: '',
-    xrequired: false,
-    xdefault: '', // (optional)
-);
+void main() async {
+  final client = Client()
+      .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
+      .setProject('<YOUR_PROJECT_ID>') // Your project ID
+      .setKey('<YOUR_API_KEY>'); // Your secret API key
+
+  final tablesDB = TablesDB(client);
+
+  final result = await tablesDB.createLineColumn(
+    databaseId: '<DATABASE_ID>',
+    tableId: '<TABLE_ID>',
+    key: 'path',
+    xrequired: false,
+    // xdefault: <provide a valid Line default or omit>, // (optional)
+  );
+}
test/src/models/attribute_point_test.dart (3)

9-9: Use the correct type literal for AttributePoint.

Change 'string' to 'point' for semantic accuracy.

-        type: 'string',
+        type: 'point',

20-26: Clean up indentation and align with the type update.

Keeps tests readable and consistent.

-            expect(result.key, 'fullName');
-                  expect(result.type, 'string');
-                  expect(result.status, 'available');
-                  expect(result.error, 'string');
-                  expect(result.xrequired, true);
-                  expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
-                  expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');
+      expect(result.key, 'fullName');
+      expect(result.type, 'point');
+      expect(result.status, 'available');
+      expect(result.error, 'string');
+      expect(result.xrequired, true);
+      expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
+      expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');

17-19: Add a map equality assertion for the round-trip.

Extra guard against serialization drift.

       final map = model.toMap();
       final result = AttributePoint.fromMap(map);
+      expect(result.toMap(), map);
test/src/models/column_polygon_test.dart (1)

20-26: Tidy indentation for readability.

-            expect(result.key, 'fullName');
-                  expect(result.type, 'string');
-                  expect(result.status, 'available');
-                  expect(result.error, 'string');
-                  expect(result.xrequired, true);
-                  expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
-                  expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');
+      expect(result.key, 'fullName');
+      expect(result.type, 'string');
+      expect(result.status, 'available');
+      expect(result.error, 'string');
+      expect(result.xrequired, true);
+      expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
+      expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');
test/services/tables_db_test.dart (1)

668-692: Use realistic geometry types in mocked responses
Replace the six 'type': 'string' entries in your geometry‐column tests with their actual types—line, point, and polygon—to verify correct deserialization and catch regressions.

Apply this focused diff to each pair of create/update mocks:

@@
-                'type': 'string',
+                'type': 'line',
@@
-                'type': 'string',
+                'type': 'line',
@@
-                'type': 'string',
+                'type': 'point',
@@
-                'type': 'string',
+                'type': 'point',
@@
-                'type': 'string',
+                'type': 'polygon',
@@
-                'type': 'string',
+                'type': 'polygon',

Optionally, strengthen your assertions:

-        expect(response, isA<models.ColumnLine>());
+        expect(response, isA<models.ColumnLine>());
+        expect((response as models.ColumnLine).type, 'line');
test/services/databases_test.dart (1)

668-692: Update geometry attribute tests to mock correct type values.

  • In test/services/databases_test.dart, replace every 'type': 'string' in the create/update Line tests with 'type': 'line', in the Point tests with 'type': 'point', and in the Polygon tests with 'type': 'polygon'.
  • (Optional) Add an assertion for the type field, e.g.:
    expect((response as models.AttributeLine).type, 'line');
lib/src/models/column_polygon.dart (2)

14-16: Fix doc grammar (“a column”, not “an column”).

Small doc polish.

-  /// Error message. Displays error generated on failure of creating or deleting an column.
+  /// Error message. Displays error generated on failure of creating or deleting a column.

44-56: Prefer typed casts over implicit dynamics in fromMap.

Avoid .toString() on nullable values and cast booleans explicitly to reduce accidental “null” strings and type drift.

-      key: map['key'].toString(),
-      type: map['type'].toString(),
-      status: map['status'].toString(),
-      error: map['error'].toString(),
-      xrequired: map['required'],
-      array: map['array'],
-      $createdAt: map['\$createdAt'].toString(),
-      $updatedAt: map['\$updatedAt'].toString(),
-      xdefault: map['default'],
+      key: map['key'] as String,
+      type: map['type'] as String,
+      status: map['status'] as String,
+      error: map['error'] as String,
+      xrequired: map['required'] as bool,
+      array: map['array'] as bool?,
+      $createdAt: map['\$createdAt'] as String,
+      $updatedAt: map['\$updatedAt'] as String,
+      xdefault: map['default'] as Map<String, dynamic>?,
lib/src/models/column_line.dart (2)

14-16: Fix doc grammar (“a column”, not “an column”).

Consistency with other docs.

-  /// Error message. Displays error generated on failure of creating or deleting an column.
+  /// Error message. Displays error generated on failure of creating or deleting a column.

44-56: Apply typed casts in fromMap to avoid unintended “null” strings and dynamic leakage.

Matches the pattern suggested for other models.

-      key: map['key'].toString(),
-      type: map['type'].toString(),
-      status: map['status'].toString(),
-      error: map['error'].toString(),
-      xrequired: map['required'],
-      array: map['array'],
-      $createdAt: map['\$createdAt'].toString(),
-      $updatedAt: map['\$updatedAt'].toString(),
-      xdefault: map['default'],
+      key: map['key'] as String,
+      type: map['type'] as String,
+      status: map['status'] as String,
+      error: map['error'] as String,
+      xrequired: map['required'] as bool,
+      array: map['array'] as bool?,
+      $createdAt: map['\$createdAt'] as String,
+      $updatedAt: map['\$updatedAt'] as String,
+      xdefault: map['default'] as Map<String, dynamic>?,
lib/src/models/attribute_point.dart (1)

44-56: Use explicit casts in fromMap for safer deserialization.

Keeps types tight and avoids silent “null”. Mirrors Column* models.

-      key: map['key'].toString(),
-      type: map['type'].toString(),
-      status: map['status'].toString(),
-      error: map['error'].toString(),
-      xrequired: map['required'],
-      array: map['array'],
-      $createdAt: map['\$createdAt'].toString(),
-      $updatedAt: map['\$updatedAt'].toString(),
-      xdefault: map['default'],
+      key: map['key'] as String,
+      type: map['type'] as String,
+      status: map['status'] as String,
+      error: map['error'] as String,
+      xrequired: map['required'] as bool,
+      array: map['array'] as bool?,
+      $createdAt: map['\$createdAt'] as String,
+      $updatedAt: map['\$updatedAt'] as String,
+      xdefault: map['default'] as Map<String, dynamic>?,
lib/src/models/attribute_line.dart (1)

44-56: fromMap: strengthen null-safety and typing for robust parsing

Avoid converting potential nulls to the string "null" and ensure correct types for booleans and maps.

   factory AttributeLine.fromMap(Map<String, dynamic> map) {
     return AttributeLine(
       key: map['key'].toString(),
       type: map['type'].toString(),
       status: map['status'].toString(),
-      error: map['error'].toString(),
-      xrequired: map['required'],
-      array: map['array'],
+      error: map['error']?.toString() ?? '',
+      xrequired: (map['required'] as bool?) ?? false,
+      array: map['array'] as bool?,
       $createdAt: map['\$createdAt'].toString(),
       $updatedAt: map['\$updatedAt'].toString(),
-      xdefault: map['default'],
+      xdefault: map['default'] as Map<String, dynamic>?,
     );
   }
lib/src/models/column_point.dart (2)

14-16: Doc typo: “an column” → “a column”

Minor grammar fix.

-  /// Error message. Displays error generated on failure of creating or deleting an column.
+  /// Error message. Displays error generated on failure of creating or deleting a column.

44-56: fromMap: mirror null-safety and types used elsewhere

Same rationale as AttributeLine.

   factory ColumnPoint.fromMap(Map<String, dynamic> map) {
     return ColumnPoint(
       key: map['key'].toString(),
       type: map['type'].toString(),
       status: map['status'].toString(),
-      error: map['error'].toString(),
-      xrequired: map['required'],
-      array: map['array'],
+      error: map['error']?.toString() ?? '',
+      xrequired: (map['required'] as bool?) ?? false,
+      array: map['array'] as bool?,
       $createdAt: map['\$createdAt'].toString(),
       $updatedAt: map['\$updatedAt'].toString(),
-      xdefault: map['default'],
+      xdefault: map['default'] as Map<String, dynamic>?,
     );
   }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1c63c04 and 2d763a6.

📒 Files selected for processing (39)
  • README.md (1 hunks)
  • docs/examples/databases/create-line-attribute.md (1 hunks)
  • docs/examples/databases/create-point-attribute.md (1 hunks)
  • docs/examples/databases/create-polygon-attribute.md (1 hunks)
  • docs/examples/databases/update-line-attribute.md (1 hunks)
  • docs/examples/databases/update-point-attribute.md (1 hunks)
  • docs/examples/databases/update-polygon-attribute.md (1 hunks)
  • docs/examples/tablesdb/create-line-column.md (1 hunks)
  • docs/examples/tablesdb/create-point-column.md (1 hunks)
  • docs/examples/tablesdb/create-polygon-column.md (1 hunks)
  • docs/examples/tablesdb/update-line-column.md (1 hunks)
  • docs/examples/tablesdb/update-point-column.md (1 hunks)
  • docs/examples/tablesdb/update-polygon-column.md (1 hunks)
  • lib/models.dart (2 hunks)
  • lib/query.dart (2 hunks)
  • lib/services/account.dart (2 hunks)
  • lib/services/databases.dart (2 hunks)
  • lib/services/tables_db.dart (1 hunks)
  • lib/src/client_browser.dart (1 hunks)
  • lib/src/client_io.dart (1 hunks)
  • lib/src/enums/credit_card.dart (1 hunks)
  • lib/src/enums/execution_method.dart (1 hunks)
  • lib/src/enums/index_type.dart (1 hunks)
  • lib/src/models/attribute_line.dart (1 hunks)
  • lib/src/models/attribute_point.dart (1 hunks)
  • lib/src/models/attribute_polygon.dart (1 hunks)
  • lib/src/models/column_line.dart (1 hunks)
  • lib/src/models/column_point.dart (1 hunks)
  • lib/src/models/column_polygon.dart (1 hunks)
  • pubspec.yaml (1 hunks)
  • test/query_test.dart (2 hunks)
  • test/services/databases_test.dart (1 hunks)
  • test/services/tables_db_test.dart (1 hunks)
  • test/src/models/attribute_line_test.dart (1 hunks)
  • test/src/models/attribute_point_test.dart (1 hunks)
  • test/src/models/attribute_polygon_test.dart (1 hunks)
  • test/src/models/column_line_test.dart (1 hunks)
  • test/src/models/column_point_test.dart (1 hunks)
  • test/src/models/column_polygon_test.dart (1 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/examples/tablesdb/create-line-column.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/tablesdb/create-point-column.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/databases/update-line-attribute.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/tablesdb/create-polygon-column.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/databases/create-point-attribute.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/databases/update-point-attribute.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/databases/update-polygon-attribute.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/tablesdb/update-line-column.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/databases/create-line-attribute.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/tablesdb/update-polygon-column.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/databases/create-polygon-attribute.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/tablesdb/update-point-column.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

🔇 Additional comments (23)
README.md (1)

26-26: Installation snippet bumped to ^17.1.0 — LGTM.

pubspec.yaml (1)

2-2: Confirm semver given enum rename.
Changing CreditCard.unionChinaPayunionPay is a source-breaking API change for consumers. Either:

  • keep a deprecated alias for unionChinaPay, or
  • bump to 18.0.0.
lib/src/enums/credit_card.dart (1)

16-16: Provide deprecated alias for renamed enum value
Add a unionChinaPay entry marked @Deprecated before unionPay to avoid compile-time breaks:

-  unionPay(value: 'unionpay'),
+  @Deprecated('Use CreditCard.unionPay; will be removed in v18')
+  unionChinaPay(value: 'unionpay'),
+  unionPay(value: 'unionpay'),

Confirm the server accepts the wire value unionpay (not union-china-pay) in v1.8.x, and verify there are no remaining references to unionChinaPay in tests or documentation.

lib/query.dart (2)

114-117: LGTM: createdBetween builder matches existing query shape.

Null attribute and [start,end] values align with other time-based builders.


126-129: LGTM: updatedBetween builder mirrors createdBetween correctly.

Consistent serialization and docs.

test/query_test.dart (2)

282-287: LGTM: createdBetween test covers method, attribute, and values.


303-308: LGTM: updatedBetween test mirrors createdBetween; good coverage.

lib/services/account.dart (1)

892-894: Deprecation annotation correct: version 1.6.0 and replacement with Account.createSession have been confirmed via Appwrite SDK changelog and API reference.

docs/examples/databases/update-line-attribute.md (1)

4-4: Endpoint template is consistent across docs
All examples use setEndpoint('https://<REGION>.cloud.appwrite.io/v1'), so no changes required.

test/src/models/column_point_test.dart (2)

4-19: Solid round-trip test structure.

Creating → toMap → fromMap → field assertions is appropriate here.


7-15: Keep type: 'string' – ColumnPoint does not constrain the type value.

docs/examples/databases/update-point-attribute.md (1)

10-16: Doc parameter names align with the updatePointAttribute signature; no changes needed.

docs/examples/databases/create-line-attribute.md (1)

14-15: xdefault is supported for line attributes – the createLineAttribute method signature includes String? xdefault and maps it to the payload’s default field, so leaving it in the example is correct.

docs/examples/tablesdb/update-point-column.md (1)

8-16: No changes needed
The updatePointColumn method name and its named parameters in docs match the SDK implementation.

docs/examples/databases/create-point-attribute.md (1)

15-15: Confirm the shape/type of xdefault for Point.

Doc may mislead if an empty string is invalid for geospatial defaults. Consider omitting or providing a correctly typed example value.

docs/examples/tablesdb/create-line-column.md (1)

15-15: Validate the expected xdefault format for Line.

If a geometry default isn't a string, remove this line or replace with a correct example.

docs/examples/databases/create-polygon-attribute.md (1)

13-15: Maintain empty‐string placeholders for key and xdefault.
Using '' as a placeholder for required (key) and optional (xdefault) fields matches the pattern in other docs examples and need not be removed or replaced.

Likely an incorrect or invalid review comment.

test/src/models/column_polygon_test.dart (2)

17-19: LGTM: round‑trip toMap/fromMap covered.


9-12: Retain type: 'string' for ColumnPolygon. It matches ColumnPoint and ColumnLine tests and model mappings, so no update is required.

lib/src/models/attribute_line.dart (1)

3-31: Model shape and serialization look consistent with existing patterns

Fields, constructor, toMap keys (including $-prefixed) align with the SDK’s conventions.

lib/src/models/column_point.dart (1)

3-31: LGTM overall

Structure and toMap keys are consistent with the rest of the SDK.

lib/services/databases.dart (2)

39-40: Deprecation message correction looks good

Directing to TablesDB.create is consistent with the rest of the deprecations.


912-947: Line attribute update: optional xdefault will clear default unintentionally

Make xdefault required (nullable) and typed as Map to mirror other update* methods and prevent accidental null being sent.

   Future<models.AttributeLine> updateLineAttribute({
@@
-    String? xdefault,
+    required Map<String, dynamic>? xdefault,

Likely an incorrect or invalid review comment.

Comment on lines 894 to 926
/// Update a point column. Changing the `default` value will not update already
/// existing documents.
Future<models.ColumnPoint> updatePointColumn({
required String databaseId,
required String tableId,
required String key,
required bool xrequired,
String? xdefault,
String? newKey,
}) async {
final String apiPath =
'/tablesdb/{databaseId}/tables/{tableId}/columns/point/{key}'
.replaceAll('{databaseId}', databaseId)
.replaceAll('{tableId}', tableId)
.replaceAll('{key}', key);

final Map<String, dynamic> apiParams = {
'required': xrequired,
'default': xdefault,
'newKey': newKey,
};

final Map<String, String> apiHeaders = {'content-type': 'application/json'};

final res = await client.call(
HttpMethod.patch,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);

return models.ColumnPoint.fromMap(res.data);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Point update: avoid silent default reset; require nullable Map

Match update signature pattern used elsewhere and prevent unintended clears.

-  /// Update a point column. Changing the `default` value will not update already
-  /// existing documents.
+  /// Update a point column. Changing the `default` value will not update already
+  /// existing rows.
   Future<models.ColumnPoint> updatePointColumn({
@@
-    String? xdefault,
+    required Map<String, dynamic>? xdefault,
📝 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
/// Update a point column. Changing the `default` value will not update already
/// existing documents.
Future<models.ColumnPoint> updatePointColumn({
required String databaseId,
required String tableId,
required String key,
required bool xrequired,
String? xdefault,
String? newKey,
}) async {
final String apiPath =
'/tablesdb/{databaseId}/tables/{tableId}/columns/point/{key}'
.replaceAll('{databaseId}', databaseId)
.replaceAll('{tableId}', tableId)
.replaceAll('{key}', key);
final Map<String, dynamic> apiParams = {
'required': xrequired,
'default': xdefault,
'newKey': newKey,
};
final Map<String, String> apiHeaders = {'content-type': 'application/json'};
final res = await client.call(
HttpMethod.patch,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return models.ColumnPoint.fromMap(res.data);
}
/// Update a point column. Changing the `default` value will not update already
/// existing rows.
Future<models.ColumnPoint> updatePointColumn({
required String databaseId,
required String tableId,
required String key,
required bool xrequired,
required Map<String, dynamic>? xdefault,
String? newKey,
}) async {
final String apiPath =
'/tablesdb/{databaseId}/tables/{tableId}/columns/point/{key}'
.replaceAll('{databaseId}', databaseId)
.replaceAll('{tableId}', tableId)
.replaceAll('{key}', key);
final Map<String, dynamic> apiParams = {
'required': xrequired,
'default': xdefault,
'newKey': newKey,
};
final Map<String, String> apiHeaders = {'content-type': 'application/json'};
final res = await client.call(
HttpMethod.patch,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return models.ColumnPoint.fromMap(res.data);
}
🤖 Prompt for AI Agents
In lib/services/tables_db.dart around lines 894–926, the updatePointColumn
method currently accepts xdefault as String? which can silently reset defaults;
change xdefault to Map<String, dynamic>? to match other update signatures, and
only include the 'default' entry in apiParams when xdefault is non-null (i.e.,
build apiParams conditionally) so omitting the parameter does not clear the
existing default; update the method signature and any callers accordingly.

Comment on lines 959 to 991
/// Update a polygon column. Changing the `default` value will not update
/// already existing documents.
Future<models.ColumnPolygon> updatePolygonColumn({
required String databaseId,
required String tableId,
required String key,
required bool xrequired,
String? xdefault,
String? newKey,
}) async {
final String apiPath =
'/tablesdb/{databaseId}/tables/{tableId}/columns/polygon/{key}'
.replaceAll('{databaseId}', databaseId)
.replaceAll('{tableId}', tableId)
.replaceAll('{key}', key);

final Map<String, dynamic> apiParams = {
'required': xrequired,
'default': xdefault,
'newKey': newKey,
};

final Map<String, String> apiHeaders = {'content-type': 'application/json'};

final res = await client.call(
HttpMethod.patch,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);

return models.ColumnPolygon.fromMap(res.data);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Polygon update: required nullable Map to prevent unintended default clearing

Also update wording to “rows”.

-  /// Update a polygon column. Changing the `default` value will not update
-  /// already existing documents.
+  /// Update a polygon column. Changing the `default` value will not update
+  /// already existing rows.
   Future<models.ColumnPolygon> updatePolygonColumn({
@@
-    String? xdefault,
+    required Map<String, dynamic>? xdefault,
🤖 Prompt for AI Agents
In lib/services/tables_db.dart around lines 959 to 991, the updatePolygonColumn
currently always sends all keys (including required) which can unintentionally
clear existing defaults; make xrequired a nullable bool (bool?) and build
apiParams so you only add entries for fields that are non-null (i.e.,
conditionally add 'required', 'default', and 'newKey' to the map) so patch
requests don't overwrite omitted values, and also change the method doc comment
wording from "documents" to "rows".

Comment on lines 44 to 56
factory AttributePolygon.fromMap(Map<String, dynamic> map) {
return AttributePolygon(
key: map['key'].toString(),
type: map['type'].toString(),
status: map['status'].toString(),
error: map['error'].toString(),
xrequired: map['required'],
array: map['array'],
$createdAt: map['\$createdAt'].toString(),
$updatedAt: map['\$updatedAt'].toString(),
xdefault: map['default'],
);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Make fromMap type-safe and null-aware (avoid "null" strings and bad casts).

Casting directly prevents accidental "null" strings and runtime type issues.

   factory AttributePolygon.fromMap(Map<String, dynamic> map) {
     return AttributePolygon(
-      key: map['key'].toString(),
-      type: map['type'].toString(),
-      status: map['status'].toString(),
-      error: map['error'].toString(),
-      xrequired: map['required'],
-      array: map['array'],
-      $createdAt: map['\$createdAt'].toString(),
-      $updatedAt: map['\$updatedAt'].toString(),
-      xdefault: map['default'],
+      key: map['key'] as String,
+      type: map['type'] as String,
+      status: map['status'] as String,
+      error: (map['error'] as String?) ?? '',
+      xrequired: map['required'] as bool,
+      array: map['array'] as bool?,
+      $createdAt: map['\$createdAt'] as String,
+      $updatedAt: map['\$updatedAt'] as String,
+      xdefault: (map['default'] as Map?)?.cast<String, dynamic>(),
     );
   }
📝 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
factory AttributePolygon.fromMap(Map<String, dynamic> map) {
return AttributePolygon(
key: map['key'].toString(),
type: map['type'].toString(),
status: map['status'].toString(),
error: map['error'].toString(),
xrequired: map['required'],
array: map['array'],
$createdAt: map['\$createdAt'].toString(),
$updatedAt: map['\$updatedAt'].toString(),
xdefault: map['default'],
);
}
factory AttributePolygon.fromMap(Map<String, dynamic> map) {
return AttributePolygon(
key: map['key'] as String,
type: map['type'] as String,
status: map['status'] as String,
error: (map['error'] as String?) ?? '',
xrequired: map['required'] as bool,
array: map['array'] as bool?,
$createdAt: map['\$createdAt'] as String,
$updatedAt: map['\$updatedAt'] as String,
xdefault: (map['default'] as Map?)?.cast<String, dynamic>(),
);
}
🤖 Prompt for AI Agents
In lib/src/models/attribute_polygon.dart around lines 44 to 56, the
factory.fromMap currently casts map values with toString() and direct access
which can produce the literal "null" string and unsafe casts; update it to be
null-aware and type-safe by: read each key with null checks (e.g., key:
map['key'] != null ? map['key'].toString() : null or a sensible default
according to the model), cast booleans and numbers using safe as T? (e.g.,
map['required'] as bool? or parse int/double only when non-null), and access the
special keys '$createdAt' and '$updatedAt' via map['\$createdAt'] and
map['\$updatedAt'] with the same null-aware pattern; ensure no value calls
toString() on null and use nullable types or defaults consistent with the
AttributePolygon constructor signature.

@stnguyen90 stnguyen90 self-requested a review September 5, 2025 01:26
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: 0

🧹 Nitpick comments (3)
lib/query.dart (3)

114-116: Doc: specify timestamp format and timezone

Add a brief note that start/end must be ISO‑8601 UTC strings (e.g., 2025-09-04T13:36:29Z) to avoid ambiguity. Optionally provide a convenience that accepts DateTime and calls toUtc().toIso8601String().


178-225: Reduce duplication in distance builders; clarify args and verify server order*

All four builders share the same structure. Factor to a private helper and keep docs concise. Also, please confirm the backend expects the values array ordered as [coordinatesOrGeometry, distance, meters].

Apply within this range:

-  static String distanceEqual(
+  static String distanceEqual(
     String attribute,
     List<dynamic> values,
     double distance, [
     bool meters = true,
-  ]) => Query._('distanceEqual', attribute, [
-    values,
-    distance,
-    meters,
-  ]).toString();
+  ]) => _distance('distanceEqual', attribute, values, distance, meters);
 
-  static String distanceNotEqual(
+  static String distanceNotEqual(
     String attribute,
     List<dynamic> values,
     double distance, [
     bool meters = true,
-  ]) => Query._('distanceNotEqual', attribute, [
-    values,
-    distance,
-    meters,
-  ]).toString();
+  ]) => _distance('distanceNotEqual', attribute, values, distance, meters);
 
-  static String distanceGreaterThan(
+  static String distanceGreaterThan(
     String attribute,
     List<dynamic> values,
     double distance, [
     bool meters = true,
-  ]) => Query._('distanceGreaterThan', attribute, [
-    values,
-    distance,
-    meters,
-  ]).toString();
+  ]) => _distance('distanceGreaterThan', attribute, values, distance, meters);
 
-  static String distanceLessThan(
+  static String distanceLessThan(
     String attribute,
     List<dynamic> values,
     double distance, [
     bool meters = true,
-  ]) => Query._('distanceLessThan', attribute, [
-    values,
-    distance,
-    meters,
-  ]).toString();
+  ]) => _distance('distanceLessThan', attribute, values, distance, meters);

Add helper inside class (outside this hunk):

static String _distance(
  String method,
  String attribute,
  List<dynamic> values,
  double distance, [
  bool meters = true,
]) => Query._(method, attribute, [values, distance, meters]).toString();

Tests: I can add unit tests covering each distance* method’s JSON shape if helpful.


226-256: Collapse geometry predicate boilerplate; name/Docs

Use a helper to remove repetition and consider clarifying the expected geometry format (e.g., GeoJSON-like object or coordinate arrays). If possible, rename parameter to geometry for readability (backwards-compat safe only if this is a new API).

Apply within this range:

-  static String intersects(String attribute, List<dynamic> values) =>
-      Query._('intersects', attribute, values).toString();
+  static String intersects(String attribute, List<dynamic> values) =>
+      _geom('intersects', attribute, values);
 
-  static String notIntersects(String attribute, List<dynamic> values) =>
-      Query._('notIntersects', attribute, values).toString();
+  static String notIntersects(String attribute, List<dynamic> values) =>
+      _geom('notIntersects', attribute, values);
 
-  static String crosses(String attribute, List<dynamic> values) =>
-      Query._('crosses', attribute, values).toString();
+  static String crosses(String attribute, List<dynamic> values) =>
+      _geom('crosses', attribute, values);
 
-  static String notCrosses(String attribute, List<dynamic> values) =>
-      Query._('notCrosses', attribute, values).toString();
+  static String notCrosses(String attribute, List<dynamic> values) =>
+      _geom('notCrosses', attribute, values);
 
-  static String overlaps(String attribute, List<dynamic> values) =>
-      Query._('overlaps', attribute, values).toString();
+  static String overlaps(String attribute, List<dynamic> values) =>
+      _geom('overlaps', attribute, values);
 
-  static String notOverlaps(String attribute, List<dynamic> values) =>
-      Query._('notOverlaps', attribute, values).toString();
+  static String notOverlaps(String attribute, List<dynamic> values) =>
+      _geom('notOverlaps', attribute, values);
 
-  static String touches(String attribute, List<dynamic> values) =>
-      Query._('touches', attribute, values).toString();
+  static String touches(String attribute, List<dynamic> values) =>
+      _geom('touches', attribute, values);
 
-  static String notTouches(String attribute, List<dynamic> values) =>
-      Query._('notTouches', attribute, values).toString();
+  static String notTouches(String attribute, List<dynamic> values) =>
+      _geom('notTouches', attribute, values);

Add helper inside class (outside this hunk):

static String _geom(String method, String attribute, List<dynamic> values) =>
    Query._(method, attribute, values).toString();

I can also add tests asserting method names and values pass-through for each predicate.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c92a2fb and 56804f8.

📒 Files selected for processing (1)
  • lib/query.dart (3 hunks)
🔇 Additional comments (1)
lib/query.dart (1)

126-128: LGTM: updatedBetween matches existing time filters

Constructor usage and payload shape are consistent with createdBefore/After and between().

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

♻️ Duplicate comments (11)
docs/examples/databases/update-polygon-attribute.md (1)

13-16: Fix placeholders and xdefault shape.

Use a real key, only include newKey when renaming, and ensure polygon defaults are nested rings (or omit).

docs/examples/databases/update-point-attribute.md (1)

3-17: Make it runnable: async main, non-empty key, correct point default.

Also print the result for a complete example.

-Client client = Client()
-    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
-    .setProject('<YOUR_PROJECT_ID>') // Your project ID
-    .setKey('<YOUR_API_KEY>'); // Your secret API key
-
-Databases databases = Databases(client);
-
-AttributePoint result = await databases.updatePointAttribute(
-    databaseId: '<DATABASE_ID>',
-    collectionId: '<COLLECTION_ID>',
-    key: '',
-    xrequired: false,
-    xdefault: [[1,2], [3, 4]], // (optional)
-    newKey: '', // (optional)
-);
+Future<void> main() async {
+  final client = Client()
+    ..setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
+    ..setProject('<YOUR_PROJECT_ID>') // Your project ID
+    ..setKey('<YOUR_API_KEY>'); // Your secret API key
+
+  final databases = Databases(client);
+
+  final AttributePoint result = await databases.updatePointAttribute(
+    databaseId: '<DATABASE_ID>',
+    collectionId: '<COLLECTION_ID>',
+    key: '<ATTRIBUTE_KEY>',
+    xrequired: false,
+    // xdefault: [1.0, 2.0], // (optional) [x,y]
+    // newKey: '<NEW_KEY>', // (optional)
+  );
+
+  print(result.toMap());
+}
docs/examples/databases/update-line-attribute.md (1)

1-18: Skipping comments on .md code per maintainer request

Acknowledging prior guidance to avoid code comments in .md files.

docs/examples/databases/create-line-attribute.md (1)

1-17: Skipping comments on .md code per maintainer request

Acknowledging prior guidance to avoid code comments in .md files.

lib/src/models/attribute_polygon.dart (1)

44-55: Make fromMap type-safe; avoid toString() on null and preserve nulls.

Direct .toString() can turn nulls into the string "null", and uncasted dynamics can throw at runtime. Use typed casts and safe defaults.

   factory AttributePolygon.fromMap(Map<String, dynamic> map) {
     return AttributePolygon(
-      key: map['key'].toString(),
-      type: map['type'].toString(),
-      status: map['status'].toString(),
-      error: map['error'].toString(),
-      xrequired: map['required'],
-      array: map['array'],
-      $createdAt: map['\$createdAt'].toString(),
-      $updatedAt: map['\$updatedAt'].toString(),
-      xdefault: List.from(map['default'] ?? []),
+      key: map['key'] as String,
+      type: map['type'] as String,
+      status: map['status'] as String,
+      error: (map['error'] as String?) ?? '',
+      xrequired: map['required'] as bool,
+      array: map['array'] as bool?,
+      $createdAt: map[r'$createdAt'] as String,
+      $updatedAt: map[r'$updatedAt'] as String,
+      xdefault: map['default'] as List?,
     );
   }
docs/examples/databases/create-polygon-attribute.md (1)

1-16: Wrap in async main; use valid placeholders; avoid misleading defaults.

Top‑level await and empty keys make the snippet non-runnable and confusing. Wrap in Future<void> main() async, provide a non-empty key, and omit xdefault unless you have a valid polygon default.

-import 'package:dart_appwrite/dart_appwrite.dart';
-
-Client client = Client()
-    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
-    .setProject('<YOUR_PROJECT_ID>') // Your project ID
-    .setKey('<YOUR_API_KEY>'); // Your secret API key
-
-Databases databases = Databases(client);
-
-AttributePolygon result = await databases.createPolygonAttribute(
-    databaseId: '<DATABASE_ID>',
-    collectionId: '<COLLECTION_ID>',
-    key: '',
-    xrequired: false,
-    xdefault: [[1,2], [3, 4]], // (optional)
-);
+import 'package:dart_appwrite/dart_appwrite.dart';
+
+Future<void> main() async {
+  final client = Client()
+    ..setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
+    ..setProject('<YOUR_PROJECT_ID>') // Your project ID
+    ..setKey('<YOUR_API_KEY>'); // Your secret API key
+
+  final databases = Databases(client);
+
+  final AttributePolygon result = await databases.createPolygonAttribute(
+    databaseId: '<DATABASE_ID>',
+    collectionId: '<COLLECTION_ID>',
+    key: '<ATTRIBUTE_KEY>',
+    xrequired: false,
+    // xdefault: <VALID_POLYGON_DEFAULT>, // (optional)
+  );
+  print(result.toMap());
+}
docs/examples/tablesdb/update-polygon-column.md (1)

1-17: Make the example runnable and realistic (async main, valid keys, optional params).

Use an async entrypoint, provide a non-empty key, and omit optional params unless demonstrating them with valid values.

-import 'package:dart_appwrite/dart_appwrite.dart';
-
-Client client = Client()
-    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
-    .setProject('<YOUR_PROJECT_ID>') // Your project ID
-    .setKey('<YOUR_API_KEY>'); // Your secret API key
-
-TablesDB tablesDB = TablesDB(client);
-
-ColumnPolygon result = await tablesDB.updatePolygonColumn(
-    databaseId: '<DATABASE_ID>',
-    tableId: '<TABLE_ID>',
-    key: '',
-    xrequired: false,
-    xdefault: [[1,2], [3, 4]], // (optional)
-    newKey: '', // (optional)
-);
+import 'package:dart_appwrite/dart_appwrite.dart';
+
+Future<void> main() async {
+  final client = Client()
+    ..setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
+    ..setProject('<YOUR_PROJECT_ID>') // Your project ID
+    ..setKey('<YOUR_API_KEY>'); // Your secret API key
+
+  final tablesDB = TablesDB(client);
+
+  final ColumnPolygon result = await tablesDB.updatePolygonColumn(
+    databaseId: '<DATABASE_ID>',
+    tableId: '<TABLE_ID>',
+    key: '<COLUMN_KEY>',
+    xrequired: false,
+    // xdefault: <VALID_POLYGON_DEFAULT>, // (optional)
+    // newKey: '<NEW_KEY>', // (optional)
+  );
+  print(result.toMap());
+}
docs/examples/tablesdb/update-point-column.md (1)

1-17: Use async main; replace empty key; avoid ambiguous defaults.

Ensure the snippet compiles and avoids invalid placeholder values; only include xdefault/newKey when valid.

-import 'package:dart_appwrite/dart_appwrite.dart';
-
-Client client = Client()
-    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
-    .setProject('<YOUR_PROJECT_ID>') // Your project ID
-    .setKey('<YOUR_API_KEY>'); // Your secret API key
-
-TablesDB tablesDB = TablesDB(client);
-
-ColumnPoint result = await tablesDB.updatePointColumn(
-    databaseId: '<DATABASE_ID>',
-    tableId: '<TABLE_ID>',
-    key: '',
-    xrequired: false,
-    xdefault: [[1,2], [3, 4]], // (optional)
-    newKey: '', // (optional)
-);
+import 'package:dart_appwrite/dart_appwrite.dart';
+
+Future<void> main() async {
+  final client = Client()
+    ..setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
+    ..setProject('<YOUR_PROJECT_ID>') // Your project ID
+    ..setKey('<YOUR_API_KEY>'); // Your secret API key
+
+  final tablesDB = TablesDB(client);
+
+  final ColumnPoint result = await tablesDB.updatePointColumn(
+    databaseId: '<DATABASE_ID>',
+    tableId: '<TABLE_ID>',
+    key: '<COLUMN_KEY>',
+    xrequired: false,
+    // xdefault: <VALID_POINT_DEFAULT>, // (optional)
+    // newKey: '<NEW_KEY>', // (optional)
+  );
+  print(result.toMap());
+}
docs/examples/tablesdb/create-polygon-column.md (1)

3-16: Wrap in async main(), avoid empty-string placeholders, and fix/omit invalid xdefault.

Top-level await won’t run in many contexts; key: '' is misleading; xdefault here isn’t a list of pairs. Make the sample executable and typed.

-Client client = Client()
-    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
-    .setProject('<YOUR_PROJECT_ID>') // Your project ID
-    .setKey('<YOUR_API_KEY>'); // Your secret API key
-
-TablesDB tablesDB = TablesDB(client);
-
-ColumnPolygon result = await tablesDB.createPolygonColumn(
-    databaseId: '<DATABASE_ID>',
-    tableId: '<TABLE_ID>',
-    key: '',
-    xrequired: false,
-    xdefault: [[1,2], [3, 4]], // (optional)
-);
+Future<void> main() async {
+  final client = Client()
+      .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
+      .setProject('<YOUR_PROJECT_ID>') // Your project ID
+      .setKey('<YOUR_API_KEY>'); // Your secret API key
+
+  final tablesDB = TablesDB(client);
+
+  final ColumnPolygon result = await tablesDB.createPolygonColumn(
+    databaseId: '<DATABASE_ID>',
+    tableId: '<TABLE_ID>',
+    key: '<COLUMN_KEY>',
+    xrequired: false,
+    // xdefault: { // (optional) GeoJSON example
+    //   "type": "Polygon",
+    //   "coordinates": [
+    //     [[<LON>, <LAT>], [<LON>, <LAT>], [<LON>, <LAT>], [<LON>, <LAT>]] // closed ring
+    //   ]
+    // },
+  );
+  print(result);
+}
docs/examples/tablesdb/update-line-column.md (1)

3-17: Make the example runnable; remove empty-string placeholders; only show optional params with valid values.

Move calls into main(), replace key: '', and don’t pass empty xdefault/newKey. Provide commented, typed examples.

-Client client = Client()
-    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
-    .setProject('<YOUR_PROJECT_ID>') // Your project ID
-    .setKey('<YOUR_API_KEY>'); // Your secret API key
-
-TablesDB tablesDB = TablesDB(client);
-
-ColumnLine result = await tablesDB.updateLineColumn(
-    databaseId: '<DATABASE_ID>',
-    tableId: '<TABLE_ID>',
-    key: '',
-    xrequired: false,
-    xdefault: [[1,2], [3, 4]], // (optional)
-    newKey: '', // (optional)
-);
+Future<void> main() async {
+  final client = Client()
+      .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
+      .setProject('<YOUR_PROJECT_ID>') // Your project ID
+      .setKey('<YOUR_API_KEY>'); // Your secret API key
+
+  final tablesDB = TablesDB(client);
+
+  final ColumnLine result = await tablesDB.updateLineColumn(
+    databaseId: '<DATABASE_ID>',
+    tableId: '<TABLE_ID>',
+    key: '<COLUMN_KEY>',
+    xrequired: false,
+    // xdefault: { // (optional) GeoJSON example
+    //   "type": "LineString",
+    //   "coordinates": [[<LON>, <LAT>], [<LON>, <LAT>]]
+    // },
+    // newKey: '<NEW_KEY>', // (optional)
+  );
+  print(result);
+}
docs/examples/tablesdb/create-point-column.md (1)

3-16: Use async main(), avoid key: '', and don’t show an invalid default.

Point defaults must be valid geometry; an array of pairs isn’t a Point. Show a correct example or omit.

-Client client = Client()
-    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
-    .setProject('<YOUR_PROJECT_ID>') // Your project ID
-    .setKey('<YOUR_API_KEY>'); // Your secret API key
-
-TablesDB tablesDB = TablesDB(client);
-
-ColumnPoint result = await tablesDB.createPointColumn(
-    databaseId: '<DATABASE_ID>',
-    tableId: '<TABLE_ID>',
-    key: '',
-    xrequired: false,
-    xdefault: [[1,2], [3, 4]], // (optional)
-);
+Future<void> main() async {
+  final client = Client()
+      .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
+      .setProject('<YOUR_PROJECT_ID>') // Your project ID
+      .setKey('<YOUR_API_KEY>'); // Your secret API key
+
+  final tablesDB = TablesDB(client);
+
+  final ColumnPoint result = await tablesDB.createPointColumn(
+    databaseId: '<DATABASE_ID>',
+    tableId: '<TABLE_ID>',
+    key: '<COLUMN_KEY>',
+    xrequired: false,
+    // xdefault: { "type": "Point", "coordinates": [<LON>, <LAT>] }, // (optional)
+    // or: xdefault: 'POINT(<LON> <LAT>)',
+  );
+  print(result);
+}
🧹 Nitpick comments (15)
lib/src/models/attribute_point.dart (1)

52-53: Avoid .toString() turning nulls into 'null'.

Cast to String to match the API contract; these fields should always be present.

lib/src/models/column_point.dart (1)

14-15: Grammar nit: “a column”, not “an column”.

-  /// Error message. Displays error generated on failure of creating or deleting an column.
+  /// Error message. Displays error generated on failure of creating or deleting a column.
lib/src/models/attribute_line.dart (3)

44-56: Harden fromMap: avoid 'null' strings and assert/cast to expected types

Use typed casts and sensible fallbacks to prevent "null" strings and runtime null issues.

   factory AttributeLine.fromMap(Map<String, dynamic> map) {
     return AttributeLine(
-      key: map['key'].toString(),
-      type: map['type'].toString(),
-      status: map['status'].toString(),
-      error: map['error'].toString(),
-      xrequired: map['required'],
-      array: map['array'],
-      $createdAt: map['\$createdAt'].toString(),
-      $updatedAt: map['\$updatedAt'].toString(),
-      xdefault: List.from(map['default'] ?? []),
+      key: map['key'] as String,
+      type: map['type'] as String,
+      status: map['status'] as String,
+      error: (map['error'] as String?) ?? '',
+      xrequired: (map['required'] as bool?) ?? false,
+      array: map['array'] as bool?,
+      $createdAt: map['\$createdAt'] as String,
+      $updatedAt: map['\$updatedAt'] as String,
+      xdefault: map['default'] is List ? List.from(map['default'] as List) : null,
     );
   }

29-31: Clarify xdefault typing

Prefer List? to document heterogenous list content and align with SDK style.

-  final List? xdefault;
+  final List<dynamic>? xdefault;

58-70: Only serialize non-null optionals

Slightly cleaner maps and closer to wire payloads by omitting nulls.

   Map<String, dynamic> toMap() {
     return {
       "key": key,
       "type": type,
       "status": status,
       "error": error,
       "required": xrequired,
-      "array": array,
+      if (array != null) "array": array,
       "\$createdAt": $createdAt,
       "\$updatedAt": $updatedAt,
-      "default": xdefault,
+      if (xdefault != null) "default": xdefault,
     };
   }
lib/src/models/column_polygon.dart (4)

14-16: Grammar: “a column”

Fix article in the doc comment.

-  /// Error message. Displays error generated on failure of creating or deleting an column.
+  /// Error message. Displays error generated on failure of creating or deleting a column.

44-56: Type-safe parsing and null handling in fromMap

Mirror the safer casts/fallbacks used elsewhere to avoid "null" strings and runtime nulls.

   factory ColumnPolygon.fromMap(Map<String, dynamic> map) {
     return ColumnPolygon(
-      key: map['key'].toString(),
-      type: map['type'].toString(),
-      status: map['status'].toString(),
-      error: map['error'].toString(),
-      xrequired: map['required'],
-      array: map['array'],
-      $createdAt: map['\$createdAt'].toString(),
-      $updatedAt: map['\$updatedAt'].toString(),
-      xdefault: List.from(map['default'] ?? []),
+      key: map['key'] as String,
+      type: map['type'] as String,
+      status: map['status'] as String,
+      error: (map['error'] as String?) ?? '',
+      xrequired: (map['required'] as bool?) ?? false,
+      array: map['array'] as bool?,
+      $createdAt: map['\$createdAt'] as String,
+      $updatedAt: map['\$updatedAt'] as String,
+      xdefault: map['default'] is List ? List.from(map['default'] as List) : null,
     );
   }

29-31: Prefer List? for xdefault

Documents intent and avoids raw List.

-  final List? xdefault;
+  final List<dynamic>? xdefault;

58-70: Omit null optionals in toMap

Keep payload minimal.

     return {
       "key": key,
       "type": type,
       "status": status,
       "error": error,
       "required": xrequired,
-      "array": array,
+      if (array != null) "array": array,
       "\$createdAt": $createdAt,
       "\$updatedAt": $updatedAt,
-      "default": xdefault,
+      if (xdefault != null) "default": xdefault,
     };
lib/src/models/column_line.dart (4)

14-16: Grammar: “a column”

Fix article in the doc comment.

-  /// Error message. Displays error generated on failure of creating or deleting an column.
+  /// Error message. Displays error generated on failure of creating or deleting a column.

44-56: fromMap: cast explicitly and handle nulls cleanly

Avoid "null" strings and dynamic-to-non-nullable pitfalls.

   factory ColumnLine.fromMap(Map<String, dynamic> map) {
     return ColumnLine(
-      key: map['key'].toString(),
-      type: map['type'].toString(),
-      status: map['status'].toString(),
-      error: map['error'].toString(),
-      xrequired: map['required'],
-      array: map['array'],
-      $createdAt: map['\$createdAt'].toString(),
-      $updatedAt: map['\$updatedAt'].toString(),
-      xdefault: List.from(map['default'] ?? []),
+      key: map['key'] as String,
+      type: map['type'] as String,
+      status: map['status'] as String,
+      error: (map['error'] as String?) ?? '',
+      xrequired: (map['required'] as bool?) ?? false,
+      array: map['array'] as bool?,
+      $createdAt: map['\$createdAt'] as String,
+      $updatedAt: map['\$updatedAt'] as String,
+      xdefault: map['default'] is List ? List.from(map['default'] as List) : null,
     );
   }

29-31: Prefer List? for xdefault

Consistent with dynamic geometry payloads.

-  final List? xdefault;
+  final List<dynamic>? xdefault;

58-70: Skip nulls in toMap

Reduces noise in serialized output.

     return {
       "key": key,
       "type": type,
       "status": status,
       "error": error,
       "required": xrequired,
-      "array": array,
+      if (array != null) "array": array,
       "\$createdAt": $createdAt,
       "\$updatedAt": $updatedAt,
-      "default": xdefault,
+      if (xdefault != null) "default": xdefault,
     };
lib/src/models/attribute_polygon.dart (2)

58-70: Don’t emit nulls in toMap; keep wire format stable.

Avoid sending null-valued keys; also prefer raw-string keys for $-prefixed fields for clarity.

-  Map<String, dynamic> toMap() {
-    return {
-      "key": key,
-      "type": type,
-      "status": status,
-      "error": error,
-      "required": xrequired,
-      "array": array,
-      "\$createdAt": $createdAt,
-      "\$updatedAt": $updatedAt,
-      "default": xdefault,
-    };
-  }
+  Map<String, dynamic> toMap() {
+    final map = <String, dynamic>{
+      'key': key,
+      'type': type,
+      'status': status,
+      'error': error,
+      'required': xrequired,
+      r'$createdAt': $createdAt,
+      r'$updatedAt': $updatedAt,
+    };
+    if (array != null) map['array'] = array;
+    if (xdefault != null) map['default'] = xdefault;
+    return map;
+  }

29-31: Consider typing xdefault to the expected geometry.

If the API expects polygon coordinates, type this as List<List<List<num>>>? (or a dedicated value object) to catch shape errors at compile time. Otherwise keep List? for backward compatibility.

-  final List? xdefault;
+  // Consider: List<List<List<num>>>? for polygon rings or a specific model type.
+  final List? xdefault;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 38ef71c and b10e61b.

📒 Files selected for processing (23)
  • docs/examples/account/update-prefs.md (1 hunks)
  • docs/examples/databases/create-document.md (1 hunks)
  • docs/examples/databases/create-line-attribute.md (1 hunks)
  • docs/examples/databases/create-point-attribute.md (1 hunks)
  • docs/examples/databases/create-polygon-attribute.md (1 hunks)
  • docs/examples/databases/update-line-attribute.md (1 hunks)
  • docs/examples/databases/update-point-attribute.md (1 hunks)
  • docs/examples/databases/update-polygon-attribute.md (1 hunks)
  • docs/examples/tablesdb/create-line-column.md (1 hunks)
  • docs/examples/tablesdb/create-point-column.md (1 hunks)
  • docs/examples/tablesdb/create-polygon-column.md (1 hunks)
  • docs/examples/tablesdb/create-row.md (1 hunks)
  • docs/examples/tablesdb/update-line-column.md (1 hunks)
  • docs/examples/tablesdb/update-point-column.md (1 hunks)
  • docs/examples/tablesdb/update-polygon-column.md (1 hunks)
  • lib/services/databases.dart (2 hunks)
  • lib/services/tables_db.dart (1 hunks)
  • lib/src/models/attribute_line.dart (1 hunks)
  • lib/src/models/attribute_point.dart (1 hunks)
  • lib/src/models/attribute_polygon.dart (1 hunks)
  • lib/src/models/column_line.dart (1 hunks)
  • lib/src/models/column_point.dart (1 hunks)
  • lib/src/models/column_polygon.dart (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • docs/examples/tablesdb/create-row.md
  • docs/examples/account/update-prefs.md
  • docs/examples/databases/create-document.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • lib/services/tables_db.dart
  • lib/services/databases.dart
🧰 Additional context used
🪛 LanguageTool
docs/examples/databases/update-polygon-attribute.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/databases/create-line-attribute.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)


[grammar] ~10-~10: There might be a mistake here.
Context: ...t = await databases.createLineAttribute( databaseId: '<DATABASE_ID>', collect...

(QB_NEW_EN)


[grammar] ~11-~11: There might be a mistake here.
Context: ...ribute( databaseId: '<DATABASE_ID>', collectionId: '<COLLECTION_ID>', key...

(QB_NEW_EN)


[grammar] ~12-~12: There might be a mistake here.
Context: ...>', collectionId: '<COLLECTION_ID>', key: '', xrequired: false, xdefa...

(QB_NEW_EN)


[grammar] ~13-~13: There might be a mistake here.
Context: ...ctionId: '<COLLECTION_ID>', key: '', xrequired: false, xdefault: [[1,2], ...

(QB_NEW_EN)


[grammar] ~14-~14: There might be a mistake here.
Context: ...ID>', key: '', xrequired: false, xdefault: [[1,2], [3, 4]], // (optional)...

(QB_NEW_EN)


[grammar] ~15-~15: There might be a mistake here.
Context: ...xdefault: [[1,2], [3, 4]], // (optional) );

(QB_NEW_EN)


[grammar] ~16-~16: There might be a mistake here.
Context: ...fault: [[1,2], [3, 4]], // (optional) );

(QB_NEW_EN)

docs/examples/databases/create-point-attribute.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/databases/create-polygon-attribute.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/databases/update-line-attribute.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/databases/update-point-attribute.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/tablesdb/create-line-column.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/tablesdb/create-point-column.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/tablesdb/create-polygon-column.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/tablesdb/update-line-column.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/tablesdb/update-point-column.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

docs/examples/tablesdb/update-polygon-column.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

Comment on lines +3 to +16
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>') // Your project ID
.setKey('<YOUR_API_KEY>'); // Your secret API key

Databases databases = Databases(client);

AttributePoint result = await databases.createPointAttribute(
databaseId: '<DATABASE_ID>',
collectionId: '<COLLECTION_ID>',
key: '',
xrequired: false,
xdefault: [[1,2], [3, 4]], // (optional)
);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Same issues: use async entrypoint and correct default shape for Point.

This fixes compile/run behavior and clarifies parameters.

-Client client = Client()
-    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
-    .setProject('<YOUR_PROJECT_ID>') // Your project ID
-    .setKey('<YOUR_API_KEY>'); // Your secret API key
-
-Databases databases = Databases(client);
-
-AttributePoint result = await databases.createPointAttribute(
-    databaseId: '<DATABASE_ID>',
-    collectionId: '<COLLECTION_ID>',
-    key: '',
-    xrequired: false,
-    xdefault: [[1,2], [3, 4]], // (optional)
-);
+Future<void> main() async {
+  final client = Client()
+    ..setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
+    ..setProject('<YOUR_PROJECT_ID>') // Your project ID
+    ..setKey('<YOUR_API_KEY>'); // Your secret API key
+
+  final databases = Databases(client);
+
+  final AttributePoint result = await databases.createPointAttribute(
+    databaseId: '<DATABASE_ID>',
+    collectionId: '<COLLECTION_ID>',
+    key: '<ATTRIBUTE_KEY>',
+    xrequired: false,
+    // xdefault: [1.0, 2.0], // (optional) [x,y]
+  );
+
+  print(result.toMap());
+}
📝 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
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>') // Your project ID
.setKey('<YOUR_API_KEY>'); // Your secret API key
Databases databases = Databases(client);
AttributePoint result = await databases.createPointAttribute(
databaseId: '<DATABASE_ID>',
collectionId: '<COLLECTION_ID>',
key: '',
xrequired: false,
xdefault: [[1,2], [3, 4]], // (optional)
);
Future<void> main() async {
final client = Client()
..setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
..setProject('<YOUR_PROJECT_ID>') // Your project ID
..setKey('<YOUR_API_KEY>'); // Your secret API key
final databases = Databases(client);
final AttributePoint result = await databases.createPointAttribute(
databaseId: '<DATABASE_ID>',
collectionId: '<COLLECTION_ID>',
key: '<ATTRIBUTE_KEY>',
xrequired: false,
// xdefault: [1.0, 2.0], // (optional) [x,y]
);
print(result.toMap());
}
🧰 Tools
🪛 LanguageTool

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

🤖 Prompt for AI Agents
In docs/examples/databases/create-point-attribute.md around lines 3–16, the
example uses a synchronous top-level call, an empty key, incorrect parameter
names (xrequired/xdefault), and an invalid default shape for a Point; update the
snippet to run inside an async entrypoint (e.g., async main and await), provide
a non-empty example key, use the correct parameter names (required and default),
and set default to a single 2-number point (e.g., default: [1, 2]) so the
example compiles and reflects the correct Point shape.

Comment on lines +10 to +17
AttributePolygon result = await databases.updatePolygonAttribute(
databaseId: '<DATABASE_ID>',
collectionId: '<COLLECTION_ID>',
key: '',
xrequired: false,
xdefault: [[1,2], [3, 4]], // (optional)
newKey: '', // (optional)
);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Wrap the snippet in an async entrypoint; top-level await won’t compile.

Make the example runnable and print the result.

-Client client = Client()
-    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
-    .setProject('<YOUR_PROJECT_ID>') // Your project ID
-    .setKey('<YOUR_API_KEY>'); // Your secret API key
-
-Databases databases = Databases(client);
-
-AttributePolygon result = await databases.updatePolygonAttribute(
-    databaseId: '<DATABASE_ID>',
-    collectionId: '<COLLECTION_ID>',
-    key: '',
-    xrequired: false,
-    xdefault: [[1,2], [3, 4]], // (optional)
-    newKey: '', // (optional)
-);
+Future<void> main() async {
+  final client = Client()
+    ..setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
+    ..setProject('<YOUR_PROJECT_ID>') // Your project ID
+    ..setKey('<YOUR_API_KEY>'); // Your secret API key
+
+  final databases = Databases(client);
+
+  final AttributePolygon result = await databases.updatePolygonAttribute(
+    databaseId: '<DATABASE_ID>',
+    collectionId: '<COLLECTION_ID>',
+    key: '<ATTRIBUTE_KEY>',
+    xrequired: false,
+    // xdefault: [
+    //   [ [0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0] ]
+    // ], // (optional) [rings][points][x,y]
+    // newKey: '<NEW_KEY>', // (optional)
+  );
+
+  print(result.toMap());
+}
📝 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
AttributePolygon result = await databases.updatePolygonAttribute(
databaseId: '<DATABASE_ID>',
collectionId: '<COLLECTION_ID>',
key: '',
xrequired: false,
xdefault: [[1,2], [3, 4]], // (optional)
newKey: '', // (optional)
);
Future<void> main() async {
final client = Client()
..setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
..setProject('<YOUR_PROJECT_ID>') // Your project ID
..setKey('<YOUR_API_KEY>'); // Your secret API key
final databases = Databases(client);
final AttributePolygon result = await databases.updatePolygonAttribute(
databaseId: '<DATABASE_ID>',
collectionId: '<COLLECTION_ID>',
key: '<ATTRIBUTE_KEY>',
xrequired: false,
// xdefault: [
// [ [0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0] ]
// ], // (optional) [rings][points][x,y]
// newKey: '<NEW_KEY>', // (optional)
);
print(result.toMap());
}
🤖 Prompt for AI Agents
In docs/examples/databases/update-polygon-attribute.md around lines 10 to 17 the
snippet uses top-level await which won't compile; wrap the call in an async
entrypoint (e.g., async function main() { ... }) perform the await inside that
function, call main() at the end, and print the returned AttributePolygon result
(e.g., console.log/print) so the example is runnable and shows output; keep the
existing parameters/placeholders but ensure the await is inside the async
function and the function is invoked.

Comment on lines +1 to +16
import 'package:dart_appwrite/dart_appwrite.dart';

Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>') // Your project ID
.setKey('<YOUR_API_KEY>'); // Your secret API key

TablesDB tablesDB = TablesDB(client);

ColumnLine result = await tablesDB.createLineColumn(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
key: '',
xrequired: false,
xdefault: [[1,2], [3, 4]], // (optional)
);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Async main and placeholders: make the example copy‑paste runnable.

Top‑level await and empty keys break quickstart UX. Wrap in main(), supply a non-empty key, and only include a valid default if you have one.

-import 'package:dart_appwrite/dart_appwrite.dart';
-
-Client client = Client()
-    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
-    .setProject('<YOUR_PROJECT_ID>') // Your project ID
-    .setKey('<YOUR_API_KEY>'); // Your secret API key
-
-TablesDB tablesDB = TablesDB(client);
-
-ColumnLine result = await tablesDB.createLineColumn(
-    databaseId: '<DATABASE_ID>',
-    tableId: '<TABLE_ID>',
-    key: '',
-    xrequired: false,
-    xdefault: [[1,2], [3, 4]], // (optional)
-);
+import 'package:dart_appwrite/dart_appwrite.dart';
+
+Future<void> main() async {
+  final client = Client()
+    ..setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
+    ..setProject('<YOUR_PROJECT_ID>') // Your project ID
+    ..setKey('<YOUR_API_KEY>'); // Your secret API key
+
+  final tablesDB = TablesDB(client);
+
+  final ColumnLine result = await tablesDB.createLineColumn(
+    databaseId: '<DATABASE_ID>',
+    tableId: '<TABLE_ID>',
+    key: '<COLUMN_KEY>',
+    xrequired: false,
+    // xdefault: <VALID_LINE_DEFAULT>, // (optional)
+  );
+  print(result.toMap());
+}
📝 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
import 'package:dart_appwrite/dart_appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>') // Your project ID
.setKey('<YOUR_API_KEY>'); // Your secret API key
TablesDB tablesDB = TablesDB(client);
ColumnLine result = await tablesDB.createLineColumn(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
key: '',
xrequired: false,
xdefault: [[1,2], [3, 4]], // (optional)
);
import 'package:dart_appwrite/dart_appwrite.dart';
Future<void> main() async {
final client = Client()
..setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
..setProject('<YOUR_PROJECT_ID>') // Your project ID
..setKey('<YOUR_API_KEY>'); // Your secret API key
final tablesDB = TablesDB(client);
final ColumnLine result = await tablesDB.createLineColumn(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
key: '<COLUMN_KEY>',
xrequired: false,
// xdefault: <VALID_LINE_DEFAULT>, // (optional)
);
print(result.toMap());
}
🧰 Tools
🪛 LanguageTool

[grammar] ~3-~3: There might be a mistake here.
Context: ...ppwrite.dart'; Client client = Client() .setEndpoint('https://.cloud.app...

(QB_NEW_EN)


[grammar] ~4-~4: There might be a mistake here.
Context: ...ud.appwrite.io/v1') // Your API Endpoint .setProject('<YOUR_PROJECT_ID>') // Your...

(QB_NEW_EN)


[grammar] ~5-~5: There might be a mistake here.
Context: ...('<YOUR_PROJECT_ID>') // Your project ID .setKey('<YOUR_API_KEY>'); // Your secre...

(QB_NEW_EN)

🤖 Prompt for AI Agents
In docs/examples/tablesdb/create-line-column.md around lines 1 to 16 the snippet
uses top‑level await and an empty column key which makes the example
non‑runnable; wrap the code in an async main function (e.g., Future<void> main()
async { ... }) so awaits run inside it, replace the empty key with a non‑empty
placeholder like 'your_column_key' (and note to replace with a real key), and
either remove the xdefault or replace it with a valid example or document it as
optional so the snippet can be copy‑pasted and run.

Comment on lines +29 to +31
/// Default value for attribute when not provided. Cannot be set when attribute is required.
final List? xdefault;

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Strongly type and cast fields; preserve default as null when absent.

Avoid runtime type errors and unintended empty-list defaults.

-  /// Default value for attribute when not provided. Cannot be set when attribute is required.
-  final List? xdefault;
+  /// Default value for attribute when not provided. Cannot be set when attribute is required.
+  final List<num>? xdefault;
@@
-      xrequired: map['required'],
-      array: map['array'],
-      $createdAt: map['\$createdAt'].toString(),
-      $updatedAt: map['\$updatedAt'].toString(),
-      xdefault: List.from(map['default'] ?? []),
+      xrequired: map['required'] as bool,
+      array: map['array'] as bool?,
+      $createdAt: map['\$createdAt'] as String,
+      $updatedAt: map['\$updatedAt'] as String,
+      xdefault: (map['default'] as List?)?.map((e) => e as num).toList(),

Also applies to: 44-55

🤖 Prompt for AI Agents
In lib/src/models/attribute_point.dart around lines 29-31 (and similarly lines
44-55), the field currently declared as "final List? xdefault;" should be
strongly typed and parsed so that absent JSON leaves it null rather than
defaulting to an empty list; update the field type to a concrete generic (e.g.,
List<dynamic>? or List<String>? depending on expected contents), adjust the
fromJson/fromMap parsing to check for the key and null before casting (use a
null-aware cast/mapper like (json['default'] as List?)?.cast<...>()), and ensure
serialization preserves null when the value is absent; apply the same
strong-typing and null-preserving parsing/serialization changes to the other
affected fields in lines 44-55.

Comment on lines +29 to +31
/// Default value for column when not provided. Cannot be set when column is required.
final List? xdefault;

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Mirror the typing/casting fixes here as well.

Align ColumnPoint with AttributePoint to avoid type issues.

-  /// Default value for column when not provided. Cannot be set when column is required.
-  final List? xdefault;
+  /// Default value for column when not provided. Cannot be set when column is required.
+  final List<num>? xdefault;
@@
-      xrequired: map['required'],
-      array: map['array'],
-      $createdAt: map['\$createdAt'].toString(),
-      $updatedAt: map['\$updatedAt'].toString(),
-      xdefault: List.from(map['default'] ?? []),
+      xrequired: map['required'] as bool,
+      array: map['array'] as bool?,
+      $createdAt: map['\$createdAt'] as String,
+      $updatedAt: map['\$updatedAt'] as String,
+      xdefault: (map['default'] as List?)?.map((e) => e as num).toList(),

Also applies to: 44-55

🤖 Prompt for AI Agents
In lib/src/models/column_point.dart around lines 29-31 (and also lines 44-55),
ColumnPoint's nullable list typing and JSON casting must match AttributePoint to
avoid runtime type issues: change the field types from generic List? to a
strongly typed List<double>? (or List<num>? made concrete as double) for
coordinate/default lists, update the constructor and any getters to use the new
typed lists, and in fromJson/fromMap ensure you safely handle nulls and cast
values using something like (json['xdefault'] as List?)?.map((e) => (e as
num).toDouble()).toList() (and the same pattern for other coordinate/default
fields). Also update toJson/serialization to produce List<double> so the model
and JSON parsing/serialization are consistent.

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: 0

🧹 Nitpick comments (1)
lib/query.dart (1)

220-223: Centralize geometry predicates via helper and add unit tests

  • Introduce a private _geometry(String method, String attribute, List<dynamic> values) in lib/query.dart and refactor the eight geometry methods (intersects, notIntersects, crosses, notCrosses, overlaps, notOverlaps, touches, notTouches) to delegate to it.
  • Add Dart tests in test/ covering each of these predicates to ensure correct query string generation.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b10e61b and 8e6ff0c.

📒 Files selected for processing (1)
  • lib/query.dart (5 hunks)
🔇 Additional comments (4)
lib/query.dart (4)

11-25: toJson cleanup looks correct

Explicit map construction + wrapping non-lists preserves payload shape and simplifies call sites. LGTM.


40-40: notEqual: behavior preserved via toJson wrapping

Passing the raw value (not pre-wrapped) is fine since toJson normalizes to a list. No functional change.


116-119: Confirm server support for createdBetween/updatedBetween and consider adding DateTime overloads

  • Tests in test/query_test.dart already verify the JSON shape; please confirm your Appwrite server version supports these filters.
  • Optional: add convenience overloads that accept DateTime (e.g., createdBetweenDate/updatedBetweenDate) and serialize to UTC ISO-8601 to reduce caller errors.

180-189: Distance methods are custom—verify API support and clarify semantics
Appwrite’s Dart SDK does not include a built-in “distance” operator or a units boolean. Confirm your backend actually supports geo-queries with (coordinates, radius, meters) semantics. If it does, factor these four methods in lib/query.dart into a private _distance helper, add assert(distance >= 0), and document that the bool flag denotes meters; otherwise remove or re-implement using supported operators (e.g. bounding-box logic).

Copy link
Contributor

@stnguyen90 stnguyen90 left a comment

Choose a reason for hiding this comment

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

Missing update to CHANGELOG.md

Copy link
Member

@lohanidamodar lohanidamodar left a comment

Choose a reason for hiding this comment

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

Looks good, let's add changelog

@abnegate abnegate merged commit 16a7403 into main Sep 9, 2025
1 check passed
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.

3 participants