Skip to content

Comments

Version management, platform validation and fallback colors#447

Open
felipecastrosales wants to merge 35 commits intoStacDev:devfrom
SuaMusica:devall
Open

Version management, platform validation and fallback colors#447
felipecastrosales wants to merge 35 commits intoStacDev:devfrom
SuaMusica:devall

Conversation

@felipecastrosales
Copy link

@felipecastrosales felipecastrosales commented Feb 12, 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

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 throughout initialization and content gating, plus a new StacVersion utility for version/condition rules.
    • Platform-aware gating and platform detection utilities for selective content.
    • Custom color parsing hook and a public setter to register it.
    • New public exports for layout and widget parsers; unified copyWith for text styles.
  • Tests

    • Comprehensive tests covering version/build gating, platform handling, and condition parsing.

lstonussi and others added 25 commits May 19, 2025 14:24
feat: add platform validation for widget support in Stac class
@CLAassistant
Copy link

CLAassistant commented Feb 12, 2026

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
0 out of 3 committers have signed the CLA.

❌ lstonussi
❌ felipecastrosales
❌ atrope


lstonussi seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 10fff99 and bd752b6.

📒 Files selected for processing (1)
  • packages/stac/test/src/utils/version/stac_version_test.dart
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/stac/test/src/utils/version/stac_version_test.dart

📝 Walkthrough

Walkthrough

Adds build-number propagation and gating, platform-aware version checks, a custom color parsing hook, new StacVersion utilities and tests, additional parser/widget re-exports, a StacTextStyle.copyWith extension, and a few pubspec dependency adjustments.

Changes

Cohort / File(s) Summary
Initialization & Registry
packages/stac/lib/src/framework/stac.dart, packages/stac/lib/src/framework/stac_registry.dart, packages/stac/lib/src/framework/stac_service.dart
Add optional buildNumber to initialization; register and expose buildNumber on StacRegistry; StacService propagates and uses buildNumber during init and JSON parsing; add setter to configure parseCustomColor.
Version Management & Tests
packages/stac/lib/src/utils/version/stac_version.dart, packages/stac/test/src/utils/version/stac_version_test.dart
Introduce StacVersion, StacConditionVersion, platform-aware fromJson and isSatisfied logic; comprehensive unit tests covering parsing, platform overrides, and comparisons.
Platform Utilities & Exports
packages/stac/lib/src/utils/stac_platforms.dart, packages/stac/lib/src/utils/utils.dart
Add platform canonicalization helpers and export stac_version.dart and stac_platforms.dart from utils barrel.
Color Parsing Hook
packages/stac/lib/src/utils/color_utils.dart, packages/stac/lib/src/framework/stac_registry.dart
Allow custom color resolution via StacRegistry.parseCustomColor when identifiers are unknown.
Parser & Widget Barrels
packages/stac/lib/src/parsers/foundation/layout/parsers.dart, packages/stac/lib/src/parsers/foundation/foundation.dart, packages/stac/lib/src/parsers/widgets/widgets.dart
Add layout parsers aggregate and expose new widget parsers (stac_double, stac_text); re-export layout aggregate from foundation barrel.
Text Style API
packages/stac_core/lib/foundation/text/stac_text_style/stac_text_style.dart
Add StacTextStyleCopyWith extension providing unified copyWith that delegates to StacCustomTextStyle or StacThemeTextStyle.
Public Barrel
packages/stac/lib/stac.dart
Expose stac_framework/stac_framework.dart via package barrel.
Configuration / Pubspecs
pubspec.yaml, packages/stac/pubspec.yaml, packages/stac_webview/pubspec.yaml
Minor root pubspec formatting; switch stac_core dependency to a git reference in package pubspecs.

Sequence Diagram

sequenceDiagram
    participant App as App
    participant Stac as Stac
    participant Service as StacService
    participant Registry as StacRegistry
    participant Json as JsonData
    participant Version as StacVersion

    App->>Stac: initialize(buildNumber: 100)
    Stac->>Service: initialize(buildNumber: 100)
    Service->>Registry: registerBuildNumber(100)
    Registry-->>Service: ack

    App->>Service: fromJson(versionConfig)
    Service->>Registry: buildNumber (getter)
    Registry-->>Service: 100
    Service->>Json: parse StacVersion config
    Json-->>Version: {buildNumber:120, condition:"greaterThan"}
    Service->>Version: isSatisfied(100)
    Version-->>Service: false
    Service-->>App: null (feature gated)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

