Skip to content

feat: support transformed discriminated branches safely#91

Merged
leoafarias merged 4 commits intomainfrom
feat/discrim-transformed-branches
Mar 6, 2026
Merged

feat: support transformed discriminated branches safely#91
leoafarias merged 4 commits intomainfrom
feat/discrim-transformed-branches

Conversation

@leoafarias
Copy link
Collaborator

@leoafarias leoafarias commented Mar 5, 2026

This PR makes Ack.discriminated generic so transformed object-backed branches are supported end-to-end at runtime and in JSON Schema conversion. It hardens discriminated behavior by enforcing object-backed branch invariants, preserving transformed-branch metadata in toJsonSchemaModel(), avoiding non-JSON defaults in emitted schema maps, and keeping equality stable across differing generic instantiations. The test suite was expanded across ack integration/schema/converter tests plus downstream converter coverage in ack_firebase_ai and ack_json_schema_builder. API docs were updated for the new signature and a runtime implementation plan doc was added under docs/plans.

@docs-page
Copy link

docs-page bot commented Mar 5, 2026

To view this pull requests documentation preview, visit the following URL:

docs.page/btwld/ack~91

Documentation is deployed and generated using docs.page.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates Ack’s discriminated-union schema to be generic so object-backed transformed branches are supported consistently at runtime and in JSON Schema (map + model) conversion, with additional hardening around branch invariants and schema emission.

Changes:

  • Make Ack.discriminated / DiscriminatedObjectSchema generic over T, enabling transformed object-backed branches to return T directly.
  • Enforce “object-backed branch” invariants in parsing and both JSON Schema conversion paths, and avoid emitting non-JSON-encodable defaults.
  • Expand test coverage across ack core/integration/converter tests and update API docs + add an implementation plan doc.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/ack_firebase_ai/test/to_firebase_ai_schema_test.dart Updates empty-map call site with explicit generic map type for new Ack.discriminated<T> signature.
packages/ack/test/schemas/discriminated_object_schema_test.dart Adds equality + JSON Schema tests for transformed discriminated branches and default serialization behavior.
packages/ack/test/integration/discriminated_child_transform_test.dart Replaces prior “compile-time rejection” narrative with runtime/integration coverage for transformed child branches and error ordering.
packages/ack/test/converters/ack_to_json_schema_model_test.dart Validates transformed discriminated branches convert to object schemas and preserve descriptions in model conversion.
packages/ack/lib/src/schemas/schema.dart Adds baseFieldsEqualErased to support structural equality across differing generic instantiations.
packages/ack/lib/src/schemas/discriminated_object_schema.dart Makes discriminated schema generic, adds branch unwrapping/invariant enforcement, safer default emission for JSON schema maps, and erased-type equality.
packages/ack/lib/src/converters/ack_to_json_schema_model.dart Updates discriminated conversion to unwrap transformed branches and inject discriminator into converted branch models.
packages/ack/lib/src/ack.dart Updates Ack.discriminated factory signature to Ack.discriminated<T extends Object>(...).
docs/plans/discriminated-transformed-branches-runtime.md Adds runtime implementation plan for transformed discriminated branches slice.
docs/api-reference/index.mdx Updates public API docs to reflect the new generic Ack.discriminated<T> signature and branch constraints.
Comments suppressed due to low confidence (1)

packages/ack/lib/src/schemas/discriminated_object_schema.dart:309

  • hashCode allocates a new MapEquality instance each time the getter is called. Since MapEquality has a const constructor, prefer a const instance (and potentially an erased AckSchema value type) to avoid repeated allocations in hot paths like map/set lookups.
  int get hashCode {
    final mapEq = MapEquality<String, AckSchema<T>>();
    return Object.hash(
      baseFieldsHashCode,
      discriminatorKey,
      mapEq.hash(schemas),
    );

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Make DiscriminatedObjectSchema generic (<T extends Object>) so branches
can be transformed schemas (e.g., Ack.object({...}).transform<Cat>(...))
instead of only plain ObjectSchema returning MapValue.

- Add _unwrapDiscriminatedBranchSchema helper for TransformedSchema chains
- Override handleNullInput: Map defaults re-parse through branches,
  non-Map defaults bypass to applyConstraintsAndRefinements
- Update both JSON Schema paths (toJsonSchema + converter) for transforms
- Add object-backed branch invariant with deterministic error messages
- Update API docs and inline dartdoc
@leoafarias leoafarias force-pushed the feat/discrim-transformed-branches branch from e5ffebe to e4a4aaf Compare March 6, 2026 16:36
@leoafarias leoafarias merged commit 3d046bb into main Mar 6, 2026
3 checks passed
@leoafarias leoafarias deleted the feat/discrim-transformed-branches branch March 6, 2026 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants