Skip to content

Conversation

ChiragAgg5k
Copy link
Member

@ChiragAgg5k ChiragAgg5k commented Sep 26, 2025

This PR contains updates to the Dart SDK for version 18.2.0.

Summary by CodeRabbit

  • New Features
    • Introduced first-class enums for statuses and triggers across models, improving type-safety and consistent JSON serialization.
  • Bug Fixes
    • Enhanced data parsing to use nested “data” fields when present for documents, preferences, and rows.
  • Documentation
    • Updated README to reference the latest version.
  • Tests
    • Updated test suite to reflect enum-based fields and serialization.
  • Chores
    • Bumped SDK to 18.2.0 and updated related headers/user-agent to match the new version.

Copy link

coderabbitai bot commented Sep 26, 2025

Walkthrough

The PR bumps the SDK version from 18.1.0 to 18.2.0 across README, pubspec.yaml, and client headers/user-agent. It introduces new enums (attribute, index, deployment, execution, health, message statuses/triggers) by adding parts to enums.dart and importing enums in models.dart. Multiple model fields switch from String to corresponding enum types, with updated fromMap/toMap to map enum values. Tests are updated to use enums. Additionally, Document, Preferences, and Row fromMap now read data from map["data"] when present, otherwise fall back to the whole map.

Possibly related PRs

Suggested reviewers

  • lohanidamodar

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title follows the Conventional Commits format and clearly summarizes the primary change of updating the Dart SDK to version 18.2.0, which aligns directly with the version bumps in headers and the pubspec included in this pull request.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev

📜 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 fa18170 and 0d2c4bc.

📒 Files selected for processing (3)
  • lib/src/models/document.dart (1 hunks)
  • lib/src/models/preferences.dart (1 hunks)
  • lib/src/models/row.dart (1 hunks)
🔇 Additional comments (2)
lib/src/models/preferences.dart (1)

9-11: Ensure Preferences.fromMap correctly handles explicit null data values.

No existing tests cover the case where map["data"] is explicitly null. Confirm the API never returns "data": null, or update the logic to use map.containsKey("data") ? map["data"] : map and add a corresponding test for this edge case.

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

39-50: Clarify and test fallback data behavior
In Row.fromMap (lib/src/models/row.dart:48), when map["data"] is absent, you fall back to the entire input map—meaning metadata keys ($id, $sequence, etc.) end up inside data. Confirm this is the intended behavior; if not, filter out metadata in the fallback case. Add a unit test covering the legacy format (no "data" key) to assert the correct data payload.


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

Caution

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

⚠️ Outside diff range comments (2)
lib/src/models/attribute_relationship.dart (1)

68-90: Handle unknown attribute statuses without throwing.
firstWhere without an orElse will now throw a StateError if the backend introduces a new status string. Previously this field was just a String, so the SDK stayed resilient to forward-compatible values. Please add a graceful fallback (even if it defaults to a sentinel) so deserialization keeps working instead of crashing.

-      status: enums.AttributeStatus.values.firstWhere(
-        (e) => e.value == map['status'],
-      ),
+      status: map['status'] != null
+          ? enums.AttributeStatus.values.firstWhere(
+              (e) => e.value == map['status'],
+              orElse: () => enums.AttributeStatus.available,
+            )
+          : enums.AttributeStatus.available,
lib/src/models/deployment.dart (1)

1-181: Add orElse fallbacks to enum parsing in models
All fromMap methods under lib/src/models use values.firstWhere without an orElse, which throws a StateError if the mapped value is missing. Update each call to include an orElse that returns a default enum or throws a descriptive error.

🧹 Nitpick comments (28)
test/src/models/index_test.dart (1)

29-29: Optionally assert wire value in map.

Add expect(map['status'], 'available') to also validate serialization.

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

24-24: Optionally verify toMap outputs the string value.

Add expect(map['status'], 'available') for the wire format check.

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

25-25: Optional: assert serialized wire value too.

Add expect(map['status'], 'available') to cover encoding.

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

34-34: Optional: include a wire-format check.

Add expect(map['status'], 'draft') to assert toMap emits the correct string.

lib/src/enums/health_antivirus_status.dart (1)

3-13: Enum definition looks good; consider centralizing parsing with fallback.

Multiple models do values.firstWhere(...) for this enum. Add a parse helper to avoid duplication and to define a single fallback policy for unknown values.

Apply this diff to add a parsing helper:

 enum HealthAntivirusStatus {
   disabled(value: 'disabled'),
   offline(value: 'offline'),
   online(value: 'online');

   const HealthAntivirusStatus({required this.value});

   final String value;

   String toJson() => value;
+
+  static HealthAntivirusStatus parse(String? raw, {HealthAntivirusStatus fallback = HealthAntivirusStatus.disabled}) {
+    for (final v in HealthAntivirusStatus.values) {
+      if (v.value == raw) return v;
+    }
+    return fallback;
+  }
 }
test/src/models/health_status_test.dart (1)

8-20: LGTM; add a serialization assertion.