feature

Suggested reviewers

  • Potatomonsta

Poem

🐰 I hop through builds and platform streams,
I parse the colors of your dreams,
copyWith stitched and versions checked tight,
parsers lined up in neat delight,
A tiny rabbit cheers the code tonight. ✨

🚥 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 accurately reflects the main features introduced in the PR: version management, platform validation, and fallback colors.
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: 9

🤖 Fix all issues with AI agents
In `@packages/stac/lib/src/framework/stac_registry.dart`:
- Around line 75-79: The registerBuildNumber method currently ignores null and
prevents resetting the stored value; update registerBuildNumber(int?
buildNumber) to allow null assignments by removing the null guard and directly
setting _buildNumber = buildNumber so tests that call
StacRegistry.instance.registerBuildNumber(null) actually clear the value, or
alternatively add a new clearBuildNumber() that sets _buildNumber = null if you
want to preserve the guard—refer to registerBuildNumber and the _buildNumber
field when making the change.

In `@packages/stac/lib/src/framework/stac_service.dart`:
- Around line 226-248: The platform gating in stac_service.dart currently uses
dart:io's Platform.operatingSystem (see the block referencing
Platform.operatingSystem, isPlatformSupported, supportedPlatforms and Log.w),
which will fail on Flutter Web; update the check to use Flutter's platform APIs
(use kIsWeb from package:flutter/foundation.dart to short-circuit web and/or
defaultTargetPlatform to compare TargetPlatform values) and map incoming
`platform` values to TargetPlatform (or handle a special "web" token) instead of
directly comparing strings; additionally define and validate against a canonical
set of supported identifiers (an enum or const List like SupportedPlatform /
supportedPlatformStrings) before using contains so typos are caught and your
Log.w can list only validated entries.

In `@packages/stac/lib/src/utils/version/stac_version.dart`:
- Around line 224-226: The current match maps unknown/null condition strings
(the '_' arm next to the "'!=' => StacConditionVersion.notEqual" case) to
StacConditionVersion.notEqual which is surprising; change the default branch to
produce a pass-through condition instead: return
StacConditionVersion.greaterThanOrEqual (or the enum variant representing >=)
and ensure any factory/constructor/path that creates a condition from a string
sets its buildNumber to 0 (i.e. a greaterThanOrEqual with buildNumber 0), so
unrecognized or missing condition strings behave as a no-op rather than silently
becoming notEqual.
- Line 1: The current stac_version.dart imports dart:io which breaks Flutter
Web; split the platform-specific code into two files: create
stac_version_io.dart containing the implementation that uses
Platform/Platform.operatingSystem and any logic currently in stac_version.dart,
and create stac_version_web.dart as a web-safe stub implementation (no dart:io
usage). Replace the direct import in stac_version.dart with conditional
exports/imports that select stac_version_io.dart when dart.library.io is
available and stac_version_web.dart when dart.library.html is available, and
remove the unconditional import of dart:io. Also update any tests that import
stac_version.dart to use the same conditional import pattern or to import the
web/io stubs so tests don’t pull in dart:io on web. Ensure identifiers and
public APIs from the original file remain exported unchanged so callers continue
to use the same symbols.

In `@packages/stac/lib/stac.dart`:
- Line 7: Remove the redundant export of
'package:stac/src/parsers/foundation/layout/parsers.dart' from stac.dart: the
layout parsers are already re-exported via parsers.dart ->
foundation/foundation.dart, so delete the export line "export
'package:stac/src/parsers/foundation/layout/parsers.dart';" from the file to
avoid duplicate exports and keep the public API minimal.

In `@packages/stac/pubspec.yaml`:
- Around line 26-28: The pubspec.yaml currently uses a local path dependency for
stac_core (stac_core: path: ../stac_core) which will block publishing; revert
this to the version constraint (e.g., stac_core: ^1.3.0) before merging or
ensure CI prevents path deps. Update the dependency entry in pubspec.yaml from
the local path back to the versioned form and/or add a CI check (dart pub
publish --dry-run or a lint) to fail the build if any dependency uses a path:
spec so stac_core isn’t published with a local path.

