Skip to content

Version management, platform validation, fallback colors and fix text json#453

Open
felipecastrosales wants to merge 37 commits intoStacDev:devfrom
SuaMusica:features/sm
Open

Version management, platform validation, fallback colors and fix text json#453
felipecastrosales wants to merge 37 commits intoStacDev:devfrom
SuaMusica:features/sm

Conversation

@felipecastrosales
Copy link

@felipecastrosales felipecastrosales commented Feb 26, 2026

This PR introduces version management, platform validation, and several improvements to the STAC framework.

✨ Features

Version Management System

  • StacVersion Class: New utility for managing app version constraints with build numbers
    • Supports platform-specific version configurations (iOS/Android)
    • Provides condition-based version checks (greaterThan, lessThan, equal, etc.)
    • Integrates with widget rendering to conditionally display components based on app version
    • Fix error in migration with children items on text widget. Previously, the text with "children" was expected to include the date, but the latest update changed it to "text." I kept both working to maintain compatibility with older and newer versions.

Build Number Support

  • Added buildNumber parameter to Stac.initialize()
  • Integrated build number registration in StacRegistry
  • Enables version-aware widget rendering from JSON

Platform Validation

  • Widgets can now specify supported platforms
  • Automatic platform checks with fallback behavior for unsupported platforms
  • Warning logs for platform mismatches

Custom Color Parsing

  • Added parseCustomColor hook in StacRegistry
  • Allows custom color resolution for non-standard color identifiers
  • Accessible via StacService.setParseCustomColor()

🔧 Improvements

  • New Layout Parsers: Added centralized export for foundation layout parsers
  • Widget Exports: Exposed StacDouble and StacText parsers
  • Dependency Update: Switched stac_core to local path dependency for development

✅ Tests

  • Comprehensive test suite for StacVersion (277 lines)
    • Platform-specific configuration tests
    • Version condition parsing and validation
    • Build number satisfaction logic
    • Edge case handling

🧹 Chores

  • Standardized quote styles across pubspec.yaml files (single → double quotes)
  • Minor formatting improvements and cleanup

🔄 Migration Notes

If you're using Stac.initialize(), you can now optionally pass a buildNumber:

await Stac.initialize(
  json: json,
  buildNumber: 123, // Optional: enables version-aware widgets
);

To use custom color parsing:

StacService.setParseCustomColor((colorString) {
  // Your custom color parsing logic
  return Colors.purple;
});

Summary by CodeRabbit

  • New Features

    • Build-number support for initialization and version-based gating
    • Platform-specific configuration and validation
    • Custom color parsing fallback
    • Version-management utilities for build-number constraints
    • Unified copyWith for text styles
    • Added layout and widget parsers; text spans accept "text" or "data" keys
  • Tests

    • Comprehensive tests for version handling and platform behavior
  • Chores

    • Updated dependency references to git-based sources

lstonussi and others added 30 commits May 19, 2025 14:24
feat: add platform validation for widget support in Stac class
- Introduced a new method to normalize and validate platform identifiers against a predefined list of supported platforms.
- Updated platform checking logic to improve validation and logging of unsupported platforms.
- Removed unused imports and cleaned up the code for better readability.
- Added missing export for layout parsers in foundation.dart.
…d version management

- Removed the deprecated platform identifier normalization logic from stac_service.dart.
- Updated platform checks to utilize a new utility function for better consistency.
- Simplified the StacVersion class constructor and adjusted platform-specific JSON handling to use the current platform string.
- Added export for stac_platforms.dart in utils.dart to support the new platform handling logic.
- Changed the test to return true when the app version is null, indicating that the constraint is satisfied in this case.
- Renamed a test for clarity, focusing on build number equality handling.
- Updated comments for better understanding of platform-specific JSON handling.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

📝 Walkthrough

Walkthrough

Adds optional build-number initialization and runtime gating (version + platform) with custom-color parsing, a new StacVersion utility, expanded parser/utility exports, small stac_core text-style/span JSON adjustments, and updates stac_core dependencies to git references.

Changes