Also assert that toMap serializes the enum back to the raw API value.

       final map = model.toMap();
+      expect(map['status'], 'pass');
       final result = HealthStatus.fromMap(map);
lib/src/models/attribute_enum.dart (2)

56-58: Gracefully handle unknown status strings from the API.

firstWhere without orElse throws StateError, breaking deserialization if the server rolls out new values. Add an explicit orElse with a clear error (or a chosen fallback if you prefer).

-      status: enums.AttributeStatus.values.firstWhere(
-        (e) => e.value == map['status'],
-      ),
+      status: enums.AttributeStatus.values.firstWhere(
+        (e) => e.value == map['status'],
+        orElse: () => throw ArgumentError('Unknown AttributeStatus: ${map['status']}'),
+      ),

64-65: Prefer typed list conversion for elements.

Make the conversion explicitly typed to avoid runtime surprises.

-      elements: List.from(map['elements'] ?? []),
+      elements: List<String>.from(map['elements'] ?? const []),
lib/src/models/health_status.dart (2)

20-22: Add explicit orElse for forward-compat.

Avoid StateError on new/unknown values; fail with a clear message or decide on a fallback.

-      status: enums.HealthCheckStatus.values.firstWhere(
-        (e) => e.value == map['status'],
-      ),
+      status: enums.HealthCheckStatus.values.firstWhere(
+        (e) => e.value == map['status'],
+        orElse: () => throw ArgumentError('Unknown HealthCheckStatus: ${map['status']}'),
+      ),

19-19: Normalize numeric type for ping.

APIs may send numbers as num/double. Coerce safely.

-      ping: map['ping'],
+      ping: (map['ping'] as num).toInt(),
lib/src/models/attribute_boolean.dart (1)

48-50: Add orElse to prevent runtime StateError on unknown statuses.

Same rationale as other models.

-      status: enums.AttributeStatus.values.firstWhere(
-        (e) => e.value == map['status'],
-      ),
+      status: enums.AttributeStatus.values.firstWhere(
+        (e) => e.value == map['status'],
+        orElse: () => throw ArgumentError('Unknown AttributeStatus: ${map['status']}'),
+      ),
lib/src/models/health_antivirus.dart (1)

16-18: Add orElse for unknown antivirus status values.

Prevents brittle deserialization when API adds new statuses.

-      status: enums.HealthAntivirusStatus.values.firstWhere(
-        (e) => e.value == map['status'],
-      ),
+      status: enums.HealthAntivirusStatus.values.firstWhere(
+        (e) => e.value == map['status'],
+        orElse: () => throw ArgumentError('Unknown HealthAntivirusStatus: ${map['status']}'),
+      ),
test/src/models/attribute_integer_test.dart (1)

18-24: Add toMap round-trip check for the wire value.

Catches accidental changes to serialization.

       final map = model.toMap();
+      expect(map['status'], 'available');
       final result = AttributeInteger.fromMap(map);
test/src/models/attribute_url_test.dart (1)

19-21: Also assert serialized value in map to catch (de)serialization regressions.

Round-tripping only can mask bugs if both sides use the same wrong key/value. Add a direct check on the map.

Apply this diff:

       final map = model.toMap();
+      expect(map['status'], AttributeStatus.available.value);
       final result = AttributeUrl.fromMap(map);
test/src/models/deployment_test.dart (1)

38-40: Assert raw map serialization for status.

Prevents silent mismatch between enum and wire value.

Apply this diff:

       final map = model.toMap();
+      expect(map['status'], DeploymentStatus.waiting.value);
       final result = Deployment.fromMap(map);
test/src/models/attribute_polygon_test.dart (1)

18-20: Add a direct map assertion for status serialization.

Apply this diff:

       final map = model.toMap();
+      expect(map['status'], AttributeStatus.available.value);
       final result = AttributePolygon.fromMap(map);
test/src/models/attribute_ip_test.dart (1)

18-21: Verify map serialization for status.

Apply this diff:

       final map = model.toMap();
+      expect(map['status'], AttributeStatus.available.value);
       final result = AttributeIp.fromMap(map);
lib/src/models/attribute_ip.dart (3)

52-55: Harden enum parsing against unknown values and nulls.

firstWhere without orElse throws on unknown/new server values; map['status'] can also be null. Add a safe fallback to avoid runtime exceptions and improve forward-compat.

Apply this diff:

-      status: enums.AttributeStatus.values.firstWhere(
-        (e) => e.value == map['status'],
-      ),
+      status: enums.AttributeStatus.values.firstWhere(
+        (e) => e.value == map['status'],
+        orElse: () => enums.AttributeStatus.failed, // fallback; pick a sensible default if you prefer another
+      ),

Optionally, consider adding an explicit Unknown case in AttributeStatus for true forward compatibility.


55-62: Avoid serializing null error as string "null".

Current toString() on a null error yields "null", which is misleading. Use a default empty string or make the field nullable if the public API allows it.

Apply this diff:

