Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(typegraph): implement additional_props #980

Merged
merged 3 commits into from
Mar 5, 2025

Conversation

luckasRanarison
Copy link
Contributor

@luckasRanarison luckasRanarison commented Mar 4, 2025

Migration notes


  • The change comes with new or modified tests
  • Hard-to-understand functions have explanatory comments
  • End-user documentation is updated to reflect the change

Summary by CodeRabbit

  • New Features

    • Introduced a configurable flag in object definitions that controls whether extra, unspecified properties are allowed. This enhances schema validation and data conversion by permitting flexible input when enabled.
    • Updated validation logic to conditionally bypass errors for additional properties when permitted.
  • Tests

    • Added new test cases and a helper function to verify input stringification and validation for both simple and nested structures.

Copy link

linear bot commented Mar 4, 2025

Copy link
Contributor

coderabbitai bot commented Mar 4, 2025

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • tests/typecheck/__snapshots__/typecheck_test.ts.snap is excluded by !**/*.snap

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

This pull request introduces a new field (additional_props/additionalProps) into several type definitions to specify whether objects allow extra properties. The changes update both the data structures and the validation logic so that unexpected properties are only flagged when additional properties are disallowed. In addition, a new function to stringify structured input has been added along with corresponding tests to verify its behavior.

Changes

File(s) Change Summary
src/metagen/.../fdk_rs/{stubs.rs, types.rs, tests/fixtures.rs}, src/typegraph/{core/.../typedef/struct_.rs, core/.../typegraph.rs, schema/.../types.rs, typegraph/types.ts} Added the additional_props (or additionalProps) field to type definitions (e.g., ObjectTypeData, ObjectNode) for object and union types. The field is initialized as false or made optional and includes serialization attributes where applicable.
src/typegate/.../engine/{planner/args.ts, typecheck/inline_validators/object.ts} Updated validation logic: modified checks to throw errors on unexpected properties only when additionalProps is falsy and renamed a parameter for clarity in object key validation.
tests/typecheck/input_validator_test.ts Added a new test case ("pass for any struct") to verify the behavior of stringifyStruct with both simple and nested structured inputs.
tests/typecheck/typecheck.py Introduced the stringify_struct function for converting structured inputs to JSON strings and exposed it via g.expose.

Sequence Diagram(s)

sequenceDiagram
    participant Client as User
    participant AC as ArgumentCollector.collectObjectArg
    participant Validator as generateObjectValidator

    Client->>AC: Submit object for validation
    AC->>AC: Check for unexpected properties
    alt additionalProps is disallowed
        AC->>Client: Throw UnexpectedPropertiesError
    else additionalProps is allowed
        AC->>AC: Skip error for unexpected properties
    end
    AC->>Validator: Forward object for further validation
    Validator->>Validator: Iterate over object keys
    alt Key marked with additionalProps
        Validator->>Validator: Skip further checks for key
    else
        Validator->>Validator: Perform standard key validation
    end
    Validator-->>AC: Return validation result
    AC-->>Client: Return final validation result
Loading
sequenceDiagram
    participant Caller as Function Caller
    participant SS as stringify_struct

    Caller->>SS: Call stringify_struct with structured params
    SS->>SS: Convert params using JSON.stringify
    SS-->>Caller: Return JSON string
Loading

Suggested reviewers

  • Natoandro
  • michael-0acf4
  • Yohe-Am

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@luckasRanarison luckasRanarison requested a review from a team March 4, 2025 05:11
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: 0

🔭 Outside diff range comments (1)
src/typegate/src/engine/typecheck/inline_validators/object.ts (1)

1-62: 💡 Verification agent

🧩 Analysis chain

Add tests to verify object validation behavior with additional properties

The changes look solid, but I recommend adding tests that specifically verify:

  1. Objects with additional properties are rejected when additionalProps is false (default)
  2. Objects with additional properties are accepted when additionalProps is true

These tests would ensure the feature works as expected across different scenarios.

Would you like me to suggest some test cases for validating this new functionality?


🏁 Script executed:

#!/bin/bash
# Find existing tests for object validation

echo "Checking for existing object validation tests..."
rg -A 5 -B 5 "additionalProps|additional_props" --type=ts --type=js test/

Length of output: 228


Action Required: Add Tests for Object Validation with Additional Properties

The implementation changes look solid. However, I couldn't find any tests covering the behavior for additional properties. Please add tests to ensure that:

  • Rejection Scenario: When additionalProps is false (the default), objects with extra keys are rejected with the expected error.
  • Acceptance Scenario: When additionalProps is true, objects with extra keys are accepted.

Also, if tests already exist in a different location than the non-existent test/ directory, please verify that they adequately cover these scenarios.

Would you like suggestions for specific test cases?

🧹 Nitpick comments (2)
src/typegate/src/engine/planner/args.ts (1)

678-678: Key implementation of additional_props behavior

This is the critical change that implements the core behavior for the additional_props feature. The code now only throws an UnexpectedPropertiesError when unexpected properties are found AND additionalProps is set to false, which properly implements the feature described in the PR objectives.

Consider adding a brief comment explaining the purpose of this conditional check for future developers:

-    if (!typ.additionalProps && unexpectedProps.length > 0) {
+    // Only throw an error for unexpected properties if additional properties are not allowed
+    if (!typ.additionalProps && unexpectedProps.length > 0) {
src/typegate/src/engine/typecheck/inline_validators/object.ts (1)

33-33: Implementation of additional properties validation looks good.

The added condition if (${typeNode.additionalProps}) { continue; } correctly allows objects to contain properties not defined in the schema when additionalProps is set to true. This works well with the existing validation logic and properly integrates with the changes in the type definitions.

I would suggest adding a brief comment explaining this behavior for future developers:

+  // Skip validation for unknown keys if additional properties are allowed
   if (${typeNode.additionalProps}) { continue; }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4115b43 and ca46519.

📒 Files selected for processing (11)
  • src/metagen/src/fdk_rs/stubs.rs (1 hunks)
  • src/metagen/src/fdk_rs/types.rs (8 hunks)
  • src/metagen/src/tests/fixtures.rs (1 hunks)
  • src/typegate/src/engine/planner/args.ts (1 hunks)
  • src/typegate/src/engine/typecheck/inline_validators/object.ts (2 hunks)
  • src/typegate/src/typegraph/types.ts (1 hunks)
  • src/typegraph/core/src/typedef/struct_.rs (1 hunks)
  • src/typegraph/core/src/typegraph.rs (1 hunks)
  • src/typegraph/schema/src/types.rs (2 hunks)
  • tests/typecheck/input_validator_test.ts (1 hunks)
  • tests/typecheck/typecheck.py (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: lint-compat (macos-14, aarch64-apple-darwin, false)
  • GitHub Check: lint-compat (macos-13, x86_64-apple-darwin, false)
  • GitHub Check: bulid-docker (linux/arm64, custom-arm)
  • GitHub Check: bulid-docker (linux/amd64, custom-ubuntu-large)
  • GitHub Check: test-full
  • GitHub Check: pre-commit
🔇 Additional comments (13)
src/metagen/src/tests/fixtures.rs (1)

61-61: New additional_props field implementation looks good

The new field additional_props: false has been properly added to the ObjectTypeData struct. This default value maintains the current behavior of not allowing additional properties in objects.

src/metagen/src/fdk_rs/stubs.rs (1)

119-119: Consistent implementation of additional_props field

The additional_props: false field has been correctly added to the ObjectTypeData struct in the test, consistent with the implementation in other files.

tests/typecheck/input_validator_test.ts (1)

243-254: Good test coverage for the stringifyStruct function

The test case effectively verifies that the stringifyStruct function handles both simple and nested structured inputs correctly. It ensures the function doesn't produce errors when processing valid inputs.

The test covers:

  1. Simple structure with primitive types (string and integer)
  2. Nested structure with an object property

This provides good basic coverage for the new functionality.

tests/typecheck/typecheck.py (2)

109-113: Well-implemented feature for dynamic object handling.

The stringify_struct function effectively demonstrates the new additional_props=True feature by allowing arbitrary properties in the input structure. This creates a flexible interface that accepts any JSON-compatible object through the params property. The implementation is straightforward and aligned with the PR objective.


124-124: Good export naming using camelCase for the public API.

The function is correctly exposed with a camelCase name (stringifyStruct) which maintains consistency with the API naming convention throughout the codebase.

src/typegraph/core/src/typedef/struct_.rs (1)

84-84: Properly propagates the additional_props field to the type definition.

The implementation correctly adds the additional_props field to the ObjectTypeData structure in the convert method. This ensures that the struct's configuration for allowing additional properties is properly preserved in the generated type representation.

src/metagen/src/fdk_rs/types.rs (2)

445-445: Default behavior correctly established for object type.

The additional_props field is appropriately set to false for the my_obj object type, establishing the default behavior that objects don't allow additional properties unless explicitly configured. This conservative default promotes schema validation and type safety.


621-621: Consistent implementation across all test object definitions.

The changes consistently add additional_props: false to all test object definitions, ensuring that the behavior is well-tested across various scenarios including cyclic references, unions, and complex object structures. This thorough approach provides good test coverage for the new feature.

Also applies to: 634-634, 647-647, 679-679, 692-692, 732-732, 745-745

src/typegate/src/typegraph/types.ts (1)

70-70:

✅ Verification successful

TypeScript interface properly updated with optional additionalProps.

The ObjectNode interface is correctly enhanced with an optional additionalProps boolean property, maintaining language-specific naming conventions (camelCase for TypeScript). Making this property optional is appropriate since it should have a default behavior when not specified.

Let's verify that the corresponding validation logic has been updated to handle this property:


🏁 Script executed:

#!/bin/bash
# Look for validation logic that might use the additionalProps field
rg -A 5 "additionalProps" --glob "*.ts" | grep -v "types.ts"

Length of output: 2840


Interface Update Verified: additionalProps Integration Confirmed

The update to the ObjectNode interface in src/typegate/src/typegraph/types.ts adding the optional additionalProps?: boolean; field is correctly propagated. Our verification shows:

  • Planner Validation: In src/typegate/src/engine/planner/args.ts, the code correctly checks if (!typ.additionalProps && unexpectedProps.length > 0) and raises an error when unexpected properties exist.
  • GraphQL Field Handling: In src/typegate/src/runtimes/utils/graphql_forward_vars.ts, the property is used to conditionally include fields like selectionSet and arguments.
  • Inline Validators: In src/typegate/src/engine/typecheck/inline_validators/object.ts, the condition if (${typeNode.additionalProps}) { continue; } confirms that the property controls the flow as intended.

The changes ensure that when additionalProps is not specified, appropriate default behavior is maintained. No further modifications are required.

src/typegraph/core/src/typegraph.rs (1)

140-140: LGTM: Default value for additional_props is correctly set to false.

The implementation correctly initializes additional_props to false, which is a sensible default value. This ensures backward compatibility as objects won't accept unknown properties unless explicitly configured to do so.

src/typegraph/schema/src/types.rs (2)

155-155: Adding camelCase serialization for ObjectTypeData is properly applied.

The #[serde(rename_all = "camelCase")] attribute ensures consistent field naming convention in serialized JSON output, which is good for API consistency.


164-166: Proper implementation of additional_props field with appropriate Serde attributes.

The implementation includes:

  1. #[serde(skip_serializing_if = "std::ops::Not::not")] - Efficiently omits the field when false to reduce payload size
  2. #[serde(default)] - Properly handles deserialization when the field is missing

This is a well-designed implementation that maintains backward compatibility while adding new functionality.

src/typegate/src/engine/typecheck/inline_validators/object.ts (1)

12-12: Parameter renamed to reflect its usage.

Removing the underscore prefix from _typeNode to typeNode improves code clarity by indicating that the parameter is now being used within the function.

Yohe-Am
Yohe-Am previously approved these changes Mar 5, 2025
Copy link

codecov bot commented Mar 5, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 81.13%. Comparing base (0531939) to head (6a9c39a).
Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #980   +/-   ##
=======================================
  Coverage   81.13%   81.13%           
=======================================
  Files         142      142           
  Lines       17967    17968    +1     
  Branches     1961     1960    -1     
=======================================
+ Hits        14578    14579    +1     
  Misses       3371     3371           
  Partials       18       18           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@Natoandro Natoandro left a comment

Choose a reason for hiding this comment

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

I wonder how we would select additional props on output types 😆

@luckasRanarison
Copy link
Contributor Author

additionalProps on output types are filtered for now, but think about it. It doesn't make sense to have variable output shape. It should always be determined in advance.

@luckasRanarison luckasRanarison merged commit d8fe98d into main Mar 5, 2025
13 checks passed
@luckasRanarison luckasRanarison deleted the met-843-addiditioonalprops-in-struct branch March 5, 2025 10:06
luckasRanarison added a commit that referenced this pull request Mar 11, 2025
<!--
Pull requests are squashed and merged using:
- their title as the commit message
- their description as the commit body

Having a good title and description is important for the users to get
readable changelog.
-->

<!-- 1. Explain WHAT the change is about -->

- Fixup for #980

<!-- 3. Explain HOW users should update their code -->

#### Migration notes

---

- [x] The change comes with new or modified tests
- [ ] Hard-to-understand functions have explanatory comments
- [ ] End-user documentation is updated to reflect the change


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Enhanced object validation now accepts additional properties when
allowed, offering more flexible data processing.
- Introduced a new REST endpoint that returns structured, stringified
data based on provided input.

- **Tests**
- Added a test case to verify the functionality of the new REST endpoint
and ensure robust input validation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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