Cohort / File(s) Summary
Build Number Wiring
packages/stac/lib/src/framework/stac.dart, packages/stac/lib/src/framework/stac_registry.dart, packages/stac/lib/src/framework/stac_service.dart
Adds optional buildNumber parameter to public initialize signatures, registers build number in registry, and threads it into service initialization.
Version & Platform Gating
packages/stac/lib/src/utils/version/stac_version.dart, packages/stac/lib/src/utils/stac_platforms.dart, packages/stac/lib/src/framework/stac_service.dart
Adds StacVersion with platform-aware JSON parsing and isSatisfied(); introduces platform helpers and integrates version/platform checks in JSON parsing with early-null filtering.
Custom Color Hook
packages/stac/lib/src/framework/stac_registry.dart, packages/stac/lib/src/utils/color_utils.dart, packages/stac/lib/src/framework/stac_service.dart
Introduces parseCustomColor registry hook and a setter on service; _parseThemeColor now falls back to registry-provided custom color resolver.
Parser & Utility Barrel Exports
packages/stac/lib/src/parsers/foundation/foundation.dart, packages/stac/lib/src/parsers/foundation/layout/parsers.dart, packages/stac/lib/src/parsers/widgets/widgets.dart, packages/stac/lib/src/utils/utils.dart, packages/stac/lib/stac.dart
Adds multiple exports (foundation layout parsers, widget parsers stac_double/stac_text, stac_version, stac_platforms) to broaden public API surface.
stac_core Text Handling
packages/stac_core/lib/foundation/text/stac_text_span/stac_text_span.dart, packages/stac_core/lib/foundation/text/stac_text_span/stac_text_span.g.dart, packages/stac_core/lib/foundation/text/stac_text_style/stac_text_style.dart
Accepts "text" or "data" keys for StacTextSpan JSON deserialization; adds StacTextStyleCopyWith extension on StacTextStyle to delegate copyWith() to concrete subtypes.
Tests
packages/stac/test/src/utils/version/stac_version_test.dart
Adds comprehensive tests for StacVersion covering JSON parsing, operator handling, platform-specific selection, and isSatisfied behavior.
Dependency Updates & Manifests
packages/stac/pubspec.yaml, packages/stac_webview/pubspec.yaml, pubspec.yaml
Replaces stac_core version constraint with a git reference to a repo/path/ref; minor whitespace cleanup in root pubspec.
Utility Additions
packages/stac/lib/src/utils/stac_platforms.dart, packages/stac/lib/src/utils/utils.dart
Adds platform normalization helpers and exposes them via utils barrel exports.

Sequence Diagram(s)

sequenceDiagram
    participant App as App
    participant StacInit as Stac.initialize()
    participant Service as StacService.initialize()
    participant Registry as StacRegistry
    participant Parser as StacService.fromJson()
    participant Version as StacVersion
    participant Platform as PlatformCheck

    App->>StacInit: initialize(buildNumber: N)
    StacInit->>Service: initialize(buildNumber: N)
    Service->>Registry: registerBuildNumber(N)
    Registry-->>Service: stored

    App->>Parser: fromJson(componentJson)
    alt version present
        Parser->>Version: StacVersion.fromJson(versionData)
        Version-->>Parser: versionObj
        Parser->>Version: isSatisfied(N)
        alt not satisfied
            Version-->>Parser: false
            Parser-->>App: null (filtered)
        else satisfied
            Parser->>Platform: validate(componentJson.platform)
            alt platform mismatch
                Platform-->>Parser: unsupported
                Parser-->>App: null (filtered)
            else supported
                Parser-->>App: component instance
            end
        end
    else no version
        Parser->>Platform: validate(componentJson.platform)
        alt platform mismatch
            Platform-->>Parser: unsupported
            Parser-->>App: null (filtered)
        else supported
            Parser-->>App: component instance
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • PR #350: Changes to stac_core text span JSON handling — overlaps the StacTextSpan readValue change.
  • PR #395: Adds a new parser and modifies StacService — touches the same service file and initialization flow.
  • PR #450: Modifies text-style copyWith implementations — related to the new StacTextStyleCopyWith extension.

Suggested labels

feature