-      error: map['error'].toString(),
+      error: map['error']?.toString() ?? '',

48-63: Audit and safeguard enum parsing across models
There are dozens of Enum.values.firstWhere(...) calls in model factories (e.g. attribute_*.dart, index.dart, message.dart, deployment.dart, execution.dart) without an orElse, which will throw if the API returns an unexpected value. Add an orElse fallback (or introduce a helper) to handle missing/unknown values consistently.

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

18-20: Add direct assertion for serialized status.

Apply this diff:

       final map = model.toMap();
+      expect(map['status'], AttributeStatus.available.value);
       final result = AttributePoint.fromMap(map);
test/src/models/attribute_boolean_test.dart (1)

18-20: Add explicit map check for status serialization.

Apply this diff:

       final map = model.toMap();
+      expect(map['status'], AttributeStatus.available.value);
       final result = AttributeBoolean.fromMap(map);
test/src/models/execution_test.dart (1)

28-30: Also assert serialized wire values for enums.

Ensures toMap emits the expected strings.

Apply this diff:

       final map = model.toMap();
+      expect(map['trigger'], ExecutionTrigger.http.value);
+      expect(map['status'],  ExecutionStatus.waiting.value);
       final result = Execution.fromMap(map);
lib/src/enums/message_status.dart (1)

10-15: Add a static parser to centralize safe deserialization.

Provide MessageStatus.fromJson/tryParse to avoid repeating values.firstWhere in models and to enable graceful fallback handling.

Apply this diff:

   const MessageStatus({required this.value});

   final String value;

+  static MessageStatus? fromJson(String? value) {
+    if (value == null) return null;
+    for (final e in MessageStatus.values) {
+      if (e.value == value) return e;
+    }
+    return null;
+  }
+
   String toJson() => value;
lib/src/enums/deployment_status.dart (1)

10-15: Provide a static fromJson/tryParse for reuse.

Helps eliminate scattered firstWhere calls and supports tolerant parsing.

Apply this diff:

   const DeploymentStatus({required this.value});

   final String value;

+  static DeploymentStatus? fromJson(String? value) {
+    if (value == null) return null;
+    for (final e in DeploymentStatus.values) {
+      if (e.value == value) return e;
+    }
+    return null;
+  }
+
   String toJson() => value;
lib/src/models/attribute_string.dart (1)

64-64: Ensure numeric type safety for JSON-decoded numbers

JSON decoders yield num; assigning directly to int can fail at runtime. Coerce safely.

Apply this diff:

-      size: map['size'],
+      size: (map['size'] as num).toInt(),
lib/src/models/deployment.dart (2)

125-128: Coerce numeric fields from num to int to avoid runtime type errors

JSON-decoded numeric values are num; direct assignment to int can fail. Convert explicitly.

Apply this diff:

-      sourceSize: map['sourceSize'],
-      buildSize: map['buildSize'],
-      totalSize: map['totalSize'],
+      sourceSize: (map['sourceSize'] as num).toInt(),
+      buildSize: (map['buildSize'] as num).toInt(),
+      totalSize: (map['totalSize'] as num).toInt(),
@@
-      buildDuration: map['buildDuration'],
+      buildDuration: (map['buildDuration'] as num).toInt(),

Also applies to: 136-136


48-49: Docstring still lists raw string values

Optional: reference enums.DeploymentStatus in the doc to reduce drift, e.g., “See enums.DeploymentStatus for possible values.”

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6b754aa and fa18170.