In `@packages/stac/test/src/utils/version/stac_version_test.dart`:
- Around line 188-202: The test for StacVersion.fromJson is brittle because it
assumes the test host is not iOS; change the JSON so the platform-specific key
cannot match the running platform (e.g., replace 'buildNumber_ios' with a
deliberately different key like 'buildNumber_fuchsia' or programmatically
compute a platform key that differs from Platform.operatingSystem) so
StacVersion.fromJson will be forced to use the generic buildNumber; update
assertions against version.buildNumber and leave the condition check for
StacConditionVersion.greaterThanOrEqual unchanged.
- Around line 144-153: The test named "handles version with non-numeric
components" is misleading because StacVersion.buildNumber is an int; update the
test to reflect that by renaming it (e.g., to "handles build number equality" or
"succeeds when build numbers are equal") and remove or replace the comment
"Non-numeric components should be treated as 0"; leave the logic that registers
the build number via StacRegistry.instance.registerBuildNumber(2000) and the
assertion expect(version.isSatisfied(...), true) unchanged so the test still
verifies StacVersion equality semantics.
- Around line 66-73: The test "returns false when app version is null" currently
calls StacRegistry.instance.registerBuildNumber(null) but due to a separate
null-guard bug that leaves the registry value unchanged the test doesn't
exercise the null case; update the test to explicitly assert the intended
behavior of StacVersion.isSatisfied when the app version is null by either (A)
ensuring the registry is actually set to null (fix/registerBuildNumber to allow
setting null) and then changing the expectation to true, or (B) bypassing the
registry and call expect(version.isSatisfied(null), true) directly; reference
StacRegistry.instance.registerBuildNumber and StacVersion.isSatisfied when
making the change.
🧹 Nitpick comments (4)
packages/stac/lib/src/parsers/widgets/widgets.dart (2)

23-23: Export is out of alphabetical order.

stac_double (line 23) is placed before stac_default_bottom_navigation_controller (line 24) and stac_default_tab_controller (line 25), but alphabetically "double" sorts after "default" and "divider". Move this export to after line 26 (stac_divider) to maintain consistent ordering.


62-62: Export is out of alphabetical order.

stac_text (line 62) is placed between stac_selectable_text and stac_set_value, but alphabetically "text" sorts after "set_value". Move this export to after the stac_tab_bar_view / stac_table_cell block (around line 83-84) where other stac_text_* exports reside, to keep the barrel consistently sorted.

packages/stac/lib/src/framework/stac_registry.dart (1)

18-18: parseCustomColor is a public mutable field on a singleton — consider using a setter for consistency.

Other registry state (_buildNumber) is encapsulated behind a method and getter. Exposing parseCustomColor as a bare public field breaks that pattern and allows any caller to overwrite it without logging or validation. StacService.setParseCustomColor already acts as the intended entry point, so making the field private with a setter would be more consistent.

This is minor since the registry is internal, but worth aligning.

packages/stac/lib/src/framework/stac.dart (1)

191-203: buildNumber parameter not documented in the method's doc comment.

The doc comment (lines 134–180) describes all other parameters but omits buildNumber. Consider adding a brief description, e.g.:

- [buildNumber]: Optional build number for version gating. When provided, JSON widget definitions with a version constraint will be checked against this value.

@felipecastrosales felipecastrosales marked this pull request as draft February 12, 2026 20:05
@felipecastrosales
Copy link
Author

@coderabbitai enhance my description on pr.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

@felipecastrosales I'll enhance the PR description for you with a comprehensive summary of the changes.


🏁 Script executed:

#!/bin/bash

# Update the PR description with an enhanced summary
gh pr edit 447 --body "## Overview

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

### 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\`:

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

To use custom color parsing:

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

Length of output: 493


@felipecastrosales I've prepared an enhanced description for your PR, but I cannot update it directly due to workflow restrictions. Here's the enhanced description you can copy and paste manually:


Overview

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

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;
});

To update the PR description:

  1. Go to the PR page
  2. Click the "..." menu next to the PR title
  3. Select "Edit"
  4. Paste the description above
  5. Click "Update comment"

Let me know if you'd like any adjustments to the description!

- 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.
@felipecastrosales felipecastrosales marked this pull request as ready for review February 25, 2026 15:02
@felipecastrosales felipecastrosales changed the title Devall Version management, platform validation and fallback colors Feb 25, 2026
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: 2

♻️ Duplicate comments (2)
packages/stac/test/src/utils/version/stac_version_test.dart (2)

17-20: Remove the ineffective registry reset in test setup.

registerBuildNumber(null) is intentionally ignored, so the “reset” comment is misleading and can hide state assumptions between tests.