Suggested reviewers

  • divyanshub024
  • Potatomonsta

Poem

🐰 I hopped in code, a tiny guard,
Build numbers checked and platforms barred.
Colors custom, parsers bloom,
Exports widened — tests go boom!
A rabbit cheers: "Gate on, ship the yard!"

🚥 Pre-merge checks | ✅ 3
✅ 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 covers multiple distinct features (version management, platform validation, color parsing, text JSON fixes) but accurately reflects the main changes across the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

❤️ Share

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

Copy link
Contributor

@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: 4

♻️ Duplicate comments (1)
packages/stac/pubspec.yaml (1)

26-31: ⚠️ Potential issue | 🟠 Major

Same git dependency concerns as in stac_webview/pubspec.yaml.

This package has identical issues with the git-based stac_core dependency:

  1. Organization mismatch: Git URL (SuaMusica/stac) differs from this package's repository (StacDev/stac at line 4).

  2. Non-reproducible builds: Branch ref devall can change at any time. Consider pinning to a specific commit SHA if a versioned release isn't available yet:

Suggested alternative using commit SHA
   # when approved, use stac_core: ^1.3.x
   stac_core:
     git:
       url: https://github.com/SuaMusica/stac.git
       path: packages/stac_core
-      ref: devall
+      ref: <commit-sha>  # Pin to specific commit for reproducibility
  1. Track the revert: Add an issue reference to ensure this temporary configuration is reverted before release.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/stac/pubspec.yaml` around lines 26 - 31, The git dependency for
stac_core currently points to url: https://github.com/SuaMusica/stac and ref:
devall which causes organization mismatch and non-reproducible builds; update
the stac_core dependency entry to reference the correct repository/org (replace
SuaMusica with StacDev in the git url or point to the canonical repo used by
this package), pin the ref to a specific commit SHA instead of the branch name
(replace ref: devall with ref: <commit-sha>), and add a TODO/issue reference
comment noting this is temporary and must be reverted to a versioned release
before publishing.
🧹 Nitpick comments (4)
packages/stac/lib/src/parsers/widgets/widgets.dart (2)

62-62: Minor: Export ordering inconsistency.

The stac_text_parser export should be grouped with other stac_text_* exports (lines 84-86: stac_text_button, stac_text_field, stac_text_form_field) for consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/stac/lib/src/parsers/widgets/widgets.dart` at line 62, The export
for stac_text_parser is out of order; move the line exporting 'stac_text_parser'
so it sits with the other stac_text_* exports (the lines exporting
stac_text_button, stac_text_field, stac_text_form_field) to keep consistent
grouping and ordering of related exports in widgets.dart.

23-24: Minor: Export ordering inconsistency.

The stac_double export appears before stac_default_* entries, breaking alphabetical ordering. Consider placing it after stac_divider (line 26) for consistency with the file's alphabetical organization.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/stac/lib/src/parsers/widgets/widgets.dart` around lines 23 - 24,
Reorder the export entries in widgets.dart so the export
'package:stac/src/parsers/widgets/stac_double/stac_double.dart' is moved to
follow the 'stac_divider' export, restoring alphabetical order among exports (so
stac_divider comes before stac_double and then the stac_default_* exports like
stac_default_bottom_navigation_controller_parser remain after).
packages/stac/lib/src/parsers/foundation/foundation.dart (1)

62-72: Redundant exports: individual layout parsers and barrel file.

Lines 62-71 export individual layout parsers, while line 72 exports layout/parsers.dart which re-exports the same files. This creates unnecessary duplication. Consider removing either:

  • The individual exports (lines 62-71), keeping only the barrel export, or
  • The barrel export (line 72), keeping the individual exports
♻️ Option 1: Keep only the barrel export
 // Layout parsers