📒 Files selected for processing (54)
  • README.md (1 hunks)
  • lib/enums.dart (1 hunks)
  • lib/models.dart (1 hunks)
  • lib/query.dart (0 hunks)
  • lib/src/client_browser.dart (1 hunks)
  • lib/src/client_io.dart (1 hunks)
  • lib/src/enums/attribute_status.dart (1 hunks)
  • lib/src/enums/deployment_status.dart (1 hunks)
  • lib/src/enums/execution_status.dart (1 hunks)
  • lib/src/enums/execution_trigger.dart (1 hunks)
  • lib/src/enums/health_antivirus_status.dart (1 hunks)
  • lib/src/enums/health_check_status.dart (1 hunks)
  • lib/src/enums/index_status.dart (1 hunks)
  • lib/src/enums/message_status.dart (1 hunks)
  • lib/src/models/attribute_boolean.dart (3 hunks)
  • lib/src/models/attribute_datetime.dart (3 hunks)
  • lib/src/models/attribute_email.dart (3 hunks)
  • lib/src/models/attribute_enum.dart (3 hunks)
  • lib/src/models/attribute_float.dart (3 hunks)
  • lib/src/models/attribute_integer.dart (3 hunks)
  • lib/src/models/attribute_ip.dart (3 hunks)
  • lib/src/models/attribute_line.dart (3 hunks)
  • lib/src/models/attribute_point.dart (3 hunks)
  • lib/src/models/attribute_polygon.dart (3 hunks)
  • lib/src/models/attribute_relationship.dart (3 hunks)
  • lib/src/models/attribute_string.dart (3 hunks)
  • lib/src/models/attribute_url.dart (3 hunks)
  • lib/src/models/deployment.dart (3 hunks)
  • lib/src/models/execution.dart (3 hunks)
  • lib/src/models/health_antivirus.dart (1 hunks)
  • lib/src/models/health_status.dart (1 hunks)
  • lib/src/models/index.dart (3 hunks)
  • lib/src/models/message.dart (3 hunks)
  • pubspec.yaml (1 hunks)
  • test/query_test.dart (0 hunks)
  • test/src/models/attribute_boolean_test.dart (3 hunks)
  • test/src/models/attribute_datetime_test.dart (3 hunks)
  • test/src/models/attribute_email_test.dart (3 hunks)
  • test/src/models/attribute_enum_test.dart (3 hunks)
  • test/src/models/attribute_float_test.dart (3 hunks)
  • test/src/models/attribute_integer_test.dart (3 hunks)
  • test/src/models/attribute_ip_test.dart (3 hunks)
  • test/src/models/attribute_line_test.dart (3 hunks)
  • test/src/models/attribute_point_test.dart (3 hunks)
  • test/src/models/attribute_polygon_test.dart (3 hunks)
  • test/src/models/attribute_relationship_test.dart (3 hunks)
  • test/src/models/attribute_string_test.dart (3 hunks)
  • test/src/models/attribute_url_test.dart (3 hunks)
  • test/src/models/deployment_test.dart (3 hunks)
  • test/src/models/execution_test.dart (3 hunks)
  • test/src/models/health_antivirus_test.dart (1 hunks)
  • test/src/models/health_status_test.dart (2 hunks)
  • test/src/models/index_test.dart (3 hunks)
  • test/src/models/message_test.dart (3 hunks)
💤 Files with no reviewable changes (2)
  • lib/query.dart
  • test/query_test.dart
🔇 Additional comments (62)
lib/src/client_browser.dart (1)

33-35: Header version bump aligns with 18.2.0 release.
Matches the updated package version and keeps HTTP metadata consistent.

pubspec.yaml (1)

2-2: Package version updated to 18.2.0 — looks good.
Keeps the manifest in sync with the new SDK release.

README.md (1)

26-26: Documentation dependency pin now matches 18.2.0.
Ensures users pull the latest SDK version.

lib/src/client_io.dart (1)

39-42: IO client headers updated cleanly.
The x-sdk-version and user-agent strings correctly reflect 18.2.0.

lib/src/enums/index_status.dart (1)

3-15: IndexStatus enum addition looks solid.
Covers all expected lifecycle states and preserves JSON serialization via value.

lib/src/enums/attribute_status.dart (1)

3-15: AttributeStatus enum wired up correctly.
Provides the necessary states with consistent string serialization.

lib/enums.dart (1)

28-35: New enum parts exported appropriately.
Keeps the enums library authoritative for all status/trigger types.

lib/models.dart (1)

4-5: Importing enums.dart ensures models share the enum namespace.
The alias lets part files reference the new enum types cleanly.

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

12-12: Good move to a typed status.

Switching to enums.AttributeStatus improves type-safety and discoverability.


69-69: Correct serialization of enum wire value.

Emitting status.value is the right wire format.

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

42-42: Typed status is a solid improvement.

Using enums.MessageStatus tightens the API.


94-94: Good: serialize enum as its string value.

status.value matches the API contract.

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

12-12: Enum-backed status aligns with the new model strategy.

Looks good.


64-64: Correct: emit the enum’s wire value.

status.value is appropriate.

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

12-12: Type-safety improvement acknowledged.

Using enums.AttributeStatus is consistent across models.


74-74: OK on emitting the enum value.

Matches the expected wire format.

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

2-2: Correct import for enums.

Needed for IndexStatus usage.


15-15: Using IndexStatus improves test clarity.

Good switch from string literal to enum.

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

2-2: Enums import looks correct.


12-12: Constructor now uses AttributeStatus as expected.

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

2-2: Enums import is appropriate.


12-12: Good: enum value in the model under test.

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

2-2: Enums import is needed and correct.


19-19: Using MessageStatus.draft is correct.

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

23-23: LGTM on serialization.

Enum serializes to its wire value. Consistent with tests.

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

8-16: LGTM; mirrors the enum-based API.

Construction aligns with new enum-typed status.

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

2-2: Import of enums is correct.

Enum-based API usage in tests aligns with the model changes.


11-12: Good migration to enums in constructor and assertions.

Status now correctly uses AttributeStatus.available.

Also applies to: 24-24

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

2-2: Enums import looks good.

Required for DeploymentStatus usage.


23-23: Enum-based status usage is correct.

Matches model changes to DeploymentStatus.

Also applies to: 55-55

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

2-2: Enums import is appropriate.


11-11: Correct enum usage for status.

Also applies to: 23-23

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

2-2: Enums import is appropriate.


11-11: Correct enum usage for status.

Also applies to: 24-24

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

11-13: Enum type migration LGTM.

Public surface now exposes enums.AttributeStatus, consistent with the SDK-wide change.


65-78: toMap enum serialization is correct.

Uses status.value as expected.

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

2-2: Enums import is appropriate.


11-11: Correct enum usage for status.

Also applies to: 23-23

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

2-2: Enums import is appropriate.


11-11: Enum-based status checks look good.

Also applies to: 23-23

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

2-2: Enums import is appropriate.


15-16: Enum usage for trigger and status is correct.

Also applies to: 37-38

lib/src/enums/health_check_status.dart (1)

3-12: Enum serialization looks solid.
Enum values map cleanly to the wire format and toJson keeps the payload stable.

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

2-24: Test update matches the enum-backed status change.
The model round-trip now asserts against AttributeStatus.available, aligning with the new API surface.

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

2-25: Enum usage exercised correctly.
The test now mirrors the enum-based status contract and still validates the round-trip.

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

2-24: Round-trip covers the enum migration.
Happy path continues to pass while verifying AttributeStatus.available.

lib/src/enums/execution_trigger.dart (1)

3-12: Trigger enum is wired correctly.
String values line up with the documented API states and serialize as expected.

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

2-30: Test aligns with the enum-backed model.
Ensures the relationship attribute continues to round-trip through the new enum field.

lib/src/enums/execution_status.dart (1)

3-13: Status enum mirrors backend states.
Values and serialization look correct for the execution lifecycle.

lib/src/enums/message_status.dart (1)

3-15: Solid enum with JSON value mapping.

Enum members, value field, and toJson look correct and consistent with other enums.

lib/src/enums/deployment_status.dart (1)

3-15: LGTM: enum design mirrors the established pattern.

Consistent value-carrying enum with toJson; aligns with SDK serialization.

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

12-12: Type migration to enums improves type-safety.

Good move from String to enums.AttributeStatus.

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

21-21: Enum-typed status is appropriate.

Improves correctness over free-form strings.

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

12-12: Enum-typed status: nice upgrade.

Keeps API consistent with other Attribute* models.

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

24-28: Enum migration for trigger/status looks good.

Consistent with new ExecutionTrigger/ExecutionStatus API.


119-120: Correct JSON emission.

Using .value ensures stable wire format.

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

2-2: Enums migration in test looks correct

Imports and assertions updated to enum-backed status are consistent with the model changes.

Also applies to: 11-11, 23-23

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

12-12: Public API type change — confirm semver and migration docs

status changed from String to enums.AttributeStatus. Ensure this is called out in the 18.2.0 release notes with migration guidance.


64-64: Correct enum serialization

Serializing as status.value is correct and interoperable with the API.

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

69-69: Enum to string mapping looks good

status.value in toMap maintains wire-compatibility.

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

2-2: Test updates align with enum-backed status

Construction and assertions now use HealthAntivirusStatus; looks good.

Also applies to: 10-10, 17-17

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

75-75: Enum serialization is correct

status.value preserves the original wire format.

Comment on lines +52 to +54
status: enums.AttributeStatus.values.firstWhere(
(e) => e.value == map['status'],
),
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Guard enum parsing against unknown values

Same issue as other models: firstWhere without orElse may throw. Add a fallback.

Apply this diff:

-      status: enums.AttributeStatus.values.firstWhere(
-        (e) => e.value == map['status'],
-      ),
+      status: enums.AttributeStatus.values.firstWhere(
+        (e) => e.value == map['status']?.toString(),
+        orElse: () => enums.AttributeStatus.values.first,
+      ),

Also consider introducing an explicit Unknown enum value across status enums and using that here.

📝 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
status: enums.AttributeStatus.values.firstWhere(
(e) => e.value == map['status'],
),
status: enums.AttributeStatus.values.firstWhere(
(e) => e.value == map['status']?.toString(),
orElse: () => enums.AttributeStatus.values.first,
),
🤖 Prompt for AI Agents
In lib/src/models/attribute_datetime.dart around lines 52 to 54, the enum
parsing uses firstWhere without an orElse and can throw for unknown values; fix
by providing an orElse that returns a safe fallback (preferably an explicit
Unknown/UnknownValue member on enums.AttributeStatus if available, otherwise a
sensible default like enums.AttributeStatus.<default>) so parsing never throws;
update the code to use firstWhere(..., orElse: () =>
enums.AttributeStatus.Unknown) (and add an explicit Unknown enum value to the
status enums if not already present and use that as the fallback).

Comment on lines +52 to 55
status: enums.AttributeStatus.values.firstWhere(
(e) => e.value == map['status'],
),
error: map['error'].toString(),
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Guard against unknown/forward-compatible status values.

values.firstWhere(...) without orElse throws when API returns a new/unknown status, causing runtime failures. Add a fallback or route through a safe parser.

Apply this diff as a minimal hardening (adjust fallback if product semantics differ):

-      status: enums.AttributeStatus.values.firstWhere(
-        (e) => e.value == map['status'],
-      ),
+      status: enums.AttributeStatus.values.firstWhere(
+        (e) => e.value == map['status'],
+        orElse: () => enums.AttributeStatus.failed,
+      ),

Run to locate other risky firstWhere enum parses to update similarly:


🏁 Script executed:

#!/bin/bash
rg -nP --type=dart -C2 'values\.firstWhere\s*\('

Length of output: 7263


Add orElse fallback to enum parsing in model classes
All .values.firstWhere((e) => e.value == map['status']) calls in lib/src/models/*.dart must include an orElse handler returning a safe default to prevent exceptions on unknown API values. For example:

- enums.AttributeStatus.values.firstWhere(
-   (e) => e.value == map['status'],
- ),
+ enums.AttributeStatus.values.firstWhere(
+   (e) => e.value == map['status'],
+   orElse: () => enums.AttributeStatus.failed,
+ ),
📝 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
status: enums.AttributeStatus.values.firstWhere(
(e) => e.value == map['status'],
),
error: map['error'].toString(),
status: enums.AttributeStatus.values.firstWhere(
(e) => e.value == map['status'],
orElse: () => enums.AttributeStatus.failed,
),
error: map['error'].toString(),
🤖 Prompt for AI Agents
In lib/src/models/attribute_email.dart around lines 52 to 55, the enum parsing
call using .values.firstWhere((e) => e.value == map['status']) can throw if the
API returns an unexpected value; update the firstWhere to include an orElse
handler that returns a safe default (for example enums.AttributeStatus.unknown
if that variant exists, otherwise enums.AttributeStatus.values.first) so the
model never throws when encountering unknown status values.

Comment on lines +56 to +58
status: enums.AttributeStatus.values.firstWhere(
(e) => e.value == map['status'],
),
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Prevent runtime StateError on unexpected/null status.

Add explicit orElse with a clear error.

Apply this diff:

-      status: enums.AttributeStatus.values.firstWhere(
-        (e) => e.value == map['status'],
-      ),
+      status: (() {
+        final value = map['status']?.toString();
+        return enums.AttributeStatus.values.firstWhere(
+          (e) => e.value == value,
+          orElse: () => throw ArgumentError.value(value, 'status', 'Unknown AttributeStatus'),
+        );
+      })(),

Run this script to find any other enum parsers missing orElse:


🏁 Script executed:

#!/bin/bash
# Find enum `values.firstWhere(` calls without an `orElse:` across the lib.
rg -nP --type=dart -C2 '(AttributeStatus|MessageStatus|IndexStatus|DeploymentStatus|ExecutionStatus|HealthStatus)\.values\.firstWhere\s*\((?![^)]*orElse)' lib

Length of output: 84


🏁 Script executed:

#!/usr/bin/env bash
python3 - <<'PYCODE'
import re, glob

patterns = ['AttributeStatus', 'MessageStatus', 'IndexStatus', 'DeploymentStatus', 'ExecutionStatus', 'HealthStatus']
for filepath in glob.glob('lib/**/*.dart', recursive=True):
    with open(filepath, 'r', encoding='utf-8') as f:
        code = f.read()
    for pat in patterns:
        for match in re.finditer(rf'\b{pat}\.values\.firstWhere\(', code):
            start = match.end()
            depth = 1
            i = start
            while i < len(code) and depth > 0:
                if code[i] == '(':
                    depth += 1
                elif code[i] == ')':
                    depth -= 1
                i += 1
            snippet = code[start:i]
            if 'orElse' not in snippet:
                lineno = code.count('\n', 0, match.start()) + 1
                print(f'{filepath}:{lineno}')
PYCODE

Length of output: 644


Add explicit orElse fallback to all enum parsing

  • lib/src/models/attribute_boolean.dart:48
  • lib/src/models/attribute_datetime.dart:52
  • lib/src/models/attribute_email.dart:52
  • lib/src/models/attribute_enum.dart:56
  • lib/src/models/attribute_float.dart:56
  • lib/src/models/attribute_integer.dart:56
  • lib/src/models/attribute_ip.dart:52
  • lib/src/models/attribute_line.dart:48
  • lib/src/models/attribute_point.dart:48
  • lib/src/models/attribute_polygon.dart:48
  • lib/src/models/attribute_relationship.dart:68
  • lib/src/models/attribute_string.dart:56
  • lib/src/models/attribute_url.dart:52
  • lib/src/models/deployment.dart:132
  • lib/src/models/execution.dart:91
  • lib/src/models/index.dart:55
  • lib/src/models/message.dart:74

Wrap each values.firstWhere(…) in a closure and add

orElse: () => throw ArgumentError.value(value, '…', 'Unknown ${EnumName}')

to prevent runtime StateError on null or unexpected values.