🧹 Suggested cleanup
   group('StacVersion', () {
-    setUp(() {
-      // Reset the app version before each test
-      StacRegistry.instance.registerBuildNumber(null);
-    });
-
     test('creates StacVersion instance correctly', () {
Based on learnings: In `packages/stac/lib/src/framework/stac_registry.dart`, null assignment in `registerBuildNumber` is intentionally guarded 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 17
- 20, The test setup is calling an ineffective reset via
StacRegistry.instance.registerBuildNumber(null) which is intentionally ignored;
remove that call and its "Reset the app version before each test" comment from
the setUp block, and if tests require deterministic registry state replace it
with an explicit action that the registry supports (e.g., a real reset method or
registering a specific known build number) rather than
registerBuildNumber(null).

226-239: ⚠️ Potential issue | 🟠 Major

Make this fallback-condition test platform-agnostic.

Using condition_windows as the “different platform” key makes the test fail when run on Windows.

🧪 Proposed stable test key
     test('falls back to generic condition when platform-specific not available',
         () {
       final json = {
         'buildNumber': 1000,
         'condition': '<',
-        'condition_windows': '!=', // Different platform
+        'condition_fuchsia': '!=', // Non-matching key for standard test hosts
       };
🤖 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 226
- 239, The test fails on Windows because it uses a hardcoded platform key
'condition_windows'; update the test JSON to use a non-existent
platform-specific key (e.g., 'condition_other' or 'condition_other_platform') so
it won't match any real platform and the code path in StacVersion.fromJson falls
back to the generic 'condition'. Keep the rest of the test the same and assert
that version.condition equals StacConditionVersion.lessThan.
🧹 Nitpick comments (4)
packages/stac_core/lib/foundation/text/stac_text_style/stac_text_style.dart (1)

733-781: Consider a switch expression for exhaustive dispatch.

The cascading if (this is …) checks work correctly, but a switch expression with Dart 3 type patterns would be more idiomatic, self-documenting, and gives you a compile-time exhaustiveness check if you ever mark StacTextStyle as sealed:

♻️ Suggested refactor
-    if (this is StacCustomTextStyle) {
-      return (this as StacCustomTextStyle).copyWith(
-        inherit: inherit,
-        color: color,
-        backgroundColor: backgroundColor,
-        fontSize: fontSize,
-        fontWeight: fontWeight,
-        fontStyle: fontStyle,
-        letterSpacing: letterSpacing,
-        wordSpacing: wordSpacing,
-        textBaseline: textBaseline,
-        height: height,
-        leadingDistribution: leadingDistribution,
-        decorationColor: decorationColor,
-        decorationStyle: decorationStyle,
-        decorationThickness: decorationThickness,
-        debugLabel: debugLabel,
-        fontFamily: fontFamily,
-        fontFamilyFallback: fontFamilyFallback,
-        package: package,
-        overflow: overflow,
-      );
-    }
-    if (this is StacThemeTextStyle) {
-      return (this as StacThemeTextStyle).copyWith(
-        inherit: inherit,
-        color: color,
-        backgroundColor: backgroundColor,
-        fontSize: fontSize,
-        fontWeight: fontWeight,
-        fontStyle: fontStyle,
-        letterSpacing: letterSpacing,
-        wordSpacing: wordSpacing,
-        textBaseline: textBaseline,
-        height: height,
-        leadingDistribution: leadingDistribution,
-        decorationColor: decorationColor,
-        decorationStyle: decorationStyle,
-        decorationThickness: decorationThickness,
-        debugLabel: debugLabel,
-        fontFamily: fontFamily,
-        fontFamilyFallback: fontFamilyFallback,
-        package: package,
-        overflow: overflow,
-      );
-    }
-    throw StateError(
-      'copyWith only supported on StacCustomTextStyle and StacThemeTextStyle',
-    );
+    return switch (this) {
+      final StacCustomTextStyle custom => custom.copyWith(
+          inherit: inherit,
+          color: color,
+          backgroundColor: backgroundColor,
+          fontSize: fontSize,
+          fontWeight: fontWeight,
+          fontStyle: fontStyle,
+          letterSpacing: letterSpacing,
+          wordSpacing: wordSpacing,
+          textBaseline: textBaseline,
+          height: height,
+          leadingDistribution: leadingDistribution,
+          decorationColor: decorationColor,
+          decorationStyle: decorationStyle,
+          decorationThickness: decorationThickness,
+          debugLabel: debugLabel,
+          fontFamily: fontFamily,
+          fontFamilyFallback: fontFamilyFallback,
+          package: package,
+          overflow: overflow,
+        ),
+      final StacThemeTextStyle theme => theme.copyWith(
+          inherit: inherit,
+          color: color,
+          backgroundColor: backgroundColor,
+          fontSize: fontSize,
+          fontWeight: fontWeight,
+          fontStyle: fontStyle,
+          letterSpacing: letterSpacing,
+          wordSpacing: wordSpacing,
+          textBaseline: textBaseline,
+          height: height,
+          leadingDistribution: leadingDistribution,
+          decorationColor: decorationColor,
+          decorationStyle: decorationStyle,
+          decorationThickness: decorationThickness,
+          debugLabel: debugLabel,
+          fontFamily: fontFamily,
+          fontFamilyFallback: fontFamilyFallback,
+          package: package,
+          overflow: overflow,
+        ),
+      _ => throw StateError(
+          'copyWith only supported on StacCustomTextStyle and StacThemeTextStyle',
+        ),
+    };

This eliminates the redundant as casts (the pattern binds a typed variable directly) and makes it immediately clear that the branches are mutually exclusive. If StacTextStyle is later made sealed, the _ wildcard arm becomes a compile-time error, prompting updates when new subtypes are added.

🤖 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_style/stac_text_style.dart`
around lines 733 - 781, Replace the cascading type-check ifs in the copyWith
implementation with a Dart 3 switch expression using type patterns to match
StacCustomTextStyle and StacThemeTextStyle, binding the matched value to a typed
variable and calling its copyWith (e.g., case StacCustomTextStyle s: return
s.copyWith(...); case StacThemeTextStyle s: return s.copyWith(...);) so you
remove the redundant casts and get exhaustiveness checking; keep the existing
parameters passed into copyWith and keep the StateError fallback (or let the
switch be exhaustive once StacTextStyle is sealed).
packages/stac/lib/src/parsers/foundation/foundation.dart (1)

72-72: Remove redundant layout parser exports to maintain a single source of truth.

Lines 62-71 export 10 individual layout parsers. Line 72 exports layout/parsers.dart, which re-exports all of those same files. This creates duplicate entries in the public API surface. Choose one approach: either export individual files directly or use the aggregator; do not do both.

🤖 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` at line 72,
foundation.dart currently exports individual layout parser files and also
re-exports them via layout/parsers.dart, creating duplicate public exports;
remove the redundancy by choosing one approach—either delete the single-line
export 'layout/parsers.dart' so only the individual layout parser exports
remain, or remove the individual layout parser exports and keep only export
'layout/parsers.dart'—and update foundation.dart accordingly (reference symbols:
export 'layout/parsers.dart' and the individual layout parser export statements
in foundation.dart).
packages/stac/lib/src/utils/version/stac_version.dart (1)

151-156: Prefer explicit buildNumber parsing to avoid opaque runtime errors.

toPlatformJson(...).toInt() on dynamic can throw NoSuchMethodError for malformed payloads (e.g. missing or string values), which is hard to diagnose.

♻️ Proposed parsing hardening
   factory StacVersion.fromJson(Map<String, dynamic> json) {
+    final rawBuildNumber = toPlatformJson(json, 'buildNumber');
+    if (rawBuildNumber is! num) {
+      throw const FormatException(
+        'Invalid or missing "buildNumber" in version config',
+      );
+    }
+
     return StacVersion(
-      buildNumber: toPlatformJson(json, 'buildNumber').toInt(),
+      buildNumber: rawBuildNumber.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 -
156, In StacVersion.fromJson replace the fragile toPlatformJson(json,
'buildNumber').toInt() usage with explicit parsing: retrieve the dynamic value
via toPlatformJson(json, 'buildNumber'), check for null, handle int values
directly, handle numeric strings with int.tryParse, and otherwise throw a clear
FormatException (or return a default) naming the field and payload; keep the
rest of the factory (including condition parsing via toStacConditionVersion())
unchanged so callers of StacVersion.fromJson get a descriptive error for
malformed buildNumber values.
packages/stac/lib/src/framework/stac_service.dart (1)

228-249: Consider fail-closed behavior when platform is provided but all identifiers are invalid.

With platform: ['andriod'] (typo), validatedPlatforms is empty and the widget is currently rendered, which bypasses the intended platform constraint.

🛡️ Suggested guard
         final invalid = rawList
             .where((s) => !supportedPlatformStrings.contains(s))
             .toList();
         if (invalid.isNotEmpty) {
           Log.w(
             'Unknown platform identifier(s) in "platform": $invalid. Supported: $supportedPlatformStrings',
           );
         }
+
+        if (validatedPlatforms.isEmpty && rawList.isNotEmpty) {
+          Log.w(
+            'Ignoring widget because all provided platform identifiers are invalid: $rawList',
+          );
+          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 228 - 249,
The current logic lets a widget render when a `platform` list was provided but
all entries are invalid (e.g., typo "andriod") because `validatedPlatforms`
becomes empty; change to fail-closed by detecting when `rawList` (or the
original provided list) is non-empty and `validatedPlatforms.isEmpty`, log the
unknown identifiers using `invalid`/`supportedPlatformStrings` and return null;
keep the existing warnings for unknown identifiers and the existing
`isPlatformSupported` check otherwise (references: validatedPlatforms, rawList,
supportedPlatformStrings, invalid, isPlatformSupported, currentPlatform).
🤖 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/lib/src/utils/stac_platforms.dart`:
- Around line 14-27: The docstring for currentPlatformString() claims it returns
one of supportedPlatformStrings but the function can return 'unknown'; fix this
mismatch by either adding 'unknown' to the supportedPlatformStrings set/const or
updating the docstring to state that the function may return 'unknown' for
unrecognized platforms; update the declaration of supportedPlatformStrings (or
the doc comment above currentPlatformString) and ensure the switch/default
branch remains or is adjusted accordingly so the contract and implementation
match (refer to currentPlatformString() and supportedPlatformStrings).

In `@packages/stac/test/src/utils/version/stac_version_test.dart`:
- Around line 46-64: The tests currently assert unknown/null inputs map to
StacConditionVersion.greaterThanOrEqual, but the implementation of
toStacConditionVersion() in stac_version.dart intentionally returns
StacConditionVersion.notEqual for unknown or null inputs; update the test
expectations: change the map entry for 'invalid' to expect
StacConditionVersion.notEqual and change the nullString expectation to
StacConditionVersion.notEqual so the tests align with the
toStacConditionVersion() behavior.

---

Duplicate comments:
In `@packages/stac/test/src/utils/version/stac_version_test.dart`:
- Around line 17-20: The test setup is calling an ineffective reset via
StacRegistry.instance.registerBuildNumber(null) which is intentionally ignored;
remove that call and its "Reset the app version before each test" comment from
the setUp block, and if tests require deterministic registry state replace it
with an explicit action that the registry supports (e.g., a real reset method or
registering a specific known build number) rather than
registerBuildNumber(null).
- Around line 226-239: The test fails on Windows because it uses a hardcoded
platform key 'condition_windows'; update the test JSON to use a non-existent
platform-specific key (e.g., 'condition_other' or 'condition_other_platform') so
it won't match any real platform and the code path in StacVersion.fromJson falls
back to the generic 'condition'. Keep the rest of the test the same and assert
that version.condition equals StacConditionVersion.lessThan.

---

Nitpick comments:
In `@packages/stac_core/lib/foundation/text/stac_text_style/stac_text_style.dart`:
- Around line 733-781: Replace the cascading type-check ifs in the copyWith
implementation with a Dart 3 switch expression using type patterns to match
StacCustomTextStyle and StacThemeTextStyle, binding the matched value to a typed
variable and calling its copyWith (e.g., case StacCustomTextStyle s: return
s.copyWith(...); case StacThemeTextStyle s: return s.copyWith(...);) so you
remove the redundant casts and get exhaustiveness checking; keep the existing
parameters passed into copyWith and keep the StateError fallback (or let the
switch be exhaustive once StacTextStyle is sealed).

In `@packages/stac/lib/src/framework/stac_service.dart`:
- Around line 228-249: The current logic lets a widget render when a `platform`
list was provided but all entries are invalid (e.g., typo "andriod") because
`validatedPlatforms` becomes empty; change to fail-closed by detecting when
`rawList` (or the original provided list) is non-empty and
`validatedPlatforms.isEmpty`, log the unknown identifiers using
`invalid`/`supportedPlatformStrings` and return null; keep the existing warnings
for unknown identifiers and the existing `isPlatformSupported` check otherwise
(references: validatedPlatforms, rawList, supportedPlatformStrings, invalid,
isPlatformSupported, currentPlatform).

In `@packages/stac/lib/src/parsers/foundation/foundation.dart`:
- Line 72: foundation.dart currently exports individual layout parser files and
also re-exports them via layout/parsers.dart, creating duplicate public exports;
remove the redundancy by choosing one approach—either delete the single-line
export 'layout/parsers.dart' so only the individual layout parser exports
remain, or remove the individual layout parser exports and keep only export
'layout/parsers.dart'—and update foundation.dart accordingly (reference symbols:
export 'layout/parsers.dart' and the individual layout parser export statements
in foundation.dart).

In `@packages/stac/lib/src/utils/version/stac_version.dart`:
- Around line 151-156: In StacVersion.fromJson replace the fragile
toPlatformJson(json, 'buildNumber').toInt() usage with explicit parsing:
retrieve the dynamic value via toPlatformJson(json, 'buildNumber'), check for
null, handle int values directly, handle numeric strings with int.tryParse, and
otherwise throw a clear FormatException (or return a default) naming the field
and payload; keep the rest of the factory (including condition parsing via
toStacConditionVersion()) unchanged so callers of StacVersion.fromJson get a
descriptive error for malformed buildNumber values.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 414ac47 and 05bbf70.

📒 Files selected for processing (9)
  • packages/stac/lib/src/framework/stac_service.dart
  • packages/stac/lib/src/parsers/foundation/foundation.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/test/src/utils/version/stac_version_test.dart
  • packages/stac_core/lib/foundation/text/stac_text_style/stac_text_style.dart
  • pubspec.yaml
💤 Files with no reviewable changes (1)
  • pubspec.yaml

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

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

26-31: ⚠️ Potential issue | 🟠 Major

Git dependency still blocks pub publish — same root issue as the prior path dependency.

Git dependencies are not allowed as dependencies for packages uploaded to pub.dev. Swapping the local path for a git reference resolves the local-machine portability issue but does not unblock publishing to pub.dev. The comment on line 26 (# when approved, use stac_core: ^1.3.x) confirms the intent, so this must be reverted to a hosted version constraint before any release cut.

🔧 Revert to a hosted version constraint for publishability
-  # when approved, use stac_core: ^1.3.x
-  stac_core:
-    git:
-      url: https://github.com/SuaMusica/stac.git
-      path: packages/stac_core
-      ref: devall
+  stac_core: ^1.3.0
🤖 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 pubspec currently pins
stac_core as a git dependency (the git block under stac_core) which prevents
publishing to pub.dev; revert this to a hosted version constraint (e.g., replace
the entire git: url/path/ref block with a version entry like "stac_core: ^1.3.x"
per the existing comment) so the package depends on a published release before
cutting a release.
🤖 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: The pubspec currently declares stac_core as a git
dependency (stac_core: git: url: ... ref: devall); replace that with a hosted
constraint (e.g., stac_core: ^1.3.0) so the package can be published to pub.dev,
or if you need a temporary non-pub.dev integration move the git entry out of
pubspec and configure a custom hosted repository instead; update the dependency
declaration for stac_core accordingly and remove the git block.

In `@packages/stac/pubspec.yaml`:
- Line 31: Replace the mutable git ref by pinning to a specific commit SHA:
locate the dependency entry that currently reads "ref: devall" in the pubspec
(the git dependency for this package) and change the ref value to the exact
commit SHA you want to lock (e.g., ref: <commit-sha>), then run dart pub get to
verify the resolved revision; ensure you commit the updated pubspec.yaml so the
dependency is reproducibly pinned.

---

Duplicate comments:
In `@packages/stac/pubspec.yaml`:
- Around line 26-31: The pubspec currently pins stac_core as a git dependency
(the git block under stac_core) which prevents publishing to pub.dev; revert
this to a hosted version constraint (e.g., replace the entire git: url/path/ref
block with a version entry like "stac_core: ^1.3.x" per the existing comment) so
the package depends on a published release before cutting a release.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 05bbf70 and 10fff99.

📒 Files selected for processing (2)
  • packages/stac/pubspec.yaml
  • packages/stac_webview/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

@coderabbitai coderabbitai bot Feb 25, 2026

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

🌐 Web query:

git dependencies pub.dev Dart Flutter package publishing rules

💡 Result:

Rules for publishing a Dart/Flutter package to pub.dev when using git dependencies

  • You cannot publish to pub.dev if your package has any git: dependencies in pubspec.yaml (this includes dependency overrides). Pub.dev requires dependencies to be hosted on the default pub server (pub.dev) (plus SDK deps like sdk: flutter). [1], [2]
  • You also cannot publish to pub.dev if your package has any path: dependencies. [2]
  • Pub.dev likewise doesn’t allow hosted dependencies from custom package repositories (non-default hosted sources). [1]

What to do instead

  • Publish the dependency package to pub.dev, then change your dependency to a normal hosted version constraint (e.g., ^1.2.3) and publish your main package. [2]
  • If you must depend on git/private/custom-hosted packages, publish to a custom package repository using publish_to: (not pub.dev). [1]

Relevant docs

  • Dart “Package dependencies” (git/path restrictions): [2]
  • Dart “Publishing packages” (dependency requirement: hosted on default server): [3]
  • Dart “Custom package repositories” (pub.dev disallows git/custom-hosted deps): [1]

Sources:
[1] https://dart.dev/tools/pub/custom-package-repositories
[2] https://dart.dev/tools/pub/dependencies
[3] https://dart.dev/tools/pub/publishing


Remove git dependency before publishing to pub.dev.

This package cannot be published to pub.dev with a git dependency. Pub.dev strictly requires all dependencies to be hosted on the default pub.dev server. Switch line 22-27 to a hosted version constraint like stac_core: ^1.3.0.

If temporary integration is required, move this dependency to a custom package repository configuration instead of pub.dev.

Proposed change
-  # when approved, use stac_core: ^1.3.x
-  stac_core:
-    git:
-      url: https://github.com/SuaMusica/stac.git
-      path: packages/stac_core
-      ref: devall
+  stac_core: ^1.3.0
📝 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
# when approved, use stac_core: ^1.3.x
stac_core:
git:
url: https://github.com/SuaMusica/stac.git
path: packages/stac_core
ref: devall
stac_core: ^1.3.0
🤖 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, The pubspec
currently declares stac_core as a git dependency (stac_core: git: url: ... ref:
devall); replace that with a hosted constraint (e.g., stac_core: ^1.3.0) so the
package can be published to pub.dev, or if you need a temporary non-pub.dev
integration move the git entry out of pubspec and configure a custom hosted
repository instead; update the dependency declaration for stac_core accordingly
and remove the git block.

Copy link
Author

Choose a reason for hiding this comment

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

no needed

Copy link
Contributor

Choose a reason for hiding this comment

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

@felipecastrosales, understood! Since this is for development on the devall branch and you've already noted the intent to switch to a hosted version when approved, the git dependency is fine for now. 👍


🧠 Learnings used
Learnt from: akhil-ge0rge
Repo: StacDev/stac PR: 421
File: packages/stac_core/lib/widgets/sliver_padding/stac_sliver_padding.dart:51-72
Timestamp: 2026-01-27T19:05:50.669Z
Learning: In the stac_core package (packages/stac_core), explicit_to_json: true is configured globally in build.yaml for json_serializable. Therefore, individual JsonSerializable annotations do not need explicitToJson: true specified.

git:
url: https://github.com/SuaMusica/stac.git
path: packages/stac_core
ref: devall
Copy link
Contributor

@coderabbitai coderabbitai bot Feb 25, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Pin ref to a specific commit SHA rather than a mutable branch name.

ref: devall resolves to whatever HEAD of that branch is at fetch time. The dart pub tool doesn't support resolving versions against a git repository; it just fetches a specific revision of the git repository. Any push to devall will silently change the resolved code, making builds non-reproducible and introducing supply-chain risk.

🔧 Pin to a specific commit SHA
-      ref: devall
+      ref: <full-commit-sha>  # e.g. a1b2c3d4e5f6...
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/stac/pubspec.yaml` at line 31, Replace the mutable git ref by
pinning to a specific commit SHA: locate the dependency entry that currently
reads "ref: devall" in the pubspec (the git dependency for this package) and
change the ref value to the exact commit SHA you want to lock (e.g., ref:
<commit-sha>), then run dart pub get to verify the resolved revision; ensure you
commit the updated pubspec.yaml so the dependency is reproducibly pinned.

Copy link
Author

Choose a reason for hiding this comment

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

no needed

Copy link
Contributor

Choose a reason for hiding this comment

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

@felipecastrosales, understood! I've noted your decision to keep the mutable branch reference for now.

@felipecastrosales
Copy link
Author

hey @divyanshub024 can u review this?

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.

4 participants