-export 'layout/stac_axis_parser.dart';
-export 'layout/stac_box_fit_parser.dart';
-export 'layout/stac_box_shape_parser.dart';
-export 'layout/stac_clip_parser.dart';
-export 'layout/stac_flex_fit_parser.dart';
-export 'layout/stac_material_tap_target_size_parser.dart';
-export 'layout/stac_stack_fit_parser.dart';
-export 'layout/stac_vertical_direction_parser.dart';
-export 'layout/stac_wrap_alignment_parser.dart';
-export 'layout/stac_wrap_cross_alignment_parser.dart';
 export 'layout/parsers.dart';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/stac/lib/src/parsers/foundation/foundation.dart` around lines 62 -
72, The file currently exports both individual layout parsers
(stac_axis_parser.dart, stac_box_fit_parser.dart, stac_box_shape_parser.dart,
stac_clip_parser.dart, stac_flex_fit_parser.dart,
stac_material_tap_target_size_parser.dart, stac_stack_fit_parser.dart,
stac_vertical_direction_parser.dart, stac_wrap_alignment_parser.dart,
stac_wrap_cross_alignment_parser.dart) and the barrel layout/parsers.dart which
re-exports the same files; remove the redundant individual exports and keep only
the single barrel export layout/parsers.dart (or alternatively remove the barrel
and keep the individual exports) so the module exports are not duplicated—update
the export list in foundation.dart accordingly.
packages/stac/lib/src/framework/stac_service.dart (1)

223-249: Consider failing closed when platform is provided but all entries are invalid.

Right now, if every provided platform identifier is invalid, the widget still renders. That can silently bypass intended platform restrictions on typo/misconfig.

🔒 Suggested guard
         if (invalid.isNotEmpty) {
           Log.w(
             'Unknown platform identifier(s) in "platform": $invalid. Supported: $supportedPlatformStrings',
           );
         }
+
+        if (validatedPlatforms.isEmpty) {
+          Log.w('No valid platform identifiers found; widget will not render.');
+          return null;
+        }

         final isPlatformSupported = validatedPlatforms.contains(
           currentPlatform,
         );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/stac/lib/src/framework/stac_service.dart` around lines 223 - 249,