🤖 Prompt for AI Agents
In lib/src/models/attribute_float.dart around lines 56 to 58, the enum lookup
uses enums.AttributeStatus.values.firstWhere((e) => e.value == map['status'])
which can throw a StateError for unknown or null values; change it to use a
closure and provide an orElse that throws an ArgumentError.value with the
failing value and field name, e.g. enums.AttributeStatus.values.firstWhere((e)
=> e.value == map['status'], orElse: () => throw
ArgumentError.value(map['status'], 'status', 'Unknown AttributeStatus')), so
unexpected values produce a clear ArgumentError instead of a StateError.

Comment on lines +56 to +58
status: enums.AttributeStatus.values.firstWhere(
(e) => e.value == map['status'],
),
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Prevent StateError on unmapped status.

Add orElse to firstWhere to ensure robustness against future enum expansion.

Apply:

-      status: enums.AttributeStatus.values.firstWhere(
-        (e) => e.value == map['status'],
-      ),
+      status: enums.AttributeStatus.values.firstWhere(
+        (e) => e.value == map['status'],
+        orElse: () => enums.AttributeStatus.failed,
+      ),
📝 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
status: enums.AttributeStatus.values.firstWhere(
(e) => e.value == map['status'],
),
status: enums.AttributeStatus.values.firstWhere(
(e) => e.value == map['status'],
orElse: () => enums.AttributeStatus.failed,
),
🤖 Prompt for AI Agents
In lib/src/models/attribute_integer.dart around lines 56 to 58, the call to
enums.AttributeStatus.values.firstWhere(...) can throw a StateError if
map['status'] doesn't match any enum; update firstWhere to supply an orElse that
returns a safe default (for example a dedicated unknown/unspecified enum member
if available, or enums.AttributeStatus.values.first) so unmatched statuses don't
crash the app.

Comment on lines +48 to +50
status: enums.AttributeStatus.values.firstWhere(
(e) => e.value == map['status'],
),
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Guard against unknown status values during deserialization.

Add an orElse that throws a clear error to avoid opaque StateError.

Apply this diff:

-      status: enums.AttributeStatus.values.firstWhere(
-        (e) => e.value == map['status'],
-      ),
+      status: (() {
+        final value = map['status']?.toString();
+        return enums.AttributeStatus.values.firstWhere(
+          (e) => e.value == value,
+          orElse: () => throw ArgumentError.value(value, 'status', 'Unknown AttributeStatus'),
+        );
+      })(),
🤖 Prompt for AI Agents
In lib/src/models/attribute_line.dart around lines 48 to 50, the deserialization
uses enums.AttributeStatus.values.firstWhere without an orElse, which throws an
opaque StateError for unknown status values; update the firstWhere call to
include an orElse that throws a clear, descriptive exception (including the
received map['status'] and possibly the attribute name/context) so
unknown/invalid status values produce an explicit error message during
deserialization.

Comment on lines +52 to +54
status: enums.AttributeStatus.values.firstWhere(
(e) => e.value == map['status'],
),
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Handle unknown/null status explicitly to avoid StateError at runtime.

values.firstWhere without orElse will throw if the server sends an unrecognized or null status. Add explicit handling with a clearer error.

Apply this diff:

-      status: enums.AttributeStatus.values.firstWhere(
-        (e) => e.value == map['status'],
-      ),
+      status: (() {
+        final value = map['status']?.toString();
+        return enums.AttributeStatus.values.firstWhere(
+          (e) => e.value == value,
+          orElse: () => throw ArgumentError.value(value, 'status', 'Unknown AttributeStatus'),
+        );
+      })(),
🤖 Prompt for AI Agents
In lib/src/models/attribute_url.dart around lines 52 to 54, the code uses
enums.AttributeStatus.values.firstWhere(...) without orElse which will throw a
generic StateError if map['status'] is null or unrecognized; update it to read
the raw status into a local var, then call firstWhere with an orElse that throws
a clearer error (e.g., include the raw status value) or returns a safe default
as appropriate for your domain, thereby preventing an unexpected runtime
StateError and providing a descriptive message when the server sends an
unknown/null status.

Comment on lines +132 to +134
status: enums.DeploymentStatus.values.firstWhere(
(e) => e.value == map['status'],
),
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Protect enum parsing from unknown/novel status values

As elsewhere, firstWhere without orElse will throw. Add fallback to keep SDK forward-compatible with new server statuses.

Apply this diff:

-      status: enums.DeploymentStatus.values.firstWhere(
-        (e) => e.value == map['status'],
-      ),
+      status: enums.DeploymentStatus.values.firstWhere(
+        (e) => e.value == map['status']?.toString(),
+        orElse: () => enums.DeploymentStatus.values.first,
+      ),

Consider adding a DeploymentStatus.unknown and using it here across the SDK.

🤖 Prompt for AI Agents
In lib/src/models/deployment.dart around lines 132 to 134, the enum parsing uses
firstWhere without an orElse which will throw on unknown server statuses; add a
safe fallback by defining a DeploymentStatus.unknown value in the enums (if not
present) and change the parsing to use firstWhere with an orElse that returns
DeploymentStatus.unknown so unknown/novel status strings map to .unknown instead
of throwing, and propagate that .unknown value across the SDK where appropriate.

Comment on lines +88 to +93
trigger: enums.ExecutionTrigger.values.firstWhere(
(e) => e.value == map['trigger'],
),
status: enums.ExecutionStatus.values.firstWhere(
(e) => e.value == map['status'],
),
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Harden enum parsing for trigger and status.

Unknown values will currently throw; add safe fallbacks to avoid runtime crashes.

Apply:

-      trigger: enums.ExecutionTrigger.values.firstWhere(
-        (e) => e.value == map['trigger'],
-      ),
-      status: enums.ExecutionStatus.values.firstWhere(
-        (e) => e.value == map['status'],
-      ),
+      trigger: enums.ExecutionTrigger.values.firstWhere(
+        (e) => e.value == map['trigger'],
+        orElse: () => enums.ExecutionTrigger.http,
+      ),
+      status: enums.ExecutionStatus.values.firstWhere(
+        (e) => e.value == map['status'],
+        orElse: () => enums.ExecutionStatus.processing,
+      ),

If preferred, expose static fromJson/tryParse on the enums and use those here for consistency.

📝 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
trigger: enums.ExecutionTrigger.values.firstWhere(
(e) => e.value == map['trigger'],
),
status: enums.ExecutionStatus.values.firstWhere(
(e) => e.value == map['status'],
),
trigger: enums.ExecutionTrigger.values.firstWhere(
(e) => e.value == map['trigger'],
orElse: () => enums.ExecutionTrigger.http,
),
status: enums.ExecutionStatus.values.firstWhere(
(e) => e.value == map['status'],
orElse: () => enums.ExecutionStatus.processing,
),
🤖 Prompt for AI Agents
In lib/src/models/execution.dart around lines 88 to 93, the enum parsing uses
firstWhere without a fallback which will throw on unknown values; update both
trigger and status parsing to provide safe fallbacks (use firstWhere with an
orElse returning a sensible default enum value, e.g. a dedicated
Unknown/Unspecified value or the first/neutral enum entry) to avoid runtime
crashes; alternatively, implement and call static fromJson/tryParse helpers on
the enums that encapsulate this safe parsing behavior and return a default when
map values are unrecognized.

Comment on lines +55 to +57
status: enums.IndexStatus.values.firstWhere(
(e) => e.value == map['status'],
),
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add fallback to avoid crashes on unknown status.

Same pitfall: firstWhere without orElse will throw for new server values.

Apply:

-      status: enums.IndexStatus.values.firstWhere(
-        (e) => e.value == map['status'],
-      ),
+      status: enums.IndexStatus.values.firstWhere(
+        (e) => e.value == map['status'],
+        orElse: () => enums.IndexStatus.failed,
+      ),
📝 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
status: enums.IndexStatus.values.firstWhere(
(e) => e.value == map['status'],
),
status: enums.IndexStatus.values.firstWhere(
(e) => e.value == map['status'],
orElse: () => enums.IndexStatus.failed,
),
🤖 Prompt for AI Agents
In lib/src/models/index.dart around lines 55 to 57, the call to
enums.IndexStatus.values.firstWhere(...) will throw if the server returns an
unknown status; change it to call firstWhere with an orElse that returns a safe
default (preferably enums.IndexStatus.unknown if that enum value exists,
otherwise enums.IndexStatus.values.first) so unknown/forward-compatible statuses
don't crash parsing, and adjust downstream code to handle the chosen default if
necessary.

Comment on lines +74 to +76
status: enums.MessageStatus.values.firstWhere(
(e) => e.value == map['status'],
),
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add robust parsing with helpful error; consider tightening list typing.

  • firstWhere without orElse will throw a generic StateError on unknown/null values. Prefer an explicit ArgumentError for clarity.
  • Optional: For topics/users/targets/deliveryErrors, prefer List.from(...) to ensure strong typing.

Apply this diff for status:

-      status: enums.MessageStatus.values.firstWhere(
-        (e) => e.value == map['status'],
-      ),
+      status: (() {
+        final value = map['status']?.toString();
+        return enums.MessageStatus.values.firstWhere(
+          (e) => e.value == value,
+          orElse: () => throw ArgumentError.value(value, 'status', 'Unknown MessageStatus'),
+        );
+      })(),
📝 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
status: enums.MessageStatus.values.firstWhere(
(e) => e.value == map['status'],
),
status: (() {
final value = map['status']?.toString();
return enums.MessageStatus.values.firstWhere(
(e) => e.value == value,
orElse: () => throw ArgumentError.value(
value,
'status',
'Unknown MessageStatus',
),
);
})(),
🤖 Prompt for AI Agents
In lib/src/models/message.dart around lines 74 to 76, replace the unsafe
enums.MessageStatus.values.firstWhere lookup with a version that supplies an
orElse which throws an ArgumentError with a clear message including the invalid
map['status'] value; also tighten list typing for
topics/users/targets/deliveryErrors by using List<String>.from(...) (or
null-aware variants) so the fields are strongly typed and avoid runtime type
errors.

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.

1 participant