When a caller provides platform but none of the entries are valid, currently the
widget still renders; update the guard in the platform handling block (around
platform, currentPlatformString(), supportedPlatformStrings, validatedPlatforms,
invalid, isPlatformSupported) to fail closed: if platform != null and
validatedPlatforms.isEmpty then Log.w that all provided platform identifiers are
invalid (include invalid list) and return null so the widget does not render;
keep the existing behavior for the case where some validatedPlatforms exist and
currentPlatform is not among them.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/stac_webview/pubspec.yaml`:
- Around line 22-27: Update the stac_core git dependency to a stable, documented
reference: clarify whether the URL "https://github.com/SuaMusica/stac.git" is an
intentional fork (document this in a short comment next to the stac_core entry)
or change it to the canonical "https://github.com/StacDev/stac" if that was
intended; replace the unstable branch ref "devall" with a pinned commit SHA or a
tagged release (or switch to the published version constraint "stac_core:
^1.3.x" once approved); and add a TODO comment with the tracking issue/PR number
to ensure the temporary git override is addressed before merge (also keep the
note that pubspec_overrides.yaml is used for local development).

In `@packages/stac/lib/src/utils/version/stac_version.dart`:
- Around line 151-157: StacVersion.fromJson currently calls toPlatformJson(json,
'buildNumber').toInt() which can throw if toPlatformJson returns null; update
the buildNumber extraction to safely handle null and non-int types by reading
the platform value as num/String?, converting with a null-aware cast and
toInt(), and providing a sensible fallback (e.g. 0) or throwing a clear
ArgumentError; specifically modify the StacVersion.fromJson factory so
buildNumber is obtained like: read = toPlatformJson(json, 'buildNumber') as num?
or String?, then compute buildNumber = read != null ? (read is num ?
read.toInt() : int.tryParse(read) ?? fallback) : fallback; keep the condition
line using toPlatformJson(json, 'condition') as String? and call
.toStacConditionVersion() as before.

In `@packages/stac/test/src/utils/version/stac_version_test.dart`:
- Around line 11-14: The current setUp uses
StacRegistry.instance.registerBuildNumber(null) which is ignored by
registerBuildNumber; replace this non-resetting pattern by either (A) removing
the global setUp and explicitly calling
StacRegistry.instance.registerBuildNumber(<explicit-value>) in each test that
needs a build number, or (B) add a test-only reset API on StacRegistry (e.g.,
resetForTests() or clearBuildNumber()) and call that from setUp; update tests to
use the explicit registerBuildNumber or the new resetForTests method instead of
passing null so test state is deterministic.
- Around line 220-226: The tests use hardcoded platform-specific keys (e.g.,
'condition_windows', 'buildNumber_ios', 'condition_android') which can match the
host runtime and make tests flaky; update the tests such as the one named "falls
back to generic condition when platform-specific not available" to compute a
non-host platform key at runtime (use dart:io Platform to detect current OS and
choose the opposite suffix or otherwise pick a platform that is guaranteed not
to match the current host) and build the JSON map with that dynamic key; apply
the same fix to the other affected tests around the other cases (the ones
referencing buildNumber_ios and condition_android) so they all construct
platform-specific keys programmatically instead of hardcoding them.

---

Duplicate comments:
In `@packages/stac/pubspec.yaml`:
- Around line 26-31: The git dependency for stac_core currently points to url:
https://github.com/SuaMusica/stac and ref: devall which causes organization
mismatch and non-reproducible builds; update the stac_core dependency entry to
reference the correct repository/org (replace SuaMusica with StacDev in the git
url or point to the canonical repo used by this package), pin the ref to a
specific commit SHA instead of the branch name (replace ref: devall with ref:
<commit-sha>), and add a TODO/issue reference comment noting this is temporary
and must be reverted to a versioned release before publishing.

---

Nitpick comments:
In `@packages/stac/lib/src/framework/stac_service.dart`:
- Around line 223-249: When a caller provides platform but none of the entries
are valid, currently the widget still renders; update the guard in the platform
handling block (around platform, currentPlatformString(),
supportedPlatformStrings, validatedPlatforms, invalid, isPlatformSupported) to
fail closed: if platform != null and validatedPlatforms.isEmpty then Log.w that
all provided platform identifiers are invalid (include invalid list) and return
null so the widget does not render; keep the existing behavior for the case
where some validatedPlatforms exist and currentPlatform is not among them.

In `@packages/stac/lib/src/parsers/foundation/foundation.dart`:
- Around line 62-72: The file currently exports both individual layout parsers
(stac_axis_parser.dart, stac_box_fit_parser.dart, stac_box_shape_parser.dart,
stac_clip_parser.dart, stac_flex_fit_parser.dart,
stac_material_tap_target_size_parser.dart, stac_stack_fit_parser.dart,
stac_vertical_direction_parser.dart, stac_wrap_alignment_parser.dart,
stac_wrap_cross_alignment_parser.dart) and the barrel layout/parsers.dart which
re-exports the same files; remove the redundant individual exports and keep only
the single barrel export layout/parsers.dart (or alternatively remove the barrel
and keep the individual exports) so the module exports are not duplicated—update
the export list in foundation.dart accordingly.

In `@packages/stac/lib/src/parsers/widgets/widgets.dart`:
- Line 62: The export for stac_text_parser is out of order; move the line
exporting 'stac_text_parser' so it sits with the other stac_text_* exports (the
lines exporting stac_text_button, stac_text_field, stac_text_form_field) to keep
consistent grouping and ordering of related exports in widgets.dart.
- Around line 23-24: Reorder the export entries in widgets.dart so the export
'package:stac/src/parsers/widgets/stac_double/stac_double.dart' is moved to
follow the 'stac_divider' export, restoring alphabetical order among exports (so
stac_divider comes before stac_double and then the stac_default_* exports like
stac_default_bottom_navigation_controller_parser remain after).

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6d090ea and b86190c.

📒 Files selected for processing (16)
  • packages/stac/lib/src/framework/stac.dart
  • packages/stac/lib/src/framework/stac_registry.dart
  • packages/stac/lib/src/framework/stac_service.dart
  • packages/stac/lib/src/parsers/foundation/foundation.dart
  • packages/stac/lib/src/parsers/foundation/layout/parsers.dart
  • packages/stac/lib/src/parsers/widgets/widgets.dart
  • packages/stac/lib/src/utils/color_utils.dart
  • packages/stac/lib/src/utils/stac_platforms.dart
  • packages/stac/lib/src/utils/utils.dart
  • packages/stac/lib/src/utils/version/stac_version.dart
  • packages/stac/lib/stac.dart
  • packages/stac/pubspec.yaml
  • packages/stac/test/src/utils/version/stac_version_test.dart
  • packages/stac_core/lib/foundation/text/stac_text_style/stac_text_style.dart
  • packages/stac_webview/pubspec.yaml
  • pubspec.yaml
💤 Files with no reviewable changes (1)
  • pubspec.yaml

Comment on lines +22 to +27
# when approved, use stac_core: ^1.3.x
stac_core:
git:
url: https://github.com/SuaMusica/stac.git
path: packages/stac_core
ref: devall
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 1. Check if the git branch 'devall' exists in the referenced repository
echo "=== Checking git branch 'devall' ==="
git ls-remote --heads https://github.com/SuaMusica/stac.git devall

# 2. Get more context about the repository
echo -e "\n=== All branches and tags in the repository ==="
git ls-remote https://github.com/SuaMusica/stac.git | head -20

Repository: StacDev/stac

Length of output: 1464


🏁 Script executed:

#!/bin/bash
# 3. Read the full pubspec.yaml to verify the context
echo "=== Full pubspec.yaml content ==="
cat -n packages/stac_webview/pubspec.yaml

Repository: StacDev/stac

Length of output: 1141


🏁 Script executed:

#!/bin/bash
# 4. Search for any TODO or issue references related to this dependency change
echo "=== Searching for TODO/FIXME comments related to stac_core or this change ==="
rg -i "todo|fixme|issue|approved|stac_core|devall" packages/stac_webview/ --type yaml --type dart

# 5. Check git history to understand when this was changed
echo -e "\n=== Recent changes to pubspec.yaml ==="
git log --oneline -10 packages/stac_webview/pubspec.yaml 2>/dev/null || echo "Git history not available"

Repository: StacDev/stac

Length of output: 799


Git dependency points to different organization with unstable branch reference.

The configuration has several issues that should be resolved:

  1. Organization mismatch: The dependency uses https://github.com/SuaMusica/stac.git while the package's homepage is https://github.com/StacDev/stac. This needs clarification—document whether this is intentional (e.g., a fork with specific features) or a configuration error.

  2. Unstable branch reference: Using branch ref devall is non-reproducible since branches can be force-pushed. Once approved, replace with a specific commit SHA or tagged release version (e.g., ^1.3.x as noted in the comment).

  3. Missing issue tracking: The comment "when approved, use stac_core: ^1.3.x" lacks an issue or PR reference. Add a TODO comment with a tracking issue number to ensure this temporary state doesn't remain unresolved.

Note: pubspec_overrides.yaml provides a local path override for development, which is appropriate for local workflows but ensure the main pubspec.yaml is resolved before merging.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/stac_webview/pubspec.yaml` around lines 22 - 27, Update the
stac_core git dependency to a stable, documented reference: clarify whether the
URL "https://github.com/SuaMusica/stac.git" is an intentional fork (document
this in a short comment next to the stac_core entry) or change it to the
canonical "https://github.com/StacDev/stac" if that was intended; replace the
unstable branch ref "devall" with a pinned commit SHA or a tagged release (or
switch to the published version constraint "stac_core: ^1.3.x" once approved);
and add a TODO comment with the tracking issue/PR number to ensure the temporary
git override is addressed before merge (also keep the note that
pubspec_overrides.yaml is used for local development).

Comment on lines +151 to +157
factory StacVersion.fromJson(Map<String, dynamic> json) {
return StacVersion(
buildNumber: toPlatformJson(json, 'buildNumber').toInt(),
condition: (toPlatformJson(json, 'condition') as String?)
.toStacConditionVersion(),
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Potential null dereference in fromJson.

If buildNumber (and platform-specific variant) is missing from the JSON, toPlatformJson returns null, and calling .toInt() on a null value will throw a NoSuchMethodError at runtime.

Consider adding null handling:

🐛 Proposed fix with null safety
 factory StacVersion.fromJson(Map<String, dynamic> json) {
+  final buildNumberValue = toPlatformJson(json, 'buildNumber');
+  if (buildNumberValue == null) {
+    throw ArgumentError('buildNumber is required in StacVersion JSON');
+  }
   return StacVersion(
-    buildNumber: toPlatformJson(json, 'buildNumber').toInt(),
+    buildNumber: (buildNumberValue as num).toInt(),
     condition: (toPlatformJson(json, 'condition') as String?)
         .toStacConditionVersion(),
   );
 }

Alternatively, if a default build number is acceptable:

♻️ Alternative: provide a default
 factory StacVersion.fromJson(Map<String, dynamic> json) {
   return StacVersion(
-    buildNumber: toPlatformJson(json, 'buildNumber').toInt(),
+    buildNumber: (toPlatformJson(json, 'buildNumber') as num?)?.toInt() ?? 0,
     condition: (toPlatformJson(json, 'condition') as String?)
         .toStacConditionVersion(),
   );
 }
📝 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 StacVersion.fromJson(Map<String, dynamic> json) {
return StacVersion(
buildNumber: toPlatformJson(json, 'buildNumber').toInt(),
condition: (toPlatformJson(json, 'condition') as String?)
.toStacConditionVersion(),
);
}
factory StacVersion.fromJson(Map<String, dynamic> json) {
final buildNumberValue = toPlatformJson(json, 'buildNumber');
if (buildNumberValue == null) {
throw ArgumentError('buildNumber is required in StacVersion JSON');
}
return StacVersion(
buildNumber: (buildNumberValue as num).toInt(),
condition: (toPlatformJson(json, 'condition') as String?)
.toStacConditionVersion(),
);
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/stac/lib/src/utils/version/stac_version.dart` around lines 151 -
157, StacVersion.fromJson currently calls toPlatformJson(json,
'buildNumber').toInt() which can throw if toPlatformJson returns null; update
the buildNumber extraction to safely handle null and non-int types by reading
the platform value as num/String?, converting with a null-aware cast and
toInt(), and providing a sensible fallback (e.g. 0) or throwing a clear
ArgumentError; specifically modify the StacVersion.fromJson factory so
buildNumber is obtained like: read = toPlatformJson(json, 'buildNumber') as num?
or String?, then compute buildNumber = read != null ? (read is num ?
read.toInt() : int.tryParse(read) ?? fallback) : fallback; keep the condition
line using toPlatformJson(json, 'condition') as String? and call
.toStacConditionVersion() as before.

Comment on lines +11 to +14
setUp(() {
// Reset the app version before each test
StacRegistry.instance.registerBuildNumber(null);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

setUp is not actually resetting build-number state.

registerBuildNumber(null) is intentionally guarded, so this setup can leave prior state in place and make tests order-dependent. Prefer setting explicit build numbers only in tests that need them (or introducing a dedicated test-only reset path).

Based on learnings: In packages/stac/lib/src/framework/stac_registry.dart, registerBuildNumber intentionally ignores null and resetting build number is not part of the design.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/stac/test/src/utils/version/stac_version_test.dart` around lines 11
- 14, The current setUp uses StacRegistry.instance.registerBuildNumber(null)
which is ignored by registerBuildNumber; replace this non-resetting pattern by
either (A) removing the global setUp and explicitly calling
StacRegistry.instance.registerBuildNumber(<explicit-value>) in each test that
needs a build number, or (B) add a test-only reset API on StacRegistry (e.g.,
resetForTests() or clearBuildNumber()) and call that from setUp; update tests to
use the explicit registerBuildNumber or the new resetForTests method instead of
passing null so test state is deterministic.

Comment on lines +220 to +226
test('falls back to generic condition when platform-specific not available',
() {
final json = {
'buildNumber': 1000,
'condition': '<',
'condition_windows': '!=', // Different platform
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Platform-negative tests are host-dependent due hardcoded platform keys.

Using fixed keys like condition_windows, buildNumber_ios, and condition_android can accidentally match the current runtime platform and make these tests flaky across CI environments.

💡 Suggested deterministic test update
+      final nonCurrentPlatforms =
+          supportedPlatformStrings.where((p) => p != platform).toList();

       final json = {
         'buildNumber': 1000,
         'condition': '<',
-        'condition_windows': '!=', // Different platform
+        'condition_${nonCurrentPlatforms.first}': '!=',
       };
+      final nonCurrentPlatforms =
+          supportedPlatformStrings.where((p) => p != platform).toList();

       final json = {
-        'buildNumber_ios':
-            2000, // Only platform-specific for different platform
-        'condition_android':
-            '>=', // Only platform-specific for different platform
+        'buildNumber_${nonCurrentPlatforms.first}': 2000,
+        'condition_${nonCurrentPlatforms.length > 1 ? nonCurrentPlatforms[1] : nonCurrentPlatforms.first}': '>=',
       };

Also applies to: 250-256

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/stac/test/src/utils/version/stac_version_test.dart` around lines 220
- 226, The tests use hardcoded platform-specific keys (e.g.,
'condition_windows', 'buildNumber_ios', 'condition_android') which can match the
host runtime and make tests flaky; update the tests such as the one named "falls
back to generic condition when platform-specific not available" to compute a
non-host platform key at runtime (use dart:io Platform to detect current OS and
choose the opposite suffix or otherwise pick a platform that is guaranteed not
to match the current host) and build the JSON map with that dynamic key; apply
the same fix to the other affected tests around the other cases (the ones
referencing buildNumber_ios and condition_android) so they all construct
platform-specific keys programmatically instead of hardcoding them.

- Introduced a utility function to read span content from either text or data keys in JSON.
- Updated the StacTextSpan class to accept text from both keys, improving flexibility in JSON handling.
- Enhanced documentation to clarify the new behavior for JSON input.update ref
Copy link
Contributor

@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.

🧹 Nitpick comments (1)
packages/stac_core/lib/foundation/text/stac_text_span/stac_text_span.dart (1)

7-9: Consider clarifying the unused key parameter.

The key parameter is intentionally unused since the function always reads from 'text' with a fallback to 'data'. This is correct for the use case, but could be clearer. Consider either:

  1. Adding a brief comment explaining why key is ignored, or
  2. Using an underscore prefix (_key) to signal intentional disuse
💡 Optional: clarify unused parameter
 /// Used by [StacTextSpan] to read span content from either `"text"` or `"data"`.
+/// The [key] parameter is required by [JsonKey.readValue] but unused here
+/// since we always check both keys for backwards compatibility.
 String? _readTextOrData(Map<dynamic, dynamic> map, String key) =>
     map['text'] ?? map['data'];

Or alternatively:

-String? _readTextOrData(Map<dynamic, dynamic> map, String key) =>
+String? _readTextOrData(Map<dynamic, dynamic> map, String _) =>
     map['text'] ?? map['data'];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/stac_core/lib/foundation/text/stac_text_span/stac_text_span.dart`
around lines 7 - 9, The helper function _readTextOrData currently takes an
unused parameter named key which is confusing; update the function signature to
mark the parameter as intentionally unused (rename it to _key) or add a brief
inline comment above _readTextOrData explaining that the function always reads
'text' with a fallback to 'data' and therefore ignores the passed key, so future
readers understand the intent (refer to function _readTextOrData and its
parameter key).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/stac_core/lib/foundation/text/stac_text_span/stac_text_span.dart`:
- Around line 7-9: The helper function _readTextOrData currently takes an unused
parameter named key which is confusing; update the function signature to mark
the parameter as intentionally unused (rename it to _key) or add a brief inline
comment above _readTextOrData explaining that the function always reads 'text'
with a fallback to 'data' and therefore ignores the passed key, so future
readers understand the intent (refer to function _readTextOrData and its
parameter key).

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b86190c and d82e83f.

📒 Files selected for processing (2)
  • packages/stac_core/lib/foundation/text/stac_text_span/stac_text_span.dart
  • packages/stac_core/lib/foundation/text/stac_text_span/stac_text_span.g.dart

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