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

feat: expanded typegraph #978

Open
wants to merge 50 commits into
base: main
Choose a base branch
from
Open

feat: expanded typegraph #978

wants to merge 50 commits into from

Conversation

Natoandro
Copy link
Contributor

@Natoandro Natoandro commented Feb 17, 2025

  • Add a crate for an expanded version of the typegraph where hoisted parameters are expanded
  • Use the expanded typegraph in metagen
    • fdk_rs
    • client_rs
    • fdk_ts
    • client_ts
    • fdk_py
    • client_py
    • fdk_substantial
  • Support for injection in metagen: hide injected types in input types

The expanded typegraph duplicates the type for different injection data. All numeric references for types, runtimes, materializers and policies are inlined, removing the need to always have a reference to the typegraph object itself.

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

    • Enhanced support for TypeScript, Python, and Rust outputs with new data structures and types for better type safety.
    • Improved GraphQL transport mechanisms and file upload flows, including refined argument handling for upload functions.
    • Introduced comprehensive definitions for various node types and their associated argument structures, including updates to Primitives, Composites, and cycle-related entities.
    • Added new methods for handling policies, types, and node metadata, enhancing the type graph's capabilities.
  • Refactor

    • Comprehensive restructuring of type conversion, metadata management, and naming conventions for increased robustness and performance.
    • Streamlined error handling and diagnostic messaging, ensuring more reliable operations and clearer feedback for users.
    • Updated function signatures and structures to improve clarity and consistency across the codebase, including renaming and restructuring of key functions.

Copy link
Contributor

coderabbitai bot commented Feb 17, 2025

📝 Walkthrough

Walkthrough

The pull request implements extensive refactoring and restructuring across multiple modules. Major updates include adding a new workspace member and dependency for a dedicated “typegraph” package; renaming, deprecating, and refactoring client generation code in the meta‑CLI and metagen modules (across Python, Rust, and TypeScript clients); and overhauls of type conversion, manifest generation, and shared utilities. Additionally, the changes introduce new data structures and methods to enhance type safety, naming, deduplication, and error handling throughout the codebase, while also updating the associated tests and sample configurations.

Changes

File(s) Change Summary
Cargo.toml, src/typegraph/graph/Cargo.toml, src/metagen/Cargo.toml Added a new workspace member and dependency for the “typegraph” package; enhanced workspace configuration with new dependencies and workspace flags.
src/meta-cli/src/cli/fdk_template.rs, src/meta-cli/src/cli/gen.rs Commented out enum variants and match arms (e.g. Template::Typescript), and wrapped raw fields in an Arc for improved thread-safety.
src/metagen/src/client_py/*, src/metagen/src/client_rs/*, src/metagen/src/client_ts/* Renamed structures (e.g. ClienPyGenConfigClientPyGenConfig), introduced new manifest structs (ClientPyManifest, RsClientManifest, TsClientManifest), modified method signatures to use generic Write traits, and removed legacy renderer functions/files.
src/metagen/src/fdk_py/*, src/metagen/src/fdk_py/types.rs Introduced a new FDK Python template (FdkPythonTemplate) and configuration (FdkPythonGenConfig); overhauled Python type rendering with new enums and structs in types.rs.
src/metagen/src/fdk_rs/*, src/metagen/src/fdk_ts/* Added new structures and methods (e.g. a Maps struct, new gen_mod_rs signature, updated stub generation, and comprehensive type rendering via new enums and configuration structs).
src/metagen/src/shared/* Removed outdated rendering structures; introduced a new manifest generation system with the ManifestEntry trait and ManifestPage; updated client extraction logic (get_gql_types), file path processing, and utility functions for writing output.
src/typegate/src/engine/policies.ts Updated type-only import for Logger and improved caching logic with additional logging for policy evaluation.
src/typegraph/**/* Overhauled the typegraph core and graph modules: refactored conversion-related code (deduplication, conversion maps, keys), introduced new modules for naming, paths, policies, runtimes, and visitors; and revamped type modules for Boolean, File, Float, Function, Integer, List, Object, Optional, String, and Union types. Also, updates were applied to schema modules (lib.rs, types.rs, injection validator) to improve equality checks and child node retrieval.
tests/** Updated tests and fixtures in metagen and typegraph directories; added new tests to validate graph expansion; adjusted sample generator configurations (commenting out client_py) and corrected typos; and introduced new utility scripts for file and shell operations.

Sequence Diagram(s)

Client Code Generation Flow

sequenceDiagram
  participant G as Generator
  participant M as Manifest (ClientPy/Rs/Ts)
  participant O as Output (Write dest)
  Note over G,M: Client generation refactoring
  G->>M: Create new client manifest (e.g. ClientPyManifest.new(Arc<Typegraph>))
  M->>M: Build Maps, NodeMetas, Selections, etc.
  M->>M: Render static content, query graph, and root functions
  M->>O: Write generated client code to output destination
  O-->>G: Completion with generated output
Loading

Type Conversion Flow

sequenceDiagram
  participant TG as Typegraph
  participant C as Conversion
  participant CM as ConversionMap
  participant NE as NamingEngine
  participant MP as ManifestPage
  Note over TG,C: Type conversion process refactored into modular steps
  TG->>C: Pass typegraph for conversion
  C->>CM: Register types and deduplicate via ConversionMap
  CM-->>C: Return type keys and mappings
  C->>NE: Invoke NamingEngine to assign unique names
  NE-->>C: Names registered
  C->>MP: Generate ManifestEntries from converted types
  MP->>C: Cache references and render all entries
  C-->>TG: Finalized type conversion output
Loading

Suggested reviewers

  • luckasRanarison
  • Yohe-Am
  • michael-0acf4
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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 plan to trigger planning for file edits and PR creation.
  • @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.

@Natoandro Natoandro force-pushed the expanded-typegraph-2 branch from 7a52445 to af7aa21 Compare March 18, 2025 10:21
@Natoandro Natoandro force-pushed the expanded-typegraph-2 branch from c512910 to f237e2d Compare March 18, 2025 19:56
Copy link
Contributor

@Yohe-Am Yohe-Am left a comment

Choose a reason for hiding this comment

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

Are namespaces exposed through the SDKs? Also, is the lack of diffs in the tests because this is entirely backwards compatible? I was expecting the invisible input types things to show up. Also, I'm guessing this has a bunch of follow up work, right? Would love tickets to clarify the progress.

pub(crate) input: Lazy<Arc<ObjectType>>,
pub(crate) output: Lazy<Type>,
pub parameter_transform: Option<FunctionParameterTransform>,
pub runtime_config: serde_json::Value, // TODO should not this be removed?
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't have use for it today?

@Natoandro Natoandro marked this pull request as ready for review March 24, 2025 10:26
@Natoandro
Copy link
Contributor Author

@Yohe-Am Thanks for your review.

Are namespaces exposed through the SDKs?

Yes, you can look at the typegraph definition in the tests for the GraphQL namespaces.

Also, is the lack of diffs in the tests because this is entirely backwards compatible? I was expecting the invisible input types things to show up.

There is something missing in the implementation. Will fix that...

Also, I'm guessing this has a bunch of follow up work, right? Would love tickets to clarify the progress.

I will need to make a full review myself...

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

🔭 Outside diff range comments (4)
src/metagen/src/client_rs/selections.rs (1)

56-105: 🛠️ Refactor suggestion

render_for_struct method
The usage of macros like impl_selection_traits! is a clean approach to avoid boilerplate. Consider fallback logic or an error if page.extras.input_types.get(...) yields None.

- let arg_ty = page.extras.input_types.get(arg_ty).unwrap();
+ let arg_ty = match page.extras.input_types.get(arg_ty) {
+     Some(a) => a,
+     None => return Err(std::fmt::Error),
+ };
src/metagen/src/fdk_rs/types.rs (1)

554-629: 🛠️ Refactor suggestion

Look into table-driven tests for better clarity.

The repeated patterns for type definitions (lines 555–629) could be more self-documenting using table-driven test constructs or parameterized test libraries, making it clearer which part of the logic each test scenario validates.

src/metagen/src/client_rs/mod.rs (1)

248-340: 🛠️ Refactor suggestion

render_root_functions generically covers different effect types.
This is a solid approach, dynamically creating method stubs for each root function. A few notes:

  • The usage of PhantomData is appropriate but confirm no uninitialized fields are needed at runtime.
  • Large expansions of code might challenge maintainability—some extraction or doc references could help.
src/metagen/src/client_ts/mod.rs (1)

227-286: 💡 Verification agent

🧩 Analysis chain

Potential panic on unwrap
The code calls unwrap() when retrieving type names. If the type isn't found, this could panic. Consider handling the error or validating that all needed keys are present.

Here's a script to scan usage of ty.output().key() calls across the codebase to ensure they're always guaranteed to exist:


🏁 Script executed:

#!/bin/bash
rg 'output\(\).key\(\)'

Length of output: 869


Action Required: Safeguard unwrap Usage for Type Lookups

The code in src/metagen/src/client_ts/mod.rs (and similar logic in other modules) invokes unwrap when retrieving type names via self.maps.types.get(&ty.output().key()).unwrap(). Although the invariant may be that all keys are present, the scan shows this pattern is repeated across the repository (e.g., in client_rs, client_py, and fdk_rs). If this invariant is ever broken, the unwrap will result in a runtime panic.

  • Verify Map Population: Ensure that all keys produced by ty.output().key() are correctly populated in the corresponding maps before these unwrap calls.
  • Improve Error Handling: If there's any risk of a missing key, consider replacing unwrap with an expect that includes a descriptive error message or implementing explicit error handling.
🧹 Nitpick comments (95)
src/metagen/src/client_ts/static/mod.ts (2)

23-25: Alias-based Node Instances Handling:
The conditional correctly checks if nodeSelection is an instance of Alias and, if so, uses its aliases() method; otherwise, it wraps the selection in an object keyed by nodeName. This logic appears sound.

Suggestion: If there's any possibility for nodeSelection to be null or undefined, consider an explicit check or comment to document the assumption.


680-686: Query Node Inner Value Extraction:
In the buildGql call for queries, a conditional is used to distinguish between a single QueryNode (using query.inner()) and an object mapping of query nodes (via Object.fromEntries). The approach is concise and consistent.

Suggestion: Consider adding a brief inline comment to clarify that when query is not a single node, all its values are expected to be QueryNode instances.

tests/utils/shell.ts (1)

82-84: Enhanced debugging output with clear delimiters.

Adding these console logs improves the debuggability of shell command execution by clearly displaying stdout and stderr outputs with distinct headers.

Consider making this verbose output conditional using a debug flag parameter to avoid excessive logging in production environments.

-  console.log("____STDOUT________\n", res.stdout, "\n____END_STDOUT____");
-  console.log("____STDERR________\n", res.stderr, "\n____END_STDERR____");
+  if (options.verbose ?? true) {
+    console.log("____STDOUT________\n", res.stdout, "\n____END_STDOUT____");
+    console.log("____STDERR________\n", res.stderr, "\n____END_STDERR____");
+  }
tests/utils/file.ts (2)

4-7: New utility function for printing file contents with line numbers.

The function correctly reads file contents and delegates to the helper function for formatted output.

Consider adding error handling for file operations and JSDoc documentation for clarity:

+/**
+ * Reads and prints a source file with line numbers.
+ * @param path - Path to the file to be printed
+ */
 export async function printSourceFile(path: string) {
+  try {
     const code = await Deno.readTextFile(path);
     printSourceCode(code);
+  } catch (error) {
+    console.error(`Error reading file ${path}:`, error);
+  }
 }

9-15: Utility function for printing code with line numbers.

This helper function correctly formats and displays code with line numbers, making it easier to reference specific lines during debugging or analysis.

Consider adding JSDoc documentation and handling potentially larger files with more lines:

+/**
+ * Prints source code with line numbers.
+ * @param code - Source code to be printed
+ */
 function printSourceCode(code: string) {
   const lines = code.split("\n");
+  const lineWidth = String(lines.length).length;
   for (let i = 0; i < lines.length; i++) {
-    const lineNo = String(i + 1).padStart(4, " ");
+    const lineNo = String(i + 1).padStart(lineWidth, " ");
     console.log(`${lineNo}| ${lines[i]}`);
   }
 }
src/metagen/src/tests/fixtures.rs (2)

6-78: Ensure uniqueness of property keys in MyOutput.

When mapping (idx, ty) to (ty.base().title.clone(), idx as u32 + 4), duplicate title fields could inadvertently overwrite properties in the properties map if multiple types share the same title.


108-132: Check cargo command exit status.

You’re relying on stdout to deserialize the typegraph but not explicitly checking status.success(). If you want to confirm correctness, consider verifying the exit status before deserialization.

 let out = tokio::process::Command::new("cargo")
     ...
     .output()
     .await?;

+ if !out.status.success() {
+     bail!("meta-cli serialize command failed with status: {:?}", out.status);
+ }
 let mut tg: Vec<tg_schema::Typegraph> = serde_json::from_slice(&out.stdout)?;
tests/metagen/typegraphs/sample/ts_upload/client.ts (1)

211-218: Rename type parameter to avoid redeclaration.

Static analysis flags 'O' as redeclared. You might rename 'O' to clarify.

-type SelectNodeOut<T> = T extends QueryNode<infer O> | MutationNode<infer O> ? O
+type SelectNodeOut<T> = T extends QueryNode<infer OutT> | MutationNode<infer OutT> ? OutT
🧰 Tools
🪛 Biome (1.9.4)

[error] 211-211: Shouldn't redeclare 'O'. Consider to delete it or rename it.

'O' is defined here:

(lint/suspicious/noRedeclare)

tests/metagen/typegraphs/identities/py/fdk.py (4)

33-210: selection_to_nodes Function: Validation and Flow

The selection parsing logic checks argument and alias usage carefully. Using descriptive exceptions is good. However, the conditional converting True if ... else False (line 44) could be replaced with a direct boolean expression (bool(...)).

- select_all = True if sub_flags is not None and sub_flags.select_all else False
+ select_all = bool(sub_flags and sub_flags.select_all)
🧰 Tools
🪛 Ruff (0.8.2)

44-44: Use bool(...) instead of True if ... else False

Replace with `bool(...)

(SIM210)


530-530: Variable Shadowing in Loops

In line 530, the loop could inadvertently shadow a variable named node, potentially making the code confusing. Consider renaming the loop variable or the outer reference to reduce ambiguity.

🧰 Tools
🪛 Ruff (0.8.2)

530-530: Loop control variable node overrides iterable it iterates

(B020)


594-688: GraphQLTransportBase: Handling HTTP and JSON Errors

The logic for building requests and checking responses is generally robust. One detail: in Python 3, raising from an exception within the except block is often recommended (raise Exception(...) from err). This clarifies exception chains in logs.

🧰 Tools
🪛 Ruff (0.8.2)

636-636: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


690-725: GraphQLTransportUrlib: Ensuring Safe Error Re-raising

Lines 724+ raise a new exception, which is good. For clarity and better traceback, consider using raise Exception(...) from err if you want to preserve the original URLError context.

🧰 Tools
🪛 Ruff (0.8.2)

696-696: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


724-724: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)

tests/metagen/typegraphs/identities/ts/fdk.ts (2)

53-58: Enumerated string type for enum.
Good approach for enumerations. If each variant has unique meaning, consider adding doc remarks for future reference.


123-140: SimpleCycles definitions.
Good extension for simpler cycles. It may be helpful to add or expand test coverage for these cyclical references.

tests/metagen/typegraphs/sample/ts/client.ts (1)

211-217: Type extraction in SelectNodeOut.
Static analysis indicates a redeclaration of O. Consider renaming the infer type to avoid shadowing or confusion with existing generic definitions.

🧰 Tools
🪛 Biome (1.9.4)

[error] 211-211: Shouldn't redeclare 'O'. Consider to delete it or rename it.

'O' is defined here:

(lint/suspicious/noRedeclare)

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

53-55: Improved error context for artifact hashing.

This change enhances error handling by adding specific context about which artifact file caused the hashing failure. Instead of a generic error, users will now see exactly which path failed, making debugging much easier.

The use of with_context is a good practice for building up contextual error chains in Rust.

Consider applying similar error context improvements to other file operations in this module for consistency, such as the list_files call on line 30.

src/meta-cli/src/cli/fdk_template.rs (2)

11-16: Consider documenting the TypeScript template removal.

The TypeScript variant has been commented out without any explanation. While this aligns with the PR objective that mentions implementation for fdk_substantial is still pending, adding a comment explaining why it's temporarily disabled would improve maintainability.

 enum Template {
     Rust,
     Python,
-    // Typescript,
+    // Typescript, // Temporarily removed, pending implementation for the expanded typegraph
 }

40-44: Ensure match statement remains complete with TypeScript template removal.

The commented-out TypeScript match arm corresponds to the removed enum variant. Consider adding a TODO comment to remind developers to re-enable this once the implementation is complete.

 let template = match self.template {
     Template::Rust => metagen::FDK_RS_DEFAULT_TEMPLATE,
     Template::Python => metagen::FDK_PY_DEFAULT_TEMPLATE,
-    // Template::Typescript => metagen::FDK_TS_DEFAULT_TEMPLATE,
+    // Template::Typescript => metagen::FDK_TS_DEFAULT_TEMPLATE, // TODO: Re-enable when TypeScript support for expanded typegraph is implemented
 };
src/metagen-client-rs/src/args.rs (1)

77-78: Consider documenting PreparedArgs functionality.

While PreparedArgs is implemented below, adding a doc comment to the struct definition would help clarify its purpose as a builder for preparing node arguments.

 #[derive(Debug)]
+/// Builder for preparing node arguments with placeholders
 pub struct PreparedArgs;
src/typegraph/graph/src/runtimes.rs (1)

19-27: Efficient materializer conversion function

The convert_materializer function correctly clones runtime and other necessary fields from the input materializer. One potential performance consideration is that it clones all fields, including potentially large data structures like the data IndexMap.

Consider documenting the ownership transfer and cloning behavior, especially for the data field which might be expensive to clone if it contains large values.

src/typegraph/graph/src/types/string.rs (2)

28-39: Efficient string type constraint checking

The is_plain() method uses the matches! macro for efficient pattern matching to determine if a string type has no constraints. This approach is concise and follows Rust best practices.

However, there's a potential issue with self.format.clone() in the pattern match. Cloning unnecessarily in a hot path like constraint checking might affect performance.

Consider using a reference instead of cloning in the pattern match:

-            (
-                self.min_length,
-                self.max_length,
-                self.pattern.as_ref(),
-                self.format.clone(),
-            ),
-            (None, None, None, None)
+            (
+                self.min_length,
+                self.max_length,
+                self.pattern.as_ref(),
+                &self.format,
+            ),
+            (None, None, None, None)

41-46: Clear format_only method implementation

The format_only() method correctly implements the logic to return the format only if no other constraints are present. However, similar to the issue in is_plain(), it returns a cloned value which could be inefficient.

Consider returning a reference to the format instead of cloning it:

-    pub fn format_only(&self) -> Option<tg_schema::StringFormat> {
+    pub fn format_only(&self) -> Option<&tg_schema::StringFormat> {
         match (self.min_length, self.max_length, self.pattern.as_ref()) {
-            (None, None, None) => self.format.clone(),
+            (None, None, None) => self.format.as_ref(),
             _ => None,
         }
     }

This would be more efficient, especially if StringFormat is a larger structure or is used frequently.

tests/metagen/metagen_test.ts (2)

111-137: Consider removing or clarifying commented-out test.

Entirely commenting out this test block might create confusion for future maintainers. If you plan to restore it soon, leave a TODO comment explaining why it is temporarily disabled. Otherwise, removing it entirely may improve clarity.


715-715: Skipped test “client_py_upload”.

The test is now disabled. If it is no longer valid or not yet ready, consider adding a clear comment explaining the reason or remove the test to avoid confusion.

src/typegraph/graph/src/conv/dedup.rs (3)

15-20: Validate the necessity of cloning injection data.
The new constructor calls ty.injection().cloned(). Ensure large clones of deeply nested InjectionNode data are indeed necessary. If immutability is guaranteed in upstream usage, consider using references or shared pointers (Arc) to reduce overhead.


22-26: Consider add/update documentation on usage.
from_rpath fetches injection info via rpath.get_injection(schema). Provide doc comments specifying when and why DuplicationKey is built from paths, especially as it may differ from the direct injection on Type.


42-48: Document variant meaning.
The Deduplication enum differentiates reusing an existing type vs. registering a new one. Consider doc comments or short remarks clarifying situations that lead to Reuse versus Register.

src/metagen/src/shared/node_metas.rs (3)

8-8: Potential circular references caution.
Re-exporting crate::interlude::* can help unify imports but watch out for cyclical references if interlude in turn references modules that might rely on these items.


10-14: Clarify the relationship between MetaFactory and ManifestEntry.
MetaFactory is simply a trait with build_meta. Ensure that implementers fully handle all Type variants. Consider referencing or linking ManifestEntry uses for a cohesive developer experience.


16-19: Guard mutable usage of stack.
A RefCell<Vec<Type>> is appropriate if there's no multi-thread concurrency. If concurrency is possible, consider Mutex or removing interior mutability.

src/metagen/src/lib.rs (1)

6-6: Wildcard import usage check.
Using typegraph::prelude::* can pollute the namespace. If only a few symbols are needed, explicit imports might improve clarity.

src/typegraph/core/src/types/type_ref/injection.rs (3)

15-15: Retain struct field as pub
Confirm whether there is a strong reason to keep the field in InjectionTree public. If not necessary, making it private might help encapsulation.

Possible approach:

- pub struct InjectionTree(pub BTreeMap<String, InjectionNode>);
+ pub struct InjectionTree(BTreeMap<String, InjectionNode>);

85-86: Avoid repeated object creation
Using or_insert(InjectionNode::Parent { children: BTreeMap::new() }) forces the creation of a new BTreeMap each time. You can use or_insert_with closure to avoid creating an unnecessary structure if the entry is already present.

Possible approach:

- let node = parent.entry(key).or_insert(InjectionNode::Parent {
-     children: BTreeMap::new(),
- });
+ let node = parent.entry(key).or_insert_with(|| InjectionNode::Parent {
+     children: BTreeMap::new(),
+ });

100-100: Consider making merge a method on InjectionTree
This function merges two InjectionTreeMaps. For discoverability and maintainability, consider implementing it as an associated method on InjectionTree.

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

20-25: Handle missing input type more gracefully
unwrap_or("()") might hide the fact that a function has no recognized input type. Consider logging or returning an error if the mapping is absent.


80-100: Commented-out tests
Disabling tests can reduce coverage and possibly reintroduce regressions. If these tests no longer apply, removing them might be preferable over leaving them commented out.

src/metagen/src/fdk_ts/mod.rs (1)

222-224: Debug output for fdk.ts content
Printing out the generated fdk.ts file is useful for debugging. Consider logging it under a debug or verbose flag to avoid cluttering logs in production.

src/metagen/src/shared/client.rs (1)

21-30: Evaluate recursive or nested unions.

In the loop over tg.output_types, only top-level variants of Union are considered, skipping non-scalar children in deeper union nesting. Confirm that more complex nesting scenarios (e.g., union within union) are handled, or if further recursion is needed for the intended design.

src/typegraph/graph/src/conv/mod.rs (3)

44-47: TypeConversionResult trait aligns with the conversion design.

Its minimal interface is clear, though consider adding doc comments to clarify expectations for finalize.


155-199: register_converted_type manages multiple IndexMap inserts.

Be mindful of concurrency if these data structures are ever shared or parallelized. Currently, the approach is sound. Just confirm no duplicates cause unintended overrides.


226-348: convert_type covers all schema nodes thoroughly.

Edge handling:

  • N::Any is unreachable, but consider logging or returning an error for future expansions.
  • For union/either, we pass true vs. false—a more descriptive parameter name might clarify the difference.
    Overall, the coverage is solid.
src/metagen/src/utils.rs (2)

31-105: processed_write handles directives effectively, but check nested errors.

Conditional nesting is well-managed using a stack. However, consider adding more explicit error messages for deeply nested or near-end-of-file unclosed blocks. Also verify that large inputs won’t degrade performance significantly from line-by-line scanning and regex usage.


160-180: Indentation utilities enhance code formatting.

Both indent_lines and indent_lines_into look well-written and robust. Consider adding tests ensuring correct handling of edge cases like empty strings or trailing newlines.

src/metagen/src/shared/types.rs (1)

25-28: Fix typos in the comments

Minor spelling corrections for "gnerated" → "generated" and "conditionds" → "conditions".

-// functions will be absent in our gnerated types
+// functions will be absent in our generated types

-// under certain conditionds, we don't want to generate aliases
+// under certain conditions, we don't want to generate aliases
src/typegraph/graph/src/types/mod.rs (2)

112-168: Be mindful of performance in recursive checks.

While TypeNodeExt::is_descendant_of() appears robust, repeated traversals on large graphs may be expensive. Consider memoizing visited nodes if performance becomes an issue.


269-301: Macros for wrapping types simplify type insertion.

The Wrap trait and impl_wrap! macro help reduce boilerplate. If usage expands further, consider adding short doc comments for future maintainers or new contributors.

src/typegraph/graph/src/visitor.rs (1)

36-53: Check potential overhead in path swapping.

Within visit(), you temporarily take(path) and then put it back. While correct, be mindful of small overhead if frequently invoked. This might be negligible, but keep an eye on performance.

src/metagen/src/client_ts/selections.rs (1)

66-98: Handle unreachable!() logic carefully
Marking Scalar or ScalarArgs as unreachable!() in union variants is logically valid if unions always hold composite fields. However, consider partial detection if future changes introduce multi-type unions.

src/metagen/src/shared/files.rs (1)

104-110: Infallible conversion
Using unreachable!() for the eyre::ErrReport suggests these errors should never occur. Ensure consistent usage in the rest of the code to avoid masked failures.

src/metagen/src/client_rs/selections.rs (1)

106-158: render_for_union design
The code effectively handles Composite and CompositeArgs. As above, consider gracefully handling missed references to avoid panics.

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

11-22: Consider validating naming and possible expansions for Alias variants.

The Alias enum covers built-in, container, and plain references. If we anticipate complex or specialized aliasing scenarios (e.g., custom generics or advanced Rust features), we may want to provide an extension mechanism or more descriptive variant names.


24-28: Confirm necessity of separate fields in Derive.

debug and serde combine to form derive attributes. If additional derives (e.g., Clone, PartialEq) arise, consider a more scalable approach (e.g., a bitflag or set-based approach) for extension.


30-49: Revisit RustType variant organization for future-proofing.

The enum RustType is well-structured, but expanding beyond Alias, Struct, Enum might necessitate additional patterns in the future (e.g., Trait). Keep an eye on potential expansions or specialized types as the typegraph grows in complexity.


63-96: Enhance error handling for unreachable alias states.

In the match arm for the Alias variant (lines 69–92), encountering _ => unreachable!() provides little context if it's genuinely reached at runtime. Consider returning an error or a debug-level log before panicking to aid in diagnosing unexpected states.


98-125: DRY up property writing logic within Struct rendering.

Within the Struct match arm (lines 104–125), repeated logic for partial, optional, and boxing leads to multiple branches. Extracting a helper function to compute the final property type string can reduce duplication and improve readability.


149-179: Consider consistency for partial naming approach.

When partial is true, we append Partial to the name. Confirm references to partial types are well documented and consistent with naming used in other parts of the codebase, ensuring clarity for maintainers.


244-383: Enforce checking for cyclical references.

The TODO is_cyclic comment (lines 271, 279, 298, 310) indicates potential cyclical references that might need deeper resolution. Implement a robust detection or resolution strategy to avoid infinite recursion or runtime errors.

Do you want me to open a new issue to track the cyclical reference detection and help implement it?


500-549: Test coverage potential for new container & partial logic.

While the test is good at verifying string, list, and optional types, consider adding test cases for deeper nesting (multiple levels of containers, nested optional). This ensures coverage of corner cases introduced by partial usage.


636-645: Adopt standard type naming strategies.

We see code generating “MyStr,” “MyStrList,” “MyStrSet,” etc. Ensure these naming patterns are consistent with your broader naming or developer guidelines. If dynamic naming might conflict, consider validation or fallback rules.


721-723: Anticipate specialized constraints for integer or float expansions.

If you expand functionality for numeric constraints (like min/max or multiple_of in TypeNode), confirm that the bridging logic in get_typespec properly generates the correct Rust representation (e.g., custom newtypes).


780-783: Evaluate potential memory overhead from deeply nested Box usage in cyclical objects.

While Box can break recursion, large or deeply cyclical graphs could still consume memory if misused. Consider referencing or caching repeated inlines.


795-795: Add comment on cyclical ObjectType logic.

If ObjB references ObjC, and so forth (lines 794–805), consider clarifying the cyclical unrolling approach in code comments or documentation for future maintainers.

src/typegraph/graph/src/lib.rs (4)

4-10: Validate module structure and clarity.

Multiple modules like conv, naming, policies, runtimes, types, etc., are being introduced or re-exported. Confirm that each submodule is well-documented and logically partitioned, avoiding hidden cyclical dependencies.


22-55: Leverage From or specialized trait for MapItem conversions.

TryFrom<conv::MapItem> uses bail! for invalid states (line 50). You might unify with other conversion patterns (like From<conv::MapItem>) for simpler code if you’re certain about your domain constraints.


83-103: Confirm closure of try_from schema conversions.

Line 86 calls conv::Conversion::convert(schema, DefaultNamingEngine::default()). Check that DefaultNamingEngine is the only engine you intend to use for conversions, or consider a more flexible approach with user-provided naming.


105-116: Make iteration logic more discoverable and documented.

root_functions(&self) returning RootFnsIter is straightforward, but new contributors may find it confusing how iteration order is decided or how nestings are handled. Consider referencing docs or adding doc comments.

src/typegraph/graph/src/path.rs (8)

13-19: Refine naming for path segments.

ObjectProp, ListItem, OptionalItem, UnionVariant are clear, but continuing expansions (like map properties, nested fields) may demand a more flexible naming or an additional field for indexing.


83-145: Enhance error messages for mismatch in apply_on_schema_node.

If the correct node type is not found, we simply bail with an error referencing the path segment. Including the title (line 104) is good, but referencing the entire path or a node index may provide more context.


147-159: Check injection application for complex objects.

apply_on_schema_node_ex merges both the base node and injection logic. In large graphs, consider partial injection paths or advanced injection merges that might require separate logic to reduce confusion.


179-186: Ensure separation of concerns for ValueTypePath.

ValueTypePath (lines 182–186) couples a reference to the FunctionType owner and a path. If the code evolves to handle more granular references or cross-functional references, consider a dedicated data structure or trait approach.


223-230: Evaluate additional enum variants in RelativePath.

We have Function, NsObject, Input, Output. If we add future top-level concepts (like Policy, Runtime references), ensure we keep RelativePath general enough or subdivide it for clarity.


264-267: Clarify usage of root for RelativePath.

Self::NsObject(vec![]) is used for the root. Document that an empty array means the root-level path in the typegraph, possibly create a specialized type for root references if it’s used frequently.


355-385: Check injection path building for each path segment.

When retrieving injection data from the function node, ensure partial or advanced injection merges are accounted for. If the path fails at any segment (line 381), we drop out. Consider logging partial successes for debug.


493-519: Consider returning a Result on pop.

pop() simply clones the path and removes the last segment. If a path is empty or we’re at the root, that might cause confusion. A Result-based approach or a no-op with a log might prevent silent path underflow.

src/typegraph/graph/src/types/optional.rs (1)

4-13: Ensure default value usage is validated.
The default_value field is a nice addition for optional types, but consider how you plan to validate or enforce schema constraints on this field at runtime.

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

179-198: Switch to BTreeMap in InjectionNode.
Using BTreeMap makes the iteration order deterministic, which can simplify debugging and testing. This is especially relevant for storing injection children in a stable order.

src/metagen/src/shared/manifest.rs (2)

4-7: Clear high-level documentation.
The doc comments clearly explain the idea behind code generation manifests. Consider adding examples to further illustrate usage.


71-86: Thread-safety considerations for get_ref.
Here, the function first reads from the cache, then writes if absent. The RwLock usage is correct, but watch for potential performance bottlenecks if the map grows large and many threads call get_ref concurrently.

You could consider an optimistic double-checked lock approach, though the current usage is likely sufficient unless performance demands are high.

src/metagen/src/client_rs/mod.rs (1)

181-203: render method unifies all sub-renderings.
Collecting static content, types, node metas, and more into a single output flow is convenient. Looks well-structured.

You might consider splitting some logic into smaller private helper methods if render grows further.

src/metagen/src/client_ts/mod.rs (2)

44-48: Consider documenting struct
Adding a short doc comment about what each map stores could improve clarity.


148-174: Render method complexity
This method is fairly large. Consider splitting or adding comments for each section to improve readability.

src/metagen/src/client_py/selections.rs (1)

12-14: Extras struct
Storing input_types is straightforward. Add doc comments if needed.

src/metagen/src/client_py/node_metas.rs (1)

142-142: Address the TODO for outjection.
There is a // TODO comment indicating that outjection is not yet implemented. This might limit the functionality if outjection is needed.

Do you want me to open a new issue or generate a helper function that handles outjection logic consistently?

src/metagen/src/client_py/mod.rs (1)

176-176: Implement the TODO render_without_header.
A placeholder comment suggests an additional rendering method. If it's required for certain configurations, it would be helpful to implement it or remove if not necessary.

src/typegraph/graph/src/types/object.rs (1)

18-18: Clarify purpose of outjection: Option<()>.
Using Option<()> is unusual; it indicates a placeholder for future logic. Explain or implement outjection handling for consistency with injections.

src/typegraph/graph/src/types/function.rs (1)

83-109: Consider returning a concrete type instead of a boxed trait.

Returning Box<dyn TypeConversionResult> may introduce extra performance overhead due to dynamic dispatch. If performance is critical or specialization is beneficial, consider returning a concrete type implementing TypeConversionResult.

src/metagen/src/client_rs/node_metas.rs (2)

164-185: Enhance argument fields rendering.

The code for rendering argument fields looks correct, but if there's a chance of naming collisions or special characters in keys, consider validating them or sanitizing them before writing to the output.


296-306: Consider clarifying file list serialization.

Storing file paths in the format "[TypePath(...)]" is concise but may be ambiguous for large sets. If future debugging or clarity is desired, consider a more verbose or structured representation.

src/typegraph/graph/src/naming/mod.rs (2)

16-26: Consider streamlining existing type usage or fallback behavior

Currently, the register method enforces that each type name is truly unique. If your intended workflow includes reusing or overriding an already-registered name, consider introducing a more flexible approach (for example, returning the existing type or providing an override flag). This may reduce the need to handle certain conflict scenarios at higher layers.


55-58: Use more robust naming for variant types

Suffixing _1, _2, ... to differentiate variant names (e.g., format!("{}_{}", item.ty.title(), idx + 1)) works, but consider a more expressive naming scheme if you expect many variants or want to reduce naming ambiguity in logs and error messages.

src/metagen/src/fdk_py/types.rs (3)

41-46: Validate non-empty alias names

When calling .named(name), ensure name isn't empty or duplicative. An empty alias name or redefinition of the same name might lead to ambiguous references or collisions in Python modules.


109-130: Consider Python version constraints for typed dict fields

This creates a TypedDict with all fields treated as optional (line 128, total=False). If your code must run on Python < 3.11, you can't use NotRequired. Still, clarifying or customizing which fields are truly required vs. optional could foster more accurate type hints.


300-311: Handle potential alias cycles for optional types

When constructing an alias for Optional[...], there's a note (TODO) about cyclical references (line 303). If a type references itself through an Optional, you might create circular imports or conflict in Python. Check for cyclical type references and handle them gracefully (e.g., forward declarations).

Do you want me to open a follow-up ticket or provide a snippet demonstrating how to detect cycles?

src/metagen/src/client_ts/node_metas.rs (2)

52-79: Handle missing references more gracefully
Within Object::render, the call to page.get_ref(prop_ty).unwrap() can cause a runtime panic if the reference is unavailable. Consider error handling or a debug assertion to provide clearer diagnostics, or gracefully skip problematic properties.


88-116: Avoid unwrap() for union variant references
Similar to the object rendering logic, calling page.get_ref(variant_key).unwrap() can trigger a panic if the reference is absent. Refactoring to return an error or a fallback could improve robustness and debugging in case of unexpected conditions.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 92f53a2 and 5725a1f.

⛔ Files ignored due to path filters (4)
  • .ghjk/deno.lock is excluded by !**/*.lock
  • Cargo.lock is excluded by !**/*.lock
  • deno.lock is excluded by !**/*.lock
  • poetry.lock is excluded by !**/*.lock
📒 Files selected for processing (85)
  • .ghjk/lock.json (8 hunks)
  • Cargo.toml (2 hunks)
  • src/meta-cli/src/cli/fdk_template.rs (2 hunks)
  • src/meta-cli/src/cli/gen.rs (2 hunks)
  • src/metagen-client-rs/src/args.rs (2 hunks)
  • src/metagen-client-rs/src/graphql.rs (1 hunks)
  • src/metagen-client-rs/src/nodes.rs (1 hunks)
  • src/metagen-client-rs/src/selection.rs (0 hunks)
  • src/metagen/Cargo.toml (1 hunks)
  • src/metagen/fixtures/client_rs/main.rs (2 hunks)
  • src/metagen/src/client_py/mod.rs (6 hunks)
  • src/metagen/src/client_py/node_metas.rs (5 hunks)
  • src/metagen/src/client_py/selections.rs (2 hunks)
  • src/metagen/src/client_py/types.rs (0 hunks)
  • src/metagen/src/client_rs/mod.rs (7 hunks)
  • src/metagen/src/client_rs/node_metas.rs (7 hunks)
  • src/metagen/src/client_rs/selections.rs (2 hunks)
  • src/metagen/src/client_ts/mod.rs (6 hunks)
  • src/metagen/src/client_ts/node_metas.rs (4 hunks)
  • src/metagen/src/client_ts/selections.rs (1 hunks)
  • src/metagen/src/client_ts/static/mod.ts (8 hunks)
  • src/metagen/src/fdk_py/mod.rs (3 hunks)
  • src/metagen/src/fdk_py/static/fdk.py (1 hunks)
  • src/metagen/src/fdk_py/types.rs (1 hunks)
  • src/metagen/src/fdk_rs/mod.rs (5 hunks)
  • src/metagen/src/fdk_rs/stubs.rs (2 hunks)
  • src/metagen/src/fdk_rs/types.rs (22 hunks)
  • src/metagen/src/fdk_ts/mod.rs (5 hunks)
  • src/metagen/src/fdk_ts/types.rs (1 hunks)
  • src/metagen/src/lib.rs (4 hunks)
  • src/metagen/src/shared/client.rs (2 hunks)
  • src/metagen/src/shared/files.rs (4 hunks)
  • src/metagen/src/shared/manifest.rs (1 hunks)
  • src/metagen/src/shared/mod.rs (1 hunks)
  • src/metagen/src/shared/node_metas.rs (1 hunks)
  • src/metagen/src/shared/types.rs (2 hunks)
  • src/metagen/src/tests/fixtures.rs (2 hunks)
  • src/metagen/src/utils.rs (2 hunks)
  • src/typegate/src/engine/planner/policies.ts (2 hunks)
  • src/typegraph/core/src/typedef/func.rs (2 hunks)
  • src/typegraph/core/src/types/type_ref/injection.rs (3 hunks)
  • src/typegraph/core/src/utils/artifacts.rs (2 hunks)
  • src/typegraph/core/src/utils/metagen_utils.rs (2 hunks)
  • src/typegraph/graph/Cargo.toml (1 hunks)
  • src/typegraph/graph/src/conv/dedup.rs (1 hunks)
  • src/typegraph/graph/src/conv/key.rs (1 hunks)
  • src/typegraph/graph/src/conv/map.rs (1 hunks)
  • src/typegraph/graph/src/conv/mod.rs (1 hunks)
  • src/typegraph/graph/src/lib.rs (1 hunks)
  • src/typegraph/graph/src/naming/mod.rs (1 hunks)
  • src/typegraph/graph/src/path.rs (1 hunks)
  • src/typegraph/graph/src/policies.rs (1 hunks)
  • src/typegraph/graph/src/runtimes.rs (1 hunks)
  • src/typegraph/graph/src/types/boolean.rs (1 hunks)
  • src/typegraph/graph/src/types/file.rs (1 hunks)
  • src/typegraph/graph/src/types/float.rs (1 hunks)
  • src/typegraph/graph/src/types/function.rs (1 hunks)
  • src/typegraph/graph/src/types/integer.rs (1 hunks)
  • src/typegraph/graph/src/types/list.rs (1 hunks)
  • src/typegraph/graph/src/types/mod.rs (1 hunks)
  • src/typegraph/graph/src/types/object.rs (1 hunks)
  • src/typegraph/graph/src/types/optional.rs (1 hunks)
  • src/typegraph/graph/src/types/string.rs (1 hunks)
  • src/typegraph/graph/src/types/union.rs (1 hunks)
  • src/typegraph/graph/src/visitor.rs (1 hunks)
  • src/typegraph/graph/tests/expanded.rs (1 hunks)
  • src/typegraph/schema/src/lib.rs (1 hunks)
  • src/typegraph/schema/src/types.rs (5 hunks)
  • src/typegraph/schema/src/validator/injection.rs (2 hunks)
  • tests/metagen/metagen_test.ts (5 hunks)
  • tests/metagen/typegraphs/identities/py/fdk.py (1 hunks)
  • tests/metagen/typegraphs/identities/rs/fdk.rs (4 hunks)
  • tests/metagen/typegraphs/identities/ts/fdk.ts (1 hunks)
  • tests/metagen/typegraphs/metagen.ts (1 hunks)
  • tests/metagen/typegraphs/other.py (1 hunks)
  • tests/metagen/typegraphs/sample/metatype.yml (2 hunks)
  • tests/metagen/typegraphs/sample/rs/client.rs (12 hunks)
  • tests/metagen/typegraphs/sample/rs/main.rs (3 hunks)
  • tests/metagen/typegraphs/sample/rs_upload/client.rs (4 hunks)
  • tests/metagen/typegraphs/sample/rs_upload/main.rs (3 hunks)
  • tests/metagen/typegraphs/sample/ts/client.ts (11 hunks)
  • tests/metagen/typegraphs/sample/ts_upload/client.ts (9 hunks)
  • tests/metagen/typegraphs/scripts/same_hit.py (1 hunks)
  • tests/utils/file.ts (1 hunks)
  • tests/utils/shell.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • src/metagen-client-rs/src/selection.rs
  • src/metagen/src/client_py/types.rs
🧰 Additional context used
🧬 Code Definitions (38)
src/typegraph/graph/src/types/boolean.rs (10)
src/typegraph/graph/src/types/object.rs (2)
  • base (45-47)
  • tag (49-51)
src/typegraph/graph/src/types/optional.rs (2)
  • base (24-26)
  • tag (28-30)
src/typegraph/graph/src/types/function.rs (2)
  • base (55-57)
  • tag (59-61)
src/typegraph/graph/src/types/union.rs (2)
  • base (25-27)
  • tag (29-35)
src/typegraph/graph/src/types/file.rs (2)
  • base (17-19)
  • tag (21-23)
src/typegraph/graph/src/types/float.rs (2)
  • base (19-21)
  • tag (23-25)
src/typegraph/graph/src/types/integer.rs (2)
  • base (19-21)
  • tag (23-25)
src/typegraph/graph/src/types/string.rs (2)
  • base (19-21)
  • tag (23-25)
src/typegraph/graph/src/types/list.rs (2)
  • base (23-25)
  • tag (27-29)
src/typegraph/graph/src/types/mod.rs (2)
  • base (101-101)
  • tag (102-102)
src/meta-cli/src/cli/gen.rs (2)
src/metagen/src/client_rs/mod.rs (2)
  • new (64-93)
  • new (102-106)
src/metagen/src/client_py/mod.rs (2)
  • new (49-53)
  • new (120-142)
src/typegraph/graph/tests/expanded.rs (3)
src/typegraph/graph/src/types/function.rs (2)
  • output (38-40)
  • tag (59-61)
src/typegraph/graph/src/lib.rs (3)
  • try_from (48-55)
  • try_from (85-87)
  • name (100-102)
src/typegraph/schema/src/lib.rs (1)
  • name (152-157)
src/typegraph/graph/src/runtimes.rs (2)
src/typegraph/graph/src/types/function.rs (1)
  • runtime (49-51)
src/typegraph/graph/src/conv/mod.rs (1)
  • new (68-93)
src/metagen/src/fdk_rs/stubs.rs (4)
src/metagen/src/fdk_rs/utils.rs (1)
  • normalize_type_title (26-43)
src/typegraph/schema/src/types.rs (1)
  • fmt (118-131)
src/typegraph/graph/src/conv/key.rs (1)
  • fmt (12-14)
src/typegraph/graph/src/types/mod.rs (2)
  • title (116-116)
  • title (142-144)
src/metagen/src/fdk_ts/mod.rs (3)
src/metagen/src/fdk_ts/types.rs (1)
  • manifest_page (248-268)
src/metagen/src/shared/mod.rs (1)
  • filter_stubbed_funcs (23-37)
src/metagen/src/fdk_ts/utils.rs (1)
  • normalize_type_title (101-113)
src/metagen/src/fdk_py/static/fdk.py (1)
tests/metagen/typegraphs/identities/py/fdk.py (6)
  • QueryGraph (1517-1692)
  • Ctx (18-30)
  • gql (29-30)
  • query (727-732)
  • query (735-740)
  • query (742-751)
src/typegraph/graph/src/path.rs (6)
src/typegraph/graph/src/lib.rs (2)
  • try_from (48-55)
  • try_from (85-87)
src/typegraph/graph/src/types/object.rs (2)
  • tag (49-51)
  • base (45-47)
src/typegraph/graph/src/types/optional.rs (2)
  • tag (28-30)
  • base (24-26)
src/typegraph/graph/src/types/function.rs (2)
  • tag (59-61)
  • base (55-57)
src/typegraph/graph/src/types/union.rs (2)
  • tag (29-35)
  • base (25-27)
src/typegraph/graph/src/conv/key.rs (1)
  • fmt (12-14)
src/metagen/src/shared/node_metas.rs (8)
src/metagen/src/client_ts/node_metas.rs (1)
  • build_meta (185-198)
src/metagen/src/client_rs/node_metas.rs (1)
  • build_meta (206-219)
src/metagen/src/client_py/node_metas.rs (1)
  • build_meta (189-202)
src/metagen/src/fdk_ts/types.rs (2)
  • ty (204-216)
  • ty (224-228)
src/metagen/src/fdk_rs/types.rs (1)
  • new (427-432)
src/typegraph/graph/src/conv/map.rs (1)
  • new (85-93)
src/typegraph/graph/src/conv/mod.rs (1)
  • new (68-93)
src/metagen/src/fdk_py/types.rs (1)
  • new (337-348)
src/typegraph/graph/src/conv/dedup.rs (3)
src/typegraph/graph/src/conv/map.rs (3)
  • new (85-93)
  • is_empty (56-58)
  • register (124-220)
src/typegraph/graph/src/conv/mod.rs (1)
  • new (68-93)
src/typegraph/schema/src/types.rs (1)
  • is_empty (191-196)
tests/metagen/typegraphs/sample/rs/main.rs (4)
tests/metagen/typegraphs/sample/rs/client.rs (2)
  • Post (245-258)
  • RootIdentityFnInput (130-141)
tests/metagen/typegraphs/sample/ts/client.ts (6)
  • Post (987-995)
  • Post (1060-1064)
  • RootCompositeArgsFnInput (1065-1067)
  • RootCompositeUnionFnOutputSelections (1115-1118)
  • RootIdentityFnInput (911-917)
  • RootIdentityFnInput (1068-1070)
tests/metagen/typegraphs/sample/py/client.py (2)
  • Post (914-921)
  • RootIdentityFnInput (1084-1089)
src/metagen-client-rs/src/nodes.rs (2)
  • select (139-141)
  • select (155-157)
src/typegraph/graph/src/types/string.rs (11)
src/typegraph/graph/src/types/object.rs (2)
  • base (45-47)
  • tag (49-51)
src/typegraph/graph/src/types/file.rs (3)
  • base (17-19)
  • tag (21-23)
  • is_plain (27-32)
src/typegraph/graph/src/types/float.rs (3)
  • base (19-21)
  • tag (23-25)
  • is_plain (29-40)
src/typegraph/graph/src/types/integer.rs (3)
  • base (19-21)
  • tag (23-25)
  • is_plain (29-40)
src/typegraph/graph/src/types/optional.rs (2)
  • base (24-26)
  • tag (28-30)
src/typegraph/graph/src/types/function.rs (2)
  • base (55-57)
  • tag (59-61)
src/typegraph/graph/src/types/union.rs (2)
  • base (25-27)
  • tag (29-35)
src/typegraph/graph/src/types/list.rs (2)
  • base (23-25)
  • tag (27-29)
src/typegraph/graph/src/types/boolean.rs (2)
  • base (14-16)
  • tag (18-20)
src/typegraph/graph/src/conv/mod.rs (1)
  • base (350-366)
src/typegraph/graph/src/types/mod.rs (2)
  • base (101-101)
  • tag (102-102)
src/typegraph/graph/src/types/mod.rs (9)
src/typegraph/graph/src/types/object.rs (4)
  • base (45-47)
  • tag (49-51)
  • children (53-55)
  • edges (57-66)
src/typegraph/graph/src/types/optional.rs (4)
  • base (24-26)
  • tag (28-30)
  • children (32-34)
  • edges (36-42)
src/typegraph/graph/src/types/union.rs (4)
  • base (25-27)
  • tag (29-35)
  • children (37-39)
  • edges (41-51)
src/typegraph/graph/src/types/list.rs (4)
  • base (23-25)
  • tag (27-29)
  • children (31-33)
  • edges (35-41)
src/typegraph/graph/src/types/file.rs (2)
  • base (17-19)
  • tag (21-23)
src/typegraph/graph/src/types/float.rs (2)
  • base (19-21)
  • tag (23-25)
src/typegraph/graph/src/types/integer.rs (2)
  • base (19-21)
  • tag (23-25)
src/typegraph/graph/src/types/string.rs (2)
  • base (19-21)
  • tag (23-25)
src/typegraph/graph/src/types/boolean.rs (2)
  • base (14-16)
  • tag (18-20)
src/metagen/src/client_rs/selections.rs (7)
src/metagen/src/client_rs/mod.rs (3)
  • render (182-203)
  • new (64-93)
  • new (102-106)
src/metagen/src/shared/manifest.rs (3)
  • render (14-18)
  • get_reference_expr (22-22)
  • with_extras (53-59)
src/metagen/src/client_ts/selections.rs (4)
  • render (25-51)
  • render (67-98)
  • render (104-109)
  • get_reference_expr (111-116)
src/typegraph/graph/src/lib.rs (1)
  • name (100-102)
src/typegraph/schema/src/lib.rs (1)
  • name (152-157)
src/typegraph/graph/src/types/union.rs (1)
  • variants (17-21)
src/metagen/src/shared/client.rs (1)
  • selection_for_field (43-83)
src/typegraph/graph/src/types/list.rs (9)
src/typegraph/graph/src/conv/mod.rs (6)
  • conv (144-149)
  • base (350-366)
  • get_type (45-45)
  • get_type (57-59)
  • finalize (46-46)
  • finalize (61-64)
src/typegraph/graph/src/types/optional.rs (7)
  • item (16-20)
  • base (24-26)
  • tag (28-30)
  • children (32-34)
  • edges (36-42)
  • get_type (74-76)
  • finalize (78-95)
src/typegraph/graph/src/types/union.rs (6)
  • base (25-27)
  • tag (29-35)
  • children (37-39)
  • edges (41-51)
  • get_type (84-86)
  • finalize (88-112)
src/typegraph/graph/src/types/mod.rs (9)
  • base (101-101)
  • tag (102-102)
  • children (104-106)
  • edges (107-109)
  • downgrade (185-198)
  • parent (115-115)
  • parent (138-140)
  • key (117-117)
  • key (146-148)
src/typegraph/graph/src/types/file.rs (2)
  • base (17-19)
  • tag (21-23)
src/typegraph/graph/src/types/float.rs (2)
  • base (19-21)
  • tag (23-25)
src/typegraph/graph/src/types/integer.rs (2)
  • base (19-21)
  • tag (23-25)
src/typegraph/graph/src/types/string.rs (2)
  • base (19-21)
  • tag (23-25)
src/typegraph/graph/src/types/boolean.rs (2)
  • base (14-16)
  • tag (18-20)
src/metagen/src/shared/files.rs (3)
src/typegraph/graph/src/path.rs (3)
  • try_from (23-31)
  • try_from (234-240)
  • input (273-279)
src/typegraph/graph/src/visitor.rs (2)
  • from (166-168)
  • traverse_types (18-29)
src/typegraph/graph/src/types/function.rs (1)
  • input (26-28)
src/metagen/src/fdk_rs/types.rs (2)
src/metagen/src/shared/types.rs (1)
  • type_body_required (23-38)
src/metagen/src/fdk_rs/utils.rs (1)
  • normalize_type_title (26-43)
src/metagen/src/client_rs/mod.rs (6)
src/metagen/src/client_ts/mod.rs (4)
  • new (59-83)
  • new (92-96)
  • render (149-174)
  • render_query_graph (190-225)
src/metagen/src/fdk_rs/types.rs (2)
  • new (427-432)
  • render (63-147)
src/metagen/src/client_rs/selections.rs (2)
  • manifest_page (164-227)
  • render (36-47)
src/metagen/src/client_ts/selections.rs (4)
  • manifest_page (119-175)
  • render (25-51)
  • render (67-98)
  • render (104-109)
src/metagen/src/client_rs/node_metas.rs (4)
  • render (46-61)
  • render (75-109)
  • render (113-147)
  • render (151-202)
src/metagen/src/shared/manifest.rs (1)
  • render (14-18)
src/metagen/src/client_ts/mod.rs (5)
src/metagen/src/client_ts/selections.rs (4)
  • manifest_page (119-175)
  • render (25-51)
  • render (67-98)
  • render (104-109)
src/metagen/src/fdk_ts/mod.rs (1)
  • new (64-68)
src/metagen/src/shared/node_metas.rs (1)
  • new (22-30)
src/metagen/src/client_ts/node_metas.rs (4)
  • render (22-32)
  • render (52-79)
  • render (89-115)
  • render (127-172)
src/metagen/src/shared/manifest.rs (1)
  • render (14-18)
src/metagen/src/client_ts/selections.rs (11)
src/metagen/src/client_ts/node_metas.rs (5)
  • render (22-32)
  • render (52-79)
  • render (89-115)
  • render (127-172)
  • get_reference_expr (34-42)
src/metagen/src/client_rs/selections.rs (2)
  • render (36-47)
  • get_reference_expr (49-53)
src/metagen/src/shared/manifest.rs (2)
  • render (14-18)
  • get_reference_expr (22-22)
src/typegraph/graph/src/conv/key.rs (1)
  • fmt (12-14)
src/typegraph/graph/src/lib.rs (1)
  • name (100-102)
src/typegraph/graph/src/types/mod.rs (4)
  • name (114-114)
  • name (130-136)
  • key (117-117)
  • key (146-148)
src/metagen/src/client_py/selections.rs (2)
  • get_reference_expr (34-39)
  • new (144-210)
src/metagen/src/client_ts/static/mod.ts (2)
  • map (306-315)
  • key (421-423)
src/typegraph/graph/src/conv/mod.rs (1)
  • new (68-93)
src/metagen/src/shared/client.rs (1)
  • selection_for_field (43-83)
src/typegraph/graph/src/types/union.rs (1)
  • variants (17-21)
src/metagen/src/lib.rs (2)
src/metagen/src/client_py/mod.rs (1)
  • from_json (31-40)
src/metagen/src/fdk_substantial/mod.rs (1)
  • from_json (17-26)
src/typegraph/graph/src/visitor.rs (7)
src/typegraph/graph/src/path.rs (2)
  • output (281-287)
  • input (273-279)
src/typegraph/graph/src/types/function.rs (3)
  • output (38-40)
  • edges (67-80)
  • input (26-28)
src/typegraph/graph/src/types/mod.rs (2)
  • edges (107-109)
  • downgrade (185-198)
src/typegraph/graph/src/types/object.rs (1)
  • edges (57-66)
src/typegraph/graph/src/types/optional.rs (1)
  • edges (36-42)
src/typegraph/graph/src/types/union.rs (1)
  • edges (41-51)
src/typegraph/graph/src/types/list.rs (1)
  • edges (35-41)
tests/metagen/typegraphs/sample/rs_upload/client.rs (2)
tests/metagen/typegraphs/sample/ts_upload/client.ts (10)
  • RootUploadFnInput (924-927)
  • FileBf9b7 (928-928)
  • RootUploadFnInputPathString25e51Optional (929-929)
  • RootUploadManyFnInput (930-933)
  • RootUploadManyFnInputPrefixString25e51Optional (934-934)
  • RootUploadManyFnInputFilesFileBf9b7List (935-935)
  • RootUploadFnOutput (936-936)
  • RootUploadManyFn (903-912)
  • scalar (899-901)
  • RootUploadFn (913-922)
tests/metagen/typegraphs/sample/py/client.py (2)
  • NodeMeta (259-263)
  • scalar (910-911)
src/typegraph/graph/src/types/optional.rs (3)
src/typegraph/graph/src/types/list.rs (5)
  • item (17-19)
  • base (23-25)
  • tag (27-29)
  • children (31-33)
  • edges (35-41)
src/typegraph/graph/src/types/mod.rs (5)
  • base (101-101)
  • tag (102-102)
  • children (104-106)
  • edges (107-109)
  • downgrade (185-198)
src/typegraph/schema/src/types.rs (2)
  • base (332-348)
  • children (394-405)
src/metagen/src/fdk_py/mod.rs (3)
src/metagen/src/fdk_py/types.rs (3)
  • from (30-37)
  • from (230-333)
  • new (337-348)
src/metagen/src/fdk_py/utils.rs (1)
  • from (16-21)
src/metagen/src/shared/mod.rs (1)
  • filter_stubbed_funcs (23-37)
src/metagen/src/shared/mod.rs (10)
src/typegraph/core/src/runtimes/prisma/context.rs (2)
  • borrow (28-30)
  • name (44-46)
src/typegraph/core/src/typegraph.rs (1)
  • tg (244-250)
src/typegraph/core/src/test_utils.rs (1)
  • ty (242-251)
src/typegraph/core/src/types/sdk/core.rs (1)
  • as_id (235-235)
src/typegraph/core/src/lib.rs (1)
  • as_id (85-90)
src/typegraph/core/src/types/type_ref.rs (1)
  • as_id (39-41)
src/typegraph/graph/src/lib.rs (1)
  • name (100-102)
src/typegraph/graph/src/types/mod.rs (2)
  • name (114-114)
  • name (130-136)
src/typegraph/core/src/runtimes/prisma/model.rs (1)
  • name (30-32)
src/typegraph/graph/src/types/optional.rs (1)
  • item (16-20)
src/metagen/src/fdk_ts/types.rs (4)
src/metagen/src/shared/types.rs (1)
  • type_body_required (23-38)
src/typegraph/graph/src/types/object.rs (2)
  • properties (29-33)
  • tag (49-51)
src/typegraph/graph/src/types/union.rs (2)
  • variants (17-21)
  • tag (29-35)
src/metagen/src/shared/manifest.rs (1)
  • get_reference_expr (22-22)
src/metagen/src/client_ts/node_metas.rs (6)
src/metagen/src/client_ts/selections.rs (4)
  • render (25-51)
  • render (67-98)
  • render (104-109)
  • get_reference_expr (111-116)
src/metagen/src/shared/manifest.rs (2)
  • render (14-18)
  • get_reference_expr (22-22)
src/metagen/src/client_ts/static/mod.ts (3)
  • Alias (369-377)
  • alias (383-385)
  • key (421-423)
src/typegraph/graph/src/types/mod.rs (4)
  • name (114-114)
  • name (130-136)
  • key (117-117)
  • key (146-148)
src/typegraph/graph/src/types/union.rs (1)
  • variants (17-21)
src/metagen/src/shared/node_metas.rs (2)
  • build_meta (13-13)
  • new (22-30)
src/typegraph/graph/src/conv/map.rs (5)
src/typegraph/graph/src/types/optional.rs (1)
  • item (16-20)
src/typegraph/graph/src/types/list.rs (1)
  • item (17-19)
src/typegraph/graph/src/types/mod.rs (4)
  • key (117-117)
  • key (146-148)
  • idx (113-113)
  • idx (126-128)
src/typegraph/graph/src/conv/key.rs (1)
  • from (21-23)
src/typegraph/graph/src/types/union.rs (1)
  • variants (17-21)
src/metagen/src/fdk_py/types.rs (4)
src/metagen/src/shared/types.rs (1)
  • type_body_required (23-38)
src/metagen/src/shared/manifest.rs (1)
  • from (40-46)
src/metagen/src/fdk_py/utils.rs (2)
  • from (16-21)
  • map (77-81)
src/metagen/src/client_py/selections.rs (1)
  • new (144-210)
src/metagen/src/tests/fixtures.rs (3)
src/typegraph/schema/src/types.rs (1)
  • base (332-348)
src/typegraph/core/src/types/type_def.rs (6)
  • data (86-86)
  • data (106-108)
  • data (132-134)
  • id (85-85)
  • id (102-104)
  • id (128-130)
src/typegraph/core/src/types/type_ref.rs (1)
  • id (128-135)
src/typegraph/schema/src/types.rs (5)
src/typegraph/graph/src/types/object.rs (1)
  • children (53-55)
src/typegraph/graph/src/types/optional.rs (2)
  • children (32-34)
  • item (16-20)
src/typegraph/graph/src/types/function.rs (3)
  • children (63-65)
  • input (26-28)
  • output (38-40)
src/typegraph/graph/src/types/union.rs (1)
  • children (37-39)
src/typegraph/graph/src/types/list.rs (2)
  • children (31-33)
  • item (17-19)
src/metagen/src/shared/manifest.rs (4)
src/metagen/src/client_rs/selections.rs (1)
  • get_reference_expr (49-53)
src/metagen/src/client_ts/node_metas.rs (1)
  • get_reference_expr (34-42)
src/metagen/src/client_ts/selections.rs (1)
  • get_reference_expr (111-116)
src/metagen/src/client_py/selections.rs (1)
  • get_reference_expr (34-39)
src/metagen/src/client_py/node_metas.rs (7)
src/metagen/src/shared/files.rs (1)
  • get_path_to_files (112-136)
src/metagen/src/client_ts/node_metas.rs (8)
  • render (22-32)
  • render (52-79)
  • render (89-115)
  • render (127-172)
  • get_reference_expr (34-42)
  • build_meta (185-198)
  • alias (202-202)
  • alias (209-213)
src/metagen/src/client_ts/mod.rs (1)
  • render (149-174)
src/metagen/src/client_py/selections.rs (4)
  • render (27-32)
  • render (55-88)
  • render (104-140)
  • get_reference_expr (34-39)
src/metagen/src/shared/manifest.rs (1)
  • get_reference_expr (22-22)
src/metagen/src/shared/node_metas.rs (1)
  • build_meta (13-13)
src/typegraph/graph/src/types/union.rs (1)
  • variants (17-21)
tests/metagen/typegraphs/sample/rs/client.rs (3)
tests/metagen/typegraphs/sample/py/client.py (7)
  • Post (914-921)
  • RootIdentityFnInput (1084-1089)
  • User (924-931)
  • RootIdentityUpdateFn (1103-1111)
  • NodeMeta (259-263)
  • scalar (910-911)
  • RootIdentityFn (1092-1100)
src/metagen/src/client_py/static/client.py (1)
  • NodeMeta (256-260)
tests/metagen/typegraphs/sample/rs_upload/client.rs (1)
  • scalar (51-58)
src/metagen/src/client_rs/node_metas.rs (12)
src/typegraph/graph/src/conv/key.rs (1)
  • fmt (12-14)
src/metagen/src/shared/files.rs (1)
  • get_path_to_files (112-136)
src/metagen/src/client_rs/mod.rs (3)
  • render (182-203)
  • new (64-93)
  • new (102-106)
src/metagen/src/client_rs/selections.rs (2)
  • render (36-47)
  • get_reference_expr (49-53)
src/metagen/src/client_ts/node_metas.rs (16)
  • render (22-32)
  • render (52-79)
  • render (89-115)
  • render (127-172)
  • get_reference_expr (34-42)
  • build_meta (185-198)
  • alias (202-202)
  • alias (209-213)
  • build_func (205-205)
  • build_func (249-270)
  • build_object (203-203)
  • build_object (215-230)
  • build_union (204-204)
  • build_union (232-247)
  • props (217-224)
  • props (256-259)
src/metagen/src/client_ts/mod.rs (3)
  • render (149-174)
  • new (59-83)
  • new (92-96)
src/metagen/src/shared/manifest.rs (2)
  • render (14-18)
  • get_reference_expr (22-22)
src/metagen/src/client_py/node_metas.rs (12)
  • get_reference_expr (177-185)
  • build_meta (189-202)
  • alias (206-206)
  • alias (213-217)
  • build_func (209-209)
  • build_func (255-275)
  • build_object (207-207)
  • build_object (219-233)
  • build_union (208-208)
  • build_union (235-253)
  • props (221-227)
  • variants (237-243)
src/typegraph/graph/src/types/mod.rs (4)
  • key (117-117)
  • key (146-148)
  • name (114-114)
  • name (130-136)
src/metagen/src/shared/node_metas.rs (1)
  • build_meta (13-13)
src/typegraph/graph/src/types/union.rs (1)
  • variants (17-21)
src/typegraph/graph/src/conv/map.rs (1)
  • new (85-93)
src/metagen/src/client_py/selections.rs (5)
src/metagen/src/client_ts/selections.rs (4)
  • render (25-51)
  • render (67-98)
  • render (104-109)
  • get_reference_expr (111-116)
src/metagen/src/shared/manifest.rs (2)
  • get_reference_expr (22-22)
  • with_extras (53-59)
src/metagen/src/client_py/static/client.py (1)
  • File (207-213)
src/metagen/src/shared/client.rs (1)
  • selection_for_field (43-83)
src/typegraph/graph/src/types/union.rs (1)
  • variants (17-21)
tests/metagen/typegraphs/identities/ts/fdk.ts (1)
tests/metagen/typegraphs/identities/py/handlers_types.py (13)
  • PrimitivesArgs (109-110)
  • Primitives (90-102)
  • CompositesArgs (117-118)
  • Composites (125-129)
  • Branch2 (136-137)
  • Cycles1Args (144-145)
  • Cycles1 (152-155)
  • Branch33A (162-164)
  • Branch33B (171-173)
  • SimpleCycles1Args (180-181)
  • SimpleCycles1 (188-190)
  • SimpleCycles2 (197-199)
  • SimpleCycles3 (206-208)
🪛 Biome (1.9.4)
src/metagen/src/client_ts/static/mod.ts

[error] 208-208: Shouldn't redeclare 'O'. Consider to delete it or rename it.

'O' is defined here:

(lint/suspicious/noRedeclare)

tests/metagen/typegraphs/sample/ts_upload/client.ts

[error] 211-211: Shouldn't redeclare 'O'. Consider to delete it or rename it.

'O' is defined here:

(lint/suspicious/noRedeclare)

tests/metagen/typegraphs/sample/ts/client.ts

[error] 211-211: Shouldn't redeclare 'O'. Consider to delete it or rename it.

'O' is defined here:

(lint/suspicious/noRedeclare)

🪛 Ruff (0.8.2)
tests/metagen/typegraphs/identities/py/fdk.py

8-8: Redefinition of unused typing from line 4

Remove definition: typing

(F811)


21-21: Undefined name HostcallBinding

(F821)


23-23: Undefined name HostcallTransport

(F821)


44-44: Use bool(...) instead of True if ... else False

Replace with `bool(...)

(SIM210)


530-530: Loop control variable node overrides iterable it iterates

(B020)


636-636: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


696-696: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


724-724: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)


1185-1185: Undefined name Primitives

(F821)


1193-1193: Undefined name PrimitivesStrString

(F821)


1194-1194: Undefined name PrimitivesEnumStringEnum

(F821)


1195-1195: Undefined name PrimitivesUuidStringUuid

(F821)


1196-1196: Undefined name PrimitivesEmailStringEmail

(F821)


1197-1197: Undefined name PrimitivesEanStringEan

(F821)


1198-1198: Undefined name PrimitivesJsonStringJson

(F821)


1199-1199: Undefined name PrimitivesUriStringUri

(F821)


1200-1200: Undefined name PrimitivesDateStringDate

(F821)


1201-1201: Undefined name PrimitivesDatetimeStringDatetime

(F821)


1202-1202: Undefined name PrimitivesIntInteger

(F821)


1203-1203: Undefined name PrimitivesFloatFloat

(F821)


1204-1204: Undefined name PrimitivesBooleanBoolean

(F821)


1240-1240: Undefined name Composites

(F821)


1249-1249: Undefined name CompositesEitherEither

(F821)


1250-1250: Undefined name CompositesUnionUnion

(F821)


1251-1251: Undefined name CompositesListPrimitivesStrStringList

(F821)


1260-1260: Undefined name Branch2

(F821)


1272-1272: Undefined name Branch4

(F821)


1275-1275: Undefined name Branch4again

(F821)


1292-1292: Undefined name Cycles1

(F821)


1310-1310: Undefined name Cycles3

(F821)


1315-1315: Undefined name Branch33A

(F821)


1316-1316: Undefined name Branch33B

(F821)


1346-1346: Undefined name SimpleCycles1

(F821)


1698-1698: Undefined name Transports

(F821)


1708-1708: Undefined name Transports

(F821)


1718-1718: Undefined name Transports

(F821)


1730-1730: Undefined name Transports

(F821)

🔇 Additional comments (352)
tests/metagen/typegraphs/sample/rs_upload/main.rs (4)

18-22: Type updates for single file upload look good.

The change from RootUploadFnInputPartial to RootUploadFnInput and direct assignment of the file property (without wrapping in Option) simplifies the API and makes the code cleaner. This aligns with the PR objectives of expanding the typegraph and inlining references.


27-29: Type updates for multiple file upload look good.

The change from RootUploadManyFnInputPartial to RootUploadManyFnInput and direct assignment of the files vector (without wrapping in Option) follows the same pattern as the single file upload, maintaining consistency in the API design.


55-58: Consistent type usage in async context.

The implementation correctly uses the new RootUploadFnInput type in the async preparation logic, ensuring consistency with the blocking implementation. The structure of the input remains the same, with direct assignment of the file property.


84-86: Consistent type usage for async multiple file upload.

The change to use RootUploadManyFnInput with direct file vector assignment in the async mutation call is consistent with the blocking implementation. This ensures a uniform API pattern across both synchronous and asynchronous contexts.

src/metagen/src/client_ts/static/mod.ts (3)

138-141: Variant Selections Conversion:
The diff reformats the conversion of variant selections by casting variant_select to a Selection and then recursively calling _selectionToNodeSet. The dynamic construction of the variant path via a template literal (${parentPath}.${instanceName}.variant(${variantTy})) is clear and effective.

Note: Double-check that casting variant_select as Selection is safe in all contexts.


716-722: Mutation Node Inner Value Extraction:
Similarly, the mutation branch uses a conditional to either extract the inner value from a single node or to transform an object of mutation nodes using Object.fromEntries. This mirrors the query logic well.

Note: Confirm that the type assertion (val as MutationNode<unknown>).inner() is valid for all cases to prevent any runtime type issues.


802-812: PreparedRequest Node Type Handling:
Within the PreparedRequest constructor, the use of instanceof for detecting if dryRunNode is a QueryNode or MutationNode is consistent with earlier patterns. The subsequent conditional transformation using Object.fromEntries for the non-single node scenario is clear.

No changes required here, but maintain awareness that similar type assertions should be verified against all expected input cases.

tests/metagen/typegraphs/other.py (1)

1-2: Copyright notice properly added.

Standard copyright and license identifier added to the file, following best practices for open source licensing.

tests/utils/file.ts (1)

1-3: Copyright notice properly added.

Standard copyright and license identifier added to the file, following best practices for open source licensing.

.ghjk/lock.json (7)

976-980: Environment Key Update for "test-codegen" Task
The updated environment key
"envKey": "bciqgfkhptprs54tg3wl45acxctzc2lu4v2xlh3slk6w4m5g5ctysv4a"
ensures that the task now uses the new configuration. Please verify that downstream tooling (e.g., code-generation scripts and CI workflows) has been updated to reference this new key.


1130-1132: Updated Environment Key for "build-tgraph-py" Task
The environment key for the Python typegraph build has been changed to
"envKey": "bciqpei32hkwk37chtbyin65e3pvaeawn6cq3ytsihyxo54ixft7yyjq".
Ensure that any related documentation or configuration files (e.g. in the metagen tool) are in sync with this update.


1139-1142: Updated Environment Key for "build-tgraph-rpc" Task
The task now uses the updated key
"envKey": "bciqn7hev7ej5zg7cixajsoe5kpouah36nmzt2o7vsxnxgl6tou4z7cy".
Please confirm that this change correctly reflects the new settings for RPC builds in the expanded typegraph setup.


1144-1147: Updated Environment Key for "build-tgraph-ts" Task
The environment key has been updated to
"envKey": "bciqdxfpgv43gmtbphf7wdom7n6wv3xvhrtexnqrokaok6ljbccma5by".
This key appears to be shared with the Node variant later; please verify consistency across the TypeScript build pipelines.


1149-1155: Consistent Environment Key for "build-tgraph-ts-node" Task
The node-specific task now reuses the same updated key
"envKey": "bciqdxfpgv43gmtbphf7wdom7n6wv3xvhrtexnqrokaok6ljbccma5by"
as its TypeScript counterpart. This appears intentional to ensure consistency; just double-check that no divergence is needed between the two tasks.


1157-1160: Updated Environment Key for "build-tgraph-core" Task
The core typegraph build now uses the new key
"envKey": "bciqg4j54df6d7tkfqx5g6fwnhuznqtrveerazjqzrtykguzhefcljpa".
Make sure that any build or dependency scripts referring to the core task are updated accordingly.


1233-1237: TYPEGRAPH_VERSION Bump to "0.0.4"
The environment variable "TYPEGRAPH_VERSION" has been updated to "0.0.4" (previously "0.0.3"). Verify that all components consuming this version (e.g., runtime configuration, client code generators, or CI scripts) have been adjusted to reflect this change.

src/metagen/src/tests/fixtures.rs (2)

80-105: Looks good!

The construction of the Typegraph schema with base objects and function nodes is clear.


212-237: Code organization is consistent.

This test block is consistent with test_typegraph_1 and checks for the correct deserialization logic.

tests/metagen/typegraphs/sample/ts_upload/client.ts (10)

26-28: Implementation looks good.

The branching logic to handle Alias vs. a single selection is concise and correct.


30-34: Loop structure is clear.

Expanding Object.entries(nodeInstances) allows straightforward iteration over instance names.


445-453: No concerns.

Ternary logic for naming the GraphQL field is straightforward.


482-489: Implementation is clear.

Mapping subNodes into a GraphQL selection string is effectively done.


491-511: Variant handling is robust.

Using the variant name and typeToGqlTypeMap for inline fragments is done correctly.


684-689: Neat usage of object creation from entries.

Building the query object from multiple node entries is idiomatic.


904-912: Correct argument definition for uploadMany.

Providing inputFiles ensures GraphQL can handle file arrays properly.


913-922: Proper argument definition for upload.

The single file input is well-specified, matching the argumentTypes field.


928-929: Type aliases appear consistent.

Alias for FileBf9b7 as File is straightforward.


934-935: Array and optional types are clearly defined.

The new optional prefix and list usage for files is coherent.

src/metagen/fixtures/client_rs/main.rs (4)

38-38: Switch to types::Post is valid.

Swapping out partial types for the full Post ensures complete data.


40-42: Clean argument injection.

Directly constructing RootCompositeArgsFnInput clarifies required fields.


95-99: Full Post usage is appropriate.

Passing fully-defined fields aligns with the updated contract.


101-103: Consistent function input.

The revised RootCompositeArgsFnInput is neatly applied.

tests/metagen/typegraphs/sample/rs/main.rs (6)

36-43: Switch from Partial to Full Types in Mutation Arguments

This block consistently replaces the previous partial types with their complete counterparts (types::Post and types::RootCompositeArgsFnInput), which reinforces stricter validation at compile time. This update appears coherent with the rest of the file and should help avoid runtime errors due to missing fields.


53-62: Consider Unifying PostPartial Usage

Line 53 still references types::PostPartial, while functions above use the full types::Post. Mixing partial and full types can cause confusion or errors if the API requires all fields. Verify whether this is intentional or should be updated to maintain consistency.


96-104: Full-Type Argument Consistency

Using types::Post and types::RootCompositeArgsFnInput inside the mutation aligns with the new strict approach in other sections of the file. This should reduce the chance of omitting required fields. Implementation looks correct.


111-117: Composite and Mixed Union Inputs

These lines replace partial input types with RootCompositeArgsFnInput, ensuring calls to api1.scalar_union, composite_union, and mixed_union are consistent with full-type requirements. This is a solid improvement in type safety.

Also applies to: 124-126, 131-133


172-174: Using types::Post in Scalar Args

Switching to types::Post for the scalar_args match is consistent with the rest of the codebase’s shift away from partial types. No issues found.


180-181: Identity Function Input

The code now calls args.get("num", |val: i64| types::RootIdentityFnInput { input: val }), which ensures a well-defined structure for the identity-related data. This update appears correct and consistent throughout.

Also applies to: 188-190

tests/metagen/typegraphs/sample/rs_upload/client.rs (7)

29-46: New types Module Introduction

These lines add a dedicated module for upload types (RootUploadFnInput, RootUploadManyFnInput, etc.). The naming and organization generally follow Rust idioms, providing a clear separation of type definitions. No major concerns identified.


59-77: RootUploadManyFn Node Meta Configuration

This addition configures the argument types (files and prefix) with the correct references to their graph type names, and properly lists files as input files. This ensures the GraphQL layer processes file uploads as intended. Looks good.


81-98: RootUploadFn Node Meta Configuration

Similarly, this section sets up the upload function’s arguments (file, path) to reference the new type definitions. The approach to input files is consistent with the many-file upload function. No issues noted.


107-107: Type Registration for file_bf9b7

Registering "file_bf9b7" in the map ensures that the custom file type is recognizable in GraphQL schema generation.


117-118: List of File Types

"root_uploadMany_fn_input_files_file_bf9b7_list" mapped to "[file_bf9b7!]!" correctly denotes a non-null list of non-null file entries. This is a proper mapping for handling file arrays.


128-128: Full-Type Signature for upload()

Changing the signature to impl Into<NodeArgs<RootUploadFnInput>> enforces complete, validated upload inputs. Good move to ensure all required fields are present.


146-146: Full-Type Signature for upload_many()

Using RootUploadManyFnInput ensures that the function receives the necessary files array and optional prefix. This aligns with the shift to fully defined types.

tests/metagen/typegraphs/identities/py/fdk.py (4)

226-233: File Class for Multipart Handling

Encapsulating file content and metadata in a class is a solid approach. Properly setting MIME types is crucial for form submissions. No issues noted here.


907-916: QueryGraphBase Class: Expand or Omit?

It’s a minimal base class referencing a typed map. If it’s only used in extended classes, the structure is fine. Otherwise, confirm that placeholders (ty_to_gql_ty_map) won't cause undefined references in other modules.


1517-1693: QueryGraph Methods for Domain Operations

Throughout, the approach of passing typed dicts (PlaceholderArgs, PrimitivesArgs, etc.) with a matching selection structure fosters type safety. Ensure that references like Transports.hostcall() are defined in the codebase or imported.


1695-1733: Handlers for Rust/Python/TypeScript Composites

These wrapper functions unify user-defined logic with the GraphQL context. The references to Transports in lines 1698, 1708, 1718, 1730 appear external. Verify that Transports is accessible in the final runtime environment.

🧰 Tools
🪛 Ruff (0.8.2)

1698-1698: Undefined name Transports

(F821)


1708-1708: Undefined name Transports

(F821)


1718-1718: Undefined name Transports

(F821)


1730-1730: Undefined name Transports

(F821)

tests/metagen/typegraphs/identities/ts/fdk.ts (13)

36-38: Well-structured type definition.
No specific issues found. Consider adding brief doc comments if you'd like more clarity for maintainers.


42-48: Clear shift to typed string aliases.
Replacing raw string types with these aliases improves code clarity and type safety.


59-68: Additional type aliases look good.
These definitions are straightforward, and having descriptive names for each variant is helpful.


69-70: CompositesArgs addition.
Clean argument struct. This structure will make your code more consistent and modular.


73-78: Enhanced composite type.
Your composite structure captures optional fields and union types well. Keep an eye on test coverage for nested objects.


83-84: Branch2 definition is succinct.
Field name is descriptive enough. No concerns here.


89-95: Extended union with string alias.
The union updates are consistent with your approach for typed primitives. Looks good.


97-98: Cycles1Args type introduction.
No immediate concerns. Consider verifying that all references to Cycles1Args are tested for recursive edge cases.


100-103: Cyclic references with optional fields.
These definitions effectively handle partial references. Make sure to test for infinite recursion or tricky cyclical usage.


105-111: Cycle handling for Cycles2 and Cycles3.
This approach for unioning cycle types is consistent. Just confirm usage in your runtime logic.


116-116: Optional reference within Branch33ATo1Cycles1Optional.
Straightforward optional pointer to Cycles1. No issues flagged.


121-121: List-based optional cyclical reference.
Implementation is consistent with the rest of the cyclical design. Looks fine.


143-145: Handlers for new argument structures.
These typed handler signatures align well with your newly introduced argument interfaces.

tests/metagen/typegraphs/sample/rs/client.rs (37)

29-34: Introduction of use types::* and module.
Splitting types into a separate module is a solid approach for maintainability. Ensure other modules reference them correctly.


36-40: Post struct with typed fields.
Straightforward definition. Everything looks consistent with your naming conventions.


41-48: RootCompositeArgsFnInput and RootIdentityFnInput.
Both new structs are minimal but clear. Good addition for strongly typed arguments.


49-62: UserPartial and PostPartial.
The optional fields effectively support partial updates. Ensure you handle nil fields properly in the calling code.


63-68: RootScalarUnionFnOutput enumeration.
The untagged enum approach works well. Keep an eye on deserialization edge cases.


69-74: RootCompositeUnionFnOutputPartial.
Mirrors the partial usage patterns. No issues here.


75-82: RootMixedUnionFnOutputPartial.
Counters multiple potential variants. Looks consistent with previous union partial definitions.


83-88: RootNestedCompositeFnOutputPartial: skeleton with optional fields.
This structure captures nested data. Fine as is, but ensure tests cover various fill levels of optional fields.


89-93: RootNestedCompositeFnOutputCompositeStructPartial.
Good layering for nested structures. No concerns.


94-97: RootNestedCompositeFnOutputCompositeStructNestedStructPartial.
Handles deeper nesting. All optional fields are consistent with your partial approach.


98-98: Type alias for list usage.
Defining a distinct alias clarifies usage in the codebase. Looks good.


99-102: RootNestedCompositeFnOutputListStructPartial definition.
One field optional structure. Straightforward approach.


103-106: RootIdentityFnInputPartial.
Consistent partial input structure. Should be easy to handle in logic and tests.


107-107: End of module block.
Module structure is neatly concluded.


120-129: RootIdentityUpdateFn node meta.
New function includes argument typings. Matches your root_meta usage pattern, so looks correct.


130-139: RootIdentityFnInput node meta.
Linking the ("input", scalar) sub-node is consistent with your partial usage.


142-149: RootIdentityFn node meta.
The combination of RootIdentityFnInput plus argument types is aligned. Keep your doc or comments updated if parameters evolve.


152-156: RootNestedCompositeFn meta delegating to RootNestedCompositeFnOutput.
No immediate issues. Ensures consistent nested structures.


157-168: RootNestedCompositeFnOutput meta configuration.
Sub-nodes for scalar, composite, list neatly reflect the partial struct.


171-180: RootNestedCompositeFnOutputListStruct node meta.
No concerns. The single field is mapped consistently.


183-193: RootNestedCompositeFnOutputCompositeStruct node meta.
Properly enumerates sub-nodes. All placeholders for deeper nesting are present.


196-207: RootNestedCompositeFnOutputCompositeStructNestedStruct node meta.
Includes a single scalar field inner. Straightforward.


208-215: RootMixedUnionFn meta.
Argument type id with string_e1a43. No issues flagged.


231-239: User node meta expansions.
Mapping id, email, and posts to scalar or composite sub-nodes is consistent with your data model.


245-255: Post node meta expansions.
Sub-nodes align with PostPartial. Good coverage for slug/title.


259-266: RootCompositeUnionFn meta.
Arg types set. Continues union approach. Looks in line with the rest of your design.


272-278: RootCompositeUnionFnOutput union.
Variants for post or user are clearly defined. No changes needed.


282-289: RootScalarUnionFn meta with id argument.
No obvious pitfalls. Ties in well with your scalar usage.


292-299: RootCompositeArgsFn meta usage.
Ties id to string_e1a43 and reuses Post(). Straightforward design.


302-306: RootCompositeNoArgsFn meta.
Just calls ..Post(). No issues.


307-316: RootScalarArgsFn meta.
Arguments for id, slug, and title. Reuses scalar(). All consistent.


319-323: RootScalarNoArgsFn meta.
No concerns. Delegates to scalar().


325-329: RootGetPostsFn node meta.
Simple reuse of Post().


330-333: RootGetUserFn node meta.
Simple reuse of User().


344-349: PostSelections struct and derived traits.
Captures post fields with typed selections. Looks good.


363-368: RootNestedCompositeFnOutputSelections for nested fields.
Defines typed selection structure for scalar, composite, and list. Aligned with the data model.


376-379: RootNestedCompositeFnOutputCompositeStructNestedStructSelections.
Enables selecting the inner field. Straightforward usage.

tests/metagen/typegraphs/sample/ts/client.ts (7)

26-28: Refined nodeInstances logic.
Switching based on Alias helps handle multiple aliases. Clear approach.


30-34: Expanded for block on node instances.
Good readability. Each instance is processed distinctly.


141-144: Union variant selection logic.
Cleanly extracts variant selections referencing variant_select. This is clear and maintainable.


451-453: Dynamic naming for GraphQL fields.
Concise logic for alias vs. original name. This is more readable than before.


684-689: Query argument expansion for object entries.
Neatly converts each node into an inner structure. Matches your approach in building queries dynamically.


805-806: Distinguishing single node vs. multiple nodes.
Using instanceof checks for QueryNode or MutationNode clarifies request context.


809-814: Dry-run node object entry mapping.
Similar pattern used above. Ensures that all node sub-selections are properly transformed.

tests/metagen/typegraphs/scripts/same_hit.py (1)

1-2: License and copyright notice properly added.

The copyright notice and SPDX license identifier have been correctly added to the file, which is a good practice for ensuring proper licensing attribution.

src/metagen/Cargo.toml (1)

14-14: Appropriate workspace dependency added.

Adding the typegraph workspace dependency to metagen aligns with the PR objectives of introducing an expanded typegraph. This allows metagen to leverage the new expanded typegraph functionality.

src/typegraph/graph/Cargo.toml (1)

1-13: New typegraph crate configuration looks good.

The Cargo.toml for the new typegraph crate is well-structured with appropriate dependencies. The inclusion of serialization libraries (serde), data structures (indexmap), and error handling (color-eyre) makes sense for a crate that will handle type graph functionality.

tests/metagen/typegraphs/metagen.ts (1)

25-32: Input struct properly renamed for consistency.

The change adds an explicit name to the input structure through .rename("OneInput"), which follows the same pattern used for the "two" function (shown on line 34). This provides better type visibility and consistency across the codebase, supporting the PR's goal of expanded typegraph functionality.

src/typegraph/core/src/utils/metagen_utils.rs (2)

4-4: Added Arc import for reference-counted smart pointers.

The addition of Arc from the std::sync module indicates a shift towards shared ownership semantics, which is important when data needs to be accessed from multiple owners or across thread boundaries.


22-22:

✅ Verification successful

Changed typegraph wrapping with double Arc implementation.

The change wraps the typegraph in two layers of Arc, which suggests a significant change in ownership semantics. This appears to be related to the expanded typegraph mentioned in the PR objectives, enabling better sharing of the typegraph across different components.

The nested structure (Arc::new(Arc::new(...).try_into()?)) implies one Arc for the converted typegraph and another for the wrapper, which aligns with the goal of inlining all numeric references and eliminating the need to maintain references to the typegraph object itself.


🏁 Script executed:

#!/bin/bash
# Verify where this double Arc wrapping pattern is used elsewhere
rg --type rust "Arc::new\(Arc::new\(" -A 2 -B 2

Length of output: 520


Double Arc wrapping confirmed; design aligns with PR objectives.

  • The verification using the grep script confirms that the double Arc pattern is limited to the intended location (src/typegraph/core/src/utils/metagen_utils.rs).
  • The nested wrapping (Arc::new(Arc::new(self.tg.clone()).try_into()?))) effectively encapsulates the typegraph conversion and facilitates improved sharing, as described.
  • No additional instances of this pattern were found, indicating the change is both localized and intentional.
Cargo.toml (2)

12-12: New workspace member added for the expanded typegraph.

Adding "src/typegraph/graph" to the workspace members follows the PR's objective of introducing a new crate for the expanded typegraph.


47-47: Added workspace dependency for the new typegraph crate.

This dependency entry allows other crates in the workspace to depend on the new typegraph implementation, enabling the broader use of the expanded typegraph components across the project.

src/typegraph/graph/src/types/boolean.rs (1)

1-21: New BooleanType implementation follows the type system pattern.

The implementation of BooleanType follows the consistent pattern seen in other type implementations, with a TypeBase field and the TypeNode trait implementation. This consistency makes the codebase more maintainable and easier to understand.

The implementation is very similar to other primitive types like StringType, IntegerType, and FloatType, which all follow the same pattern of implementing the base() and tag() methods from the TypeNode trait.

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

7-7: Updated error handling imports.

The import change to include ErrorContext trait and Result type prepares for the improved error handling implemented below.

src/metagen-client-rs/src/nodes.rs (2)

24-29: New SubNodes enum looks good

The addition of the SubNodes enum with its three variants (None, Atomic, and Union) provides a clear and structured way to represent different types of node relationships in queries. The Debug derive is appropriate for this data structure.


31-39: SelectNodeErased structure is well-designed

The SelectNodeErased struct is properly designed to contain all necessary information for nodes used in queries, including name, arguments, sub-nodes, and input files. The Debug derive will be helpful for developers when troubleshooting.

src/typegraph/graph/src/types/float.rs (3)

8-16: FloatType structure looks good

The FloatType struct effectively encapsulates a floating-point type with all common constraints (minimum, maximum, exclusive bounds, multiple_of). All fields are appropriately marked as optional, allowing for flexibility in type definitions.


18-26: TypeNode implementation is appropriate

The TypeNode trait implementation for Arc<FloatType> follows the expected pattern, providing access to the base type and a static tag identifier.


28-40: Clean implementation of is_plain method

The is_plain method efficiently uses pattern matching to check if all constraints are None, indicating a plain float type. This is a clean and readable implementation.

src/typegraph/graph/src/types/file.rs (3)

8-14: FileType structure looks good

The FileType struct properly encapsulates file type constraints including size limits and mime types. The fields are appropriately made optional to support cases where constraints aren't needed.


16-24: TypeNode implementation is appropriate

The TypeNode trait implementation for Arc<FileType> correctly provides access to the base type and defines the type tag as "file".


27-32: Efficient is_plain method implementation

The is_plain method correctly uses as_ref() when pattern matching on mime_types since it's an Option<Vec<String>>. This approach properly handles the reference without moving the value.

tests/metagen/typegraphs/sample/metatype.yml (2)

13-15: Python client generator disabled

The client_py generator configuration has been commented out. Based on the PR objectives, this appears to be intentional while the expanded typegraph functionality is being implemented.

Is this intentional and temporary? Please verify that Python client generation will be re-enabled once the expanded typegraph implementation is completed for all languages.


26-28: Python upload client generator disabled

Similar to the main client, the Python client generator for file uploads has been commented out, which is consistent with the previous change.

src/metagen-client-rs/src/graphql.rs (1)

380-386: Fixed syntax error in error handling.

The added semicolon after the closing brace correctly terminates the return statement in the error handling block, ensuring proper Rust syntax for the match arm.

src/typegraph/graph/src/conv/key.rs (2)

8-15: Well-structured type key implementation with clear purpose.

The TypeKey implementation includes all necessary traits for use in collections and comparisons. The documentation comment clarifies its purpose as storing both a type index and variant ID.


17-24: Clear implementation of TypeKeyEx with good type conversion.

The TypeKeyEx struct and its From<&Type> implementation provide a convenient way to create keys from type references. This will help with type deduplication as mentioned in the PR objectives.

src/metagen-client-rs/src/args.rs (2)

36-43: Good addition of NodeArgsMerged for handling different argument types.

The new NodeArgsMerged enum effectively handles both inline arguments and placeholders with their type information. This structure supports the expanded typegraph functionality mentioned in the PR objectives, allowing for better type handling.


71-75: Clear NodeArgValue structure for type-aware argument values.

The NodeArgValue struct cleanly pairs the type name with its value, improving type safety when handling arguments. This supports the typegraph expansion described in the PR objectives.

src/typegraph/core/src/typedef/func.rs (2)

18-18: Library dependency change from IndexMap to BTreeMap

The import statement has been modified to use BTreeMap from the standard library instead of the previously imported IndexMap. This change aligns with the broader migration for the expanded typegraph structure.


136-136:

❓ Verification inconclusive

Changed data structure from IndexMap to BTreeMap

The res variable is now initialized as a BTreeMap instead of an IndexMap. This is a significant change in behavior:

  • BTreeMap keeps keys sorted, while IndexMap preserves insertion order
  • BTreeMap has O(log n) lookup time vs O(1) average-case for IndexMap

This change ensures consistent ordering of properties in the injection tree, which is likely necessary for the expanded typegraph functionality described in the PR objectives.


🏁 Script executed:

#!/bin/bash
# Check if this change is consistent with other files using InjectionTree
echo "Checking other files that use InjectionTree:"
rg -A 3 "InjectionTree" --glob "*.rs" | grep -B 3 -A 3 "(BTreeMap|IndexMap)"

Length of output: 175


Attention: Data Structure Change Requires Manual Verification

The update in src/typegraph/core/src/typedef/func.rs switches the initialization of the res variable from IndexMap to BTreeMap. This change enforces sorted key ordering instead of preserving insertion order, and shifts lookup performance from O(1) average-case (IndexMap) to O(log n) (BTreeMap).

  • This modification is intended to ensure consistent ordering in the injection tree, which aligns with the expanded typegraph functionality.
  • However, our automated search for consistent usage of either BTreeMap or IndexMap in files referencing InjectionTree returned no results.

Please verify manually that:

  • The change aligns with the overall design and expectations for the injection tree.
  • No unintended side effects are introduced by this data structure change across the codebase.
src/typegate/src/engine/planner/policies.ts (2)

4-4: Improved TypeScript type import syntax

The import statement has been updated to use the more modern TypeScript syntax for importing types, changing from import { type Logger } to import type { Logger }. This is a minor syntax improvement that better separates type imports from value imports.


278-281: Enhanced logging for cached policy results

The policy evaluator now stores the cached result in a variable before returning it, and adds a log message when running in verbose mode. This improves observability by making it explicitly clear when cached authorization results are being used.

This change will help with debugging policy evaluation flows, particularly in identifying when cached results are being applied.

src/typegraph/graph/src/runtimes.rs (2)

29-30: Appropriate type aliases for shared references

The type aliases for Materializer and Runtime as Arc<T> types are appropriate for these shared resources. Using Arc ensures these potentially large structures can be efficiently shared across the application without unnecessary cloning.


9-17:

✅ Verification successful

Well-structured MaterializerNode implementation

The MaterializerNode struct is well-defined with clear field names and appropriate types. The TODO comment on lines 14-15 appropriately flags the need for a more specific type for the data field in the future, particularly since it might reference other materializers.


🏁 Script executed:

#!/bin/bash
# Look for usage of the MaterializerNode data field to understand its content structure
echo "Checking for MaterializerNode data field usage:"
rg "materializer.*data" --glob "*.rs" -A 3 -B 3

Length of output: 2552


MaterializerNode structure verified and approved

The scan confirms that the data field is used in various parts of the code—retrieving keys like "mat", "inp", and "op_name"—which supports keeping the flexible IndexMap<String, Value> type for now. The existing TODO indicating a need for a more specific type is still relevant for future improvements.

src/typegraph/graph/src/types/string.rs (2)

8-16: Clear and comprehensive StringType implementation

The StringType struct covers all standard string validation constraints (min/max length, pattern, format, enumeration) with appropriate optional fields. The structure parallels JSON Schema's string validation rules, which is a good practice.


18-26: Standard TypeNode trait implementation

The TypeNode trait implementation for Arc<StringType> follows the consistent pattern seen in other type implementations shown in the relevant code snippets. The base() and tag() methods are implemented correctly and consistently with other type nodes.

src/metagen/src/fdk_py/static/fdk.py (3)

1-15: Well-structured type declarations with conditional compilation

The type aliases and conditional compilation directives are well organized. The code properly uses typing.Any for platform-specific types and defines a clear callable signature for HostcallBinding.


16-29: Clean implementation of the Ctx class with conditional parameters

The Ctx class implementation is clean and follows the same structure seen in the test typegraphs. The conditional compilation with metagen-genif directives ensures that the appropriate fields are included based on whether HOSTCALL is enabled.


31-32: Simple and effective GQL method implementation

The gql method provides a straightforward interface for executing GraphQL queries by delegating to the binding function and ensuring variables are properly converted to a dictionary.

src/typegraph/graph/src/types/integer.rs (3)

1-16: Well-defined IntegerType struct with appropriate constraints

The IntegerType struct is well-designed with all necessary constraint fields for integer validation (minimum, maximum, exclusive bounds, and multiple_of). All fields are properly marked as optional to accommodate different constraint combinations.


18-26: Clear TypeNode trait implementation

The TypeNode implementation for Arc<IntegerType> provides straightforward access to the base type and a static type tag. Using Arc here is appropriate for shared ownership semantics, which aligns with the expanded typegraph approach mentioned in the PR objectives.


28-41: Efficient is_plain implementation

The is_plain method efficiently checks if all constraint fields are None using pattern matching. This is a useful utility for identifying unconstrained integer types during code generation or serialization.

src/meta-cli/src/cli/gen.rs (2)

174-176: Improved memory management with Arc

Wrapping the raw typegraph in an Arc improves memory management by providing shared ownership, which is essential for the expanded typegraph mentioned in the PR objectives. This change ensures that the typegraph data can be safely shared across threads without unnecessary cloning.


198-200: Consistent Arc usage across different code paths

This change maintains consistency with the previous change by also wrapping the typegraph loaded from a path in an Arc. This consistency is important to ensure all code paths handle the typegraph data with the same ownership semantics.

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

216-246: Comprehensive is_composite implementation for type classification

The is_composite method provides a thorough classification of types, appropriately handling all variants including recursive types like Optional, List, Union, and Either. The method correctly identifies primitive types and handles composite types recursively.

There is a placeholder for Any types marked with unimplemented!(), which is appropriate if support for this type is planned for future work.


248-250: Efficient is_function implementation

The is_function method uses pattern matching to efficiently check if a type is a function without unnecessary computation. This concise implementation enhances the API of the Typegraph class and will be useful for the expanded typegraph feature.

tests/metagen/metagen_test.ts (3)

95-100: Handle potential Deno.copyFile errors.

Currently, there's no error handling for the file copy operation. In the event of a missing source file or a permission issue, the test may fail silently or produce unclear error messages. Consider wrapping this call in try/catch logic or using Deno.copyFileSync within a try block to provide clearer feedback to maintainers.


438-438: Typographical fix recognized.

Renaming name: "primtives" to name: "primitives" is correct. Thank you for fixing this minor typo.


529-531: Test coverage limited to 'py' prefix.

By continuing early for non-"py" prefixes, these scenarios are effectively skipped, which may reduce test coverage for the other prefixes. Confirm that this is the intended behavior and that you do not need to validate the same logic in other prefixes.

src/typegraph/graph/tests/expanded.rs (3)

1-3: License headers confirmed.

The MPL-2.0 license headers look correct. No changes required.


4-6: Imports look good.

Using standard library imports and referencing typegraph modules is appropriate.


8-62: Add snapshot test or assertions as needed.

This test function exercises the meta-cli output by deserializing the schema and printing details. Including automated assertions or snapshot tests (rather than just println!) may catch regressions. This addresses a past suggestion to snapshot test.

src/metagen/src/fdk_rs/mod.rs (10)

17-18: Introduction of RustTypesConfig import.

Bringing in RustTypesConfig is a sensible move to facilitate the new type-building logic.


136-136: Empty line insertion.

This extra line might simply organize code blocks for clarity. No issues found.


140-140: Indirect generation of the .rs contents.

Calling template.gen_mod_rs(&self.config, tg.clone()) centralizes the code generation logic. This approach is maintainable.


146-146: Retrieving typegraph name.

Using tg.name() keeps the crate naming conventional. No concerns here.


172-175: New Maps struct introduced.

Separating input and output references into Maps clarifies code organization. This structure is beneficial for caching.


177-177: Refactored function signature to accept Arc<Typegraph>.

Using Arc can simplify ownership and reduce unnecessary cloning. This is a clean design choice for concurrency and reference sharing.


193-197: Building and rendering the manifest.

Configuring .derive_serde(true) and .derive_debug(true) is beneficial for debugging and serialization. Good setup for building a robust manifest.


199-203: Initializing Maps with cached references.

Storing references for inputs and outputs fosters consistent usage across code generation steps. Nicely implemented.


215-217: Filtering stubbed functions for specified runtimes.

filter_stubbed_funcs usage with context-provided error messages is clear and helpful. Good error-handling approach.


220-221: Generating stub traits for each materializer.

Invoking stubs::gen_stub for each function fosters modular stub creation. This pattern is maintainable and easy to extend.

src/typegraph/graph/src/conv/dedup.rs (4)

10-13: Ensure that deriving Hash aligns with InjectionNode usage.
DuplicationKey is marked #[derive(Hash)], which depends on InjectionNode being hashable in a consistent manner. Verify that InjectionNode’s internal structure (including any nested children) remains immutable and stable, or hashing collisions could lead to unexpected behavior down the line.

Would you like me to generate a script to look for potential mutation/hashing pitfalls in any InjectionNode usage throughout the repository?


28-34: Confirm alignment with InjectionNode::is_empty.
is_empty relies on injection.is_empty() or true if None. Verify that returning true when injection is None is desired in all contexts, or consider returning false for None if that better reflects semantics.


36-40: Leverage direct from usage for uniformity.
The From<&Type> trait is a neat convenience. Make sure all places requiring a DuplicationKey from a reference to Type consistently use this trait to keep code uniform.


58-96: Check concurrency assumptions.
deduplicate reads from self.direct without mutating it, yet the logic suggests it’s part of a broader registration flow. Confirm it isn’t invoked in parallel with other mutations on ConversionMap, or add synchronization.

src/metagen/src/shared/node_metas.rs (3)

6-6: No immediate concerns.
Importing TypeNodeExt is standard. Nothing appears problematic at a glance.


22-30: Check for potential errors in root_functions iteration.
root_functions returns a Result, which is unwrapped via root_fn?. Ensure any partial success/failure scenario is handled or documented if one root function fails while others succeed.


32-34: Push usage is straightforward.
No immediate issues. The method is minimal and correct for adding items to the stack.

src/metagen/src/lib.rs (1)

193-193: Typo fix is correct.
Renaming ClienPyGenConfig to ClientPyGenConfig aligns with typical naming. Looks good.

src/typegraph/core/src/types/type_ref/injection.rs (3)

9-10: Use of BTreeMap for stable key ordering
Switching from IndexMap to BTreeMap changes iteration order from insertion order to sorted order. Ensure that sorted ordering does not conflict with injection node usage.

Please verify if there are any assumptions about insertion order in the injection logic.


17-17: Good consistency with new BTreeMap alias
Renaming the alias from IndexMap to BTreeMap is consistent with your broader changes.


65-65:

✅ Verification successful

Ensure no ordering assumption in recursive calls
When changing from IndexMap to BTreeMap, ensure that child injection logic does not rely on insertion order.

We can check for iteration usage or any deterministic ordering logic in the codebase with the following script:


🏁 Script executed:

#!/bin/bash
# Searching for iteration usage over 'parent' or 'children'
rg "for .* in parent|children"

Length of output: 16600


Ordering Assumptions in Injection Recursion Verified

The search for iterations over parent or children did not reveal any hidden reliance on insertion order. In the recursive logic (e.g., collecting keys from children in src/typegraph/core/src/types/type_ref/injection.rs), the use of BTreeMap now guarantees sorted order, and there's no evidence that previous insertion order was assumed.

  • Confirmed no direct iteration assumes IndexMap’s insertion order.
  • The key collection (using children.keys().collect()) reflects sorted order, which is acceptable in the current logic.
  • Downstream logic and tests should still be reviewed to ensure the sorted order aligns with overall expectations.
src/metagen/src/fdk_rs/stubs.rs (4)

4-5: Added typegraph imports
Ensures direct usage of FunctionType and TypeNodeExt. Confirm usage in place of the older StubbedFunction references is fully integrated.


15-17: Signature updated to use Arc and super::Maps
Replacing StubbedFunction with FunctionType may improve consistency across the codebase.


26-26: Potential panic from unwrap
Using .unwrap() on maps.output.get(...) can panic if the key is missing. Consider error handling or a descriptive fallback.


27-27: Title normalization
Using normalize_type_title for the function name is a consistent approach to ensure valid Rust-styled identifiers.

src/metagen/src/fdk_ts/mod.rs (4)

10-11: Imports manifest_page
Importing manifest_page from types fosters a more streamlined approach for TypeScript generation. This is consistent with the new type manifest approach.


90-93: Render all manifest TS types
The code now calls manifest_page(&tg)? and then manif.render_all(dest)?, which centralizes type definitions. This is a good approach to ensure all types are generated in one place.


100-100: Error context with wrap_err_with
Good use of wrap_err_with to provide context on failures when filtering stubbed functions.


104-106: Dynamic type name creation
Using utils::normalize_type_title for both input and output type names, as well as the function name, ensures consistency and avoids potential naming collisions.

src/metagen/src/fdk_ts/types.rs (8)

6-7: Introduced ManifestEntry and ManifestPage usage
This leverages the new manifest-based system for generating TS types. Aligns well with a more generic approach to type representation.


11-16: Definition of Alias enum
The Alias enum provides a structured way to represent built-in, optional, or container types in TS. This is a nice design to keep logic for optional and array types distinct from object or union variants.


18-37: TsType enum for comprehensive representation
These variants (Alias, Object, Enum, and LiteralEnum) clearly capture the major TS type constructs. Great extension for covering complex scenarios like literal enum variants.


39-46: fn builtin helper
This static constructor for built-in TS types with an optional name simplifies the creation of type aliases. Excellent for readability.


48-53: ObjectProp struct
Encapsulating each property’s name, type, and optionality keeps object definitions straightforward.


55-114: Implementation of ManifestEntry for TsType
Rendering logic is neatly organized per variant, ensuring a clear, centralized approach for generating TS definitions. The pattern is easy to extend for future expansions.


145-246: Comprehensive type parsing in get_typespec
Appropriately handles each type variant, including enumerations and specialized string formats. The usage of type_body_required is consistent with skipping trivial types.


248-268: Creates manifest of input and output types
Merging input and output types into a single map fosters simpler code generation. Skipping empty objects prevents generating unhelpful stubs.

src/metagen/src/shared/client.rs (4)

4-19: Consider potential collisions and edge cases when gathering GraphQL types.

This new function relies on an IndexMap where duplicate keys could overwrite existing entries. Confirm this behavior is intentional. As a further improvement, consider whether nested input properties (e.g., nested objects) should be included, ensuring the function covers deeper structures if required.


32-33: Return value usage is straightforward.

Returning the res IndexMap appears consistent with the function's goal. No further concerns.


35-41: Updated SelectionTy fields enhance clarity.

Migrating to TypeKey fields is a clean improvement that promotes consistent referencing across the codebase. The enum variants now capture important type information more robustly.


43-83: Validate recursion and unreachable branches in selection_for_field.

The heavy use of recursion for Optional, List, and nested Function outputs might risk deep recursion or edge cases returning another function. Ensure that a function returning another function never occurs in practice (as indicated by unreachable!). Adding assertions or tests for unusual nested constructs could help detect future regressions.

src/typegraph/graph/src/conv/mod.rs (13)

1-6: License headers look correct.
No further changes suggested here.


7-14: Check imports for usage consistency.
They appear valid for the introduced functionalities. No issues flagged.


21-24: Mod statements structure the code.
Exposes internal modules consistently. Looks good.


25-29: Interlude re-exports.
Provides a concise re-export interface. This modularity pattern helps maintain clarity.


32-42: Conversion struct fields might become large in memory.

The Conversion struct aggregates multiple large collections. Monitor for potential memory usage issues, especially for large schemas. Otherwise, the approach is coherent.


49-54: FinalizedTypeConversion provides a neat short-circuit.

This is a helpful pattern to store pre-converted, cached, or trivial types. Implementation is straightforward and concise.


56-65: TypeConversionResult implementation is clean.

No material concerns. The finalize method correctly no-ops.


67-93: Conversion::new carefully builds dependencies.

Constructing runtimes, materializers, and policies from the schema is logical. Validate that materializer or policy indices are never out of range for large or unusual schemas.


95-153: Primary convert<NE> flow may assume type 0 is always the root.

This function defaults to the type_idx: 0 path. Ensure that the zero-based assumption remains valid as schema usage evolves. Also confirm that root.assert_object() never fails if there's a scenario with a non-object root.


201-214: register_type_2 is a flexible helper.

The extra duplicate param clarifies behavior for repeated references. Approve the approach.


216-224: register_type wrapper.

Reads well and further reduces boilerplate. No issues.


350-366: base function extracts fundamental info.

No immediate concerns. The injection mechanism is well integrated with rpath.get_injection().


368-373: convert_policies is straightforward.

Delegates well to convert_policy_spec. It’s concise and maintainable.

src/metagen/src/utils.rs (2)

4-4: Re-export of interlude is standard.

No concerns to report here.


107-158: collect_at_first_instance reorders lines neatly.

The approach is straightforward. Confirm that partial matches or lines containing the pattern more than once are not incorrectly processed. Also ensure it gracefully handles empty input.

src/typegraph/schema/src/validator/injection.rs (3)

4-4: Confirm that switching to BTreeMap is intentional

Replacing IndexMap with BTreeMap changes iteration from insertion order to sorted order. If your validation logic relies on the original insertion order, this may introduce subtle differences.

Would you like to run a script to confirm that the updated iteration order produces the expected validation results?


79-79: Check iteration order impact in Parent injection node

InjectionNode::Parent { children } now uses a BTreeMap, meaning the iteration over children will be in sorted key order. Verify that this does not break any implicit assumptions about traversal order in your injection logic.


180-180: Revisit iteration order for validate_union

Within validate_union, the children parameter now leverages BTreeMap, causing sorted-key iteration. If the validation logic previously relied on the insertion sequence, this change could produce different outcomes.

src/metagen/src/shared/types.rs (1)

31-35: Primitive type checks appear consistent

The checks for primitive type titles (e.g., boolean_, integer_, etc.) are straightforward and align with your approach for selectively generating type bodies.

src/typegraph/graph/src/types/mod.rs (5)

34-43: Enums appear well-structured.

The EdgeKind enum uniquely captures various relationships (e.g., OptionalItem, ListItem, etc.) comprehensively. No issues stand out here.


45-71: Consider the reliability of upgrade() calls in equality & hashing.

Within the Edge struct, both PartialEq and Hash rely on upgrade() calls. If the underlying Arc is dropped, upgrade() will fail. Currently, you invoke expect("no strong pointer for type") to handle that scenario. Depending on the code’s usage patterns, this might introduce runtime panics. If it’s guaranteed never to be dropped, this is acceptable; otherwise, consider returning a recoverable error or safely handling None.


73-82: Validate optional injection behavior.

TypeBase includes an injection: Option<InjectionNode>. Ensure that any required validations or post-processing (like special handling of hidden types) are consistently enforced.


84-110: Structure for Type and TypeNode is logical.

The Type enum comprehensively covers the supported types (e.g., Boolean, Float, File, etc.). The default children() and edges() returning empty is a practical fallback for leaf-like types. This design cleanly integrates with the visitor pattern.


170-257: Use of WeakType fosters safer graph references.

The downgrade/upgrade mechanics are consistent with Rust’s ownership rules. This pattern effectively prevents reference cycles. The code is clear and free of obvious concurrency or memory pitfalls.

src/typegraph/graph/src/visitor.rs (4)

7-11: Traversal flow control is well-designed.

The VisitNext enum concisely manages whether to move to children, siblings, or stop. This aids a clean, predictable graph traversal.


13-16: VisitNode struct is straightforward.

Storing both the current ty and its path is beneficial for debugging, logging, or advanced transformations.


54-102: traverse_types_with_path ensures consistent visitor flow.

The code properly handles the Stop or Siblings signals. The approach is clear and maintainable.


104-161: Cyclic path detection appears robust.

PathExt::is_cyclic uses a HashSet to detect repeated (from, to) pairs. This is a valid approach. For complex scenarios (like merging edges) or “shortest cycle” checks, additional logic might be needed, but this is sufficient as-is.

src/typegraph/graph/src/types/union.rs (5)

9-14: UnionType fields are well-organized.

base, variants, and either are succinctly declared. The use of Lazy<Vec<Type>> is good for deferred initialization.


16-22: Ensure variants are initialized early.

variants() panics if they’re not set. Confirm that all union types properly finalize their variants before usage.


24-52: Implementation of TypeNode is cohesive.

Using tag() to differentiate “either” from “union” is concise. The edges() method enumerates each variant with an indexed edge, aligning well with EdgeKind::UnionVariant.


54-75: Union conversion function is clear.

convert_union delegates to UnionTypeConversionResult for finalizing variant construction. This design isolates creation and finalization logic elegantly.


77-114: Finalize method systematically handles each variant.

By pushing the union variant path segment, the code ensures nested references are well-tracked. The OnceLock error handling is suitable for preventing multiple sets.

src/metagen/src/client_ts/selections.rs (6)

6-10: Imports look appropriate.
No issues spotted. The additions correctly reference needed traits and modules.


12-15: Well-defined enum structure
Defining separate variants for Object and Union is clear and straightforward. This approach simplifies maintenance and extensibility.


18-22: Struct visibility
Object holds internal fields marked as private. Ensure external usage is fully handled via methods or in the same module if broader access is needed.

Do all modules that consume Object exist in the same crate or provide necessary accessors?


54-58: Union struct definitions
The Union struct parallels Object closely, keeping design consistent for selection types. No issues spotted.


101-117: ManifestEntry implementation
Returning Some(name.clone()) in get_reference_expr is consistent and straightforward. Good job employing the trait to unify rendering logic.


119-175: Manifest page creation
Logic for iterating tg.output_types and constructing either an Object or Union selection is clear and covers relevant composite types. The early continue for non-composite or scalar types avoids clutter. Looks solid.

src/metagen/src/shared/files.rs (5)

5-5: Visitor imports
Importing VisitNext is correct for traversals. No issues identified.


9-9: Use of Arc<str>
Moving to Arc<str> may improve memory efficiency for shared string slices. Ensure that call sites handle the reference type correctly.


18-23: Explicit bail for union variants
The bail on encountering a union variant prevents file handling in polymorphic types. This is consistent with the stated constraint. Confirm that it's tested so we detect unexpected usage early.


79-89: New TryFrom implementation
This code neatly mirrors the existing slice-based TryFrom, adding flexibility for Vec<PathSegment>. Verify whether both forms are consistently used.


112-136: get_path_to_files logic
Traverses input fields of a function and captures file paths. The approach is concise, but ensure that partial paths for nested optional or list items are handled gracefully.

Would you like to verify coverage for deeper nested structures?

src/metagen/src/client_rs/selections.rs (7)

6-11: Imports
These new imports from typegraph and local modules align well with the expanded RustSelection approach.


14-19: Fine-grained union property
UnionProp grouping of variant name, type, and selection type is a neat breakdown. This improves clarity, especially for generating specialized code.


21-31: Enum for structured selections
RustSelection distinctly models Struct vs. Union. This is a robust design to handle branching logic in rendering.


33-54: ManifestEntry usage
Implements the trait straightforwardly, returning references via get_reference_expr. The approach is cohesive with the rest of the codebase.


160-162: Extras struct
Storing input_types in IndexMap is flexible for referencing argument types. No immediate concerns here.


164-227: Manifest page function
Builds Struct or Union from composite types. Inclusion of input_types in extras fosters easy argument lookups. Logical approach, well-aligned with other language backends.


229-230: Type alias
RustSelectionManifestPage clarifies usage across the codebase. Straightforward and helpful for readability.

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

127-145: Leverage custom attribute for #[serde(untagged)] in the Enum variant.

The #[serde(untagged)] attribute usage is correct, but ensure future expansions (like adjacently tagged or explicit discriminants) are handled systematically if more complex tagging is required.


389-477: Re-examine partial type usage within output_page.

The logic conditionally references input types if partial is not set (lines 457–467). Carefully confirm that skipping new or specialized references doesn’t lead to subtle aliasing bugs for partial outputs.

Could you confirm that partial output references remain consistent by running relevant integration tests?


652-678: Confirm untagged variant usage for MyEither.

#[serde(untagged)] on the MyEither enum is correct for union-like structures. However, if you need partial, selective, or discriminant-based tagging in the future, you might want to unify the approach across MyEither and MyUnion.


808-808: Evaluate potential error messages for cyclical union expansions.

When a union references itself indirectly, advanced error handling or fallback might be necessary. Adding more robust logging or structured error returns could improve debugging.


4-5:

❓ Verification inconclusive

Check for naming consistency and clarify usage in imports.

The import statements bring in ManifestEntry, ManifestPage, indent_lines_into, and utils. Ensure these are consistently used within this file and verify that we aren’t unnecessarily importing items that remain unused.


🏁 Script executed:

#!/bin/bash
# Description: Verify import usage in src/metagen/src/fdk_rs/types.rs to confirm references are used.
rg -A 5 "^(use (super::manifest|super::indent_lines_into|super::utils))" src/metagen/src/fdk_rs/types.rs

Length of output: 321


Import Consistency and Usage Verification

The import statements in src/metagen/src/fdk_rs/types.rs (lines 4–5) currently import:

use super::manifest::{ManifestEntry, ManifestPage};
use super::{indent_lines_into, utils::*};

Please ensure the following:

  • Naming Conventions: Verify that names such as ManifestEntry, ManifestPage, and indent_lines_into align with the project’s naming standards.
  • Usage Clarity: Confirm that every imported item is indeed used within this file. For instance, if only a few members from utils are needed, consider replacing the wildcard import with explicit names for better clarity and maintainability.
  • Consistency Check: Make sure that these items are consistently applied throughout the file without causing ambiguity or potential namespace conflicts.

If all imported elements are used appropriately and adhere to naming conventions, no further changes are needed. Otherwise, adjust the imports to reflect only what’s necessary and maintain clarity in the code.

src/typegraph/graph/src/lib.rs (2)

12-20: Avoid potential naming collisions with Lazy<T>.

In line 15, pub type Lazy<T> = std::sync::OnceLock<T>; is straightforward. Watch for confusion with the standard LazyLock in Rust if other parts of the code consider alternative lazy initialization approaches.


58-80: Guard multi-variant usage in find_type.

match self.conversion_map.get(idx as usize)? can produce Namespace, Function, or Value. Confirm that each variant usage is validated in the broader context so that the returned type is used as expected.

src/typegraph/graph/src/path.rs (3)

4-10: Verify alignment with EdgeKind definitions.

Lines 4–10 reference EdgeKind, FunctionType, Type. Ensure that each EdgeKind variant you map to or from PathSegment is consistently updated when new variants appear, preventing out-of-sync definitions.


161-176: Gracefully handle non-parent injection nodes.

apply_on_injection expects a Parent injection node for ObjectProp paths. If we ever need to handle deeper injection nesting or typed injection expansions, add more robust pattern matching or documentation.


301-328: Confirm path containment checks align with partial expansions.

contains(..) verifies if a path includes xkey. If partial expansions exist, ensure we handle them consistently (e.g., partial references in the path might not map 1:1 to the final schema node).

src/typegraph/graph/src/types/optional.rs (5)

1-3: No action needed.
These license headers are standard and require no changes.


15-21: Confirm concurrency behavior for item().
Using Lazy<Type> with OnceLock is generally fine. However, if this code is accessed from multiple threads, ensure that any concurrent initialization is safe and won't cause panics.


23-43: Implementation of TypeNode looks solid.
The children and edges methods correctly link the optional type to its underlying item. This is consistent with the other type implementations.


45-66: Check references to convert_optional usage.
Everything seems correct for conversion. Confirm that any code calling convert_optional provides valid JSON for default_value and that the final result is tested (particularly if default_value or item are absent).


67-96: Lifecycle management for the optional item is well-handled.
The finalize method properly sets the item once and fails otherwise, which is a good safeguard.

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

20-20: Deriving PartialEq and Eq for SingleValue is appropriate.
This helps compare JSON values but ensure you handle potential ordering differences within nested objects or arrays, since JSON structures can differ but still represent the same data.


25-30: InjectionData derivations appear correct.
The additional PartialEq and Eq make sense for consistent comparisons of injection data.


224-229: Use of BTreeMap for injections and outjections in FunctionTypeData.
The shift from IndexMap to BTreeMap aligns with the consistent approach across the codebase. Ensure all call sites are updated accordingly.


393-405: children() method is consistent with other type definitions.
Returning child type IDs for each node facilitates straightforward graph traversal. Good job maintaining consistency here.

src/typegraph/graph/src/types/list.rs (4)

16-20: Guard the item() accessor for concurrency.
Similar to the optional type, verify if multi-threaded usage might require additional synchronization.


22-42: TypeNode trait implementation looks consistent.
The children() and edges() methods correctly reflect the relationship between the list and its item. Nicely done.


44-66: convert_list function is well-structured.
Ensure downstream code calls this with correctly configured schema data, especially for optional constraints like unique_items.


68-96: ListTypeConversionResult finalization is robust.
The use of OnceLock again guards the item from multiple sets, preventing logical errors.

src/metagen/src/shared/manifest.rs (9)

1-3: Good use of licensing and documentation headers.
These lines effectively establish the MPL-2.0 license and provide a short introduction.


12-23: Trait design looks consistent.
The ManifestEntry trait concisely defines a rendering mechanism and a method to retrieve reference expressions, promoting extensibility for future manifest entries. No immediate concerns.


25-33: Struct concurrency approach is sensible.
Storing references in an RwLock<IndexMap<...>> is a reasonable approach for parallel reads. Confirm that any external usage requiring mutation won't introduce race conditions.

Would you like to generate a script to search for code paths involving concurrent writes to reference_cache?


35-47: Conversion constructor aligns well with Rust conventions.
The From<IndexMap<TypeKey, S>> implementation sets sensible defaults and ensures that the manifest page can be conveniently built from an index map.


49-59: Flexible instantiation with extras.
The with_extras function allows specifying additional context, improving the reusability of ManifestPage. No issues spotted.


65-69: Proactive reference caching.
Calling get_ref(key) within cache_references is a neat trick to ensure every entry's reference is initially resolved. This precomputation could speed up later lookups.


88-93: Straightforward rendering approach.
The render_all function loops through each entry and delegates to ManifestEntry::render. Straight and readable.


95-99: Buffered rendering is well-structured.
render_all_buffered creates a single string for all entries. This is helpful for concatenating or passing the entire output somewhere else.


101-108: Neat extraction of cached references.
Filtering out only the Some values from the cache is a concise way to get all valid references. This design is beneficial for debugging or generating reports.

src/metagen/src/shared/mod.rs (7)

9-10: New modules introduced.
Adding pub mod manifest and pub mod node_metas cleanly separates the codebase. Good move for modular design.


13-13: HashSet import can reduce duplication.
Using a HashSet for stubbed_runtimes streamlines membership checks. This is a neat optimization.


16-16: FunctionType import.
Bringing FunctionType into scope is valid for typed function usage; no concerns.


26-28: Refactored return type.
filter_stubbed_funcs returning Vec<Arc<FunctionType>> is more intuitive, removing the need to wrap a custom struct. Consider verifying that external calls are updated for the new return signature.


30-33: filter usage is straightforward.
Filtering over the .functions.values() with membership checks in stubbed_runtimes. This logic is clear.


36-36: Returning Ok(stubbed_funcs)
No issues found. Looks consistent with the signature.


39-63: Comprehensive coverage of GraphQL scalar mapping.
get_gql_type accounts for optional types, lists, known scalars, and fallback to custom titles. A few considerations:

  • For large type graphs, repeated calls might be a performance concern.
  • The function tries to handle all known internal Metatype variants. Double-check that no variant is accidentally left out.

Do you want to run a script searching for all calls to get_gql_type to ensure correct usage and coverage?

src/metagen/src/client_rs/mod.rs (5)

9-13: Imports are well-organized and specific.
Explicitly importing RustTypesConfig, RustTypesSubmanifest, RsNodeMeta, and RustSelectionManifestPage clarifies dependencies.


43-45: Manifest instantiation & render.
Creating RsClientManifest and rendering it immediately to a buffer is a natural flow. Ensure that all error handling from render is truly necessary here if the method can fail unexpectedly.


205-246: render_query_graph handles GraphQL type mapping neatly.
It inserts each (type name → gql type) pair into a map in the new QueryGraph. The approach is good. Watch out for naming collisions if multiple types share the same name.


344-344: render_static is straightforward.
Injecting a static file (client.rs) is a practical approach. Confirm that the static file is kept in sync with any new type expansions.


349-376: Namespace approach for node metas.
with_metas_namespace encloses the generated methods under mod node_metas, tidying scope. Implementation is clear and concise.

src/metagen/src/client_ts/mod.rs (10)

9-10: Imports look good
No issues identified with these newly added imports.


16-16: Extension import
No concerns with importing TypeNodeExt.


50-56: Struct creation
The struct cleanly organizes required components.


58-83: Manifest creation
Logic is straightforward, effectively caching references in each manifest.


133-133: Manifest instantiation
No issues with this approach.


134-135: Rendering buffer
No concerns, code is succinct.


139-139: Buffer content assignment
No issues; straightforward.


176-189: Node metas rendering
Implementation is clear, no concerns.


190-225: Query graph rendering
No immediate issues. The code is self-explanatory.


337-340: Error logging
Displaying lines in case of a failed check is helpful for debugging.

src/metagen/src/client_py/selections.rs (12)

6-6: Pascal case import
No issues with the heck usage.


10-10: Import expansions
References to interlude and shared::client look correct.


16-16: Type alias
No concerns with the manifest page alias.


18-22: Enum for Python selections
Implementation is clear and prepares for either object or union selections.


24-40: ManifestEntry implementation
No issues. Correctly dispatches rendering.


42-46: ObjectProp details
Straightforward design.


48-52: Object struct
Maintains a name and a list of props. Good approach.


54-89: Object rendering
TypedDict creation is well-structured for Python.


91-95: UnionVariant struct
Straightforward. No issues.


97-101: Union struct
Holds name and variant list. No concerns.


103-140: Union rendering
Handling union variants and restricting scalars is appropriate.


143-210: Page creation
Filters composite types properly and constructs either Object or Union. Implementation is solid.

src/metagen/src/fdk_py/mod.rs (17)

4-5: Import statements
No issues with newly introduced imports for fmt::Write and Cow.


9-9: GenDestBuf usage
Clean usage of a utility struct.


11-12: ClientPyManifest & PyTypesPage
These imports match the new approach. No issues.


14-14: Public types module
This exposes types for external usage. Looks fine.


16-16: Default template
String includes appear correct.


18-20: FdkPythonTemplate
Allocating a template struct is a good pattern.


22-28: From implementation
Swapping out the fdk.py entry is logical.


36-40: New config fields
Allowing users to skip validations for these optional fields is sensible.


63-63: Generator constructor
Uses garde for validation. Implementation is consistent.


65-65: Config validation
No issues. This ensures correct config usage.


70-70: FdkPythonTemplate impl
No immediate concerns.


71-144: render_fdk_py
Generates the final Python code. Overall approach is fine.


146-156: Static generation
Writing the template to the buffer is straightforward.


190-198: Swapping input
Retrieving the typegraph from generator inputs is standard practice.


199-202: Template extraction
No issues, merges the template from inputs.


205-211: File insertion
Creates fdk.py with the rendered contents. Good approach.


217-278: End‐to‐end test
Checks the generated file with ruff. Adequate coverage for linting.

src/metagen/src/client_py/node_metas.rs (2)

49-56: Avoid panics when references are missing.
Currently, page.get_ref(ty_key).unwrap() may panic if references are missing. Consider handling missing references gracefully to prevent runtime panics.

Would you like me to generate a script to search for all unwrap calls within this module to ensure we handle potential None values properly?


240-253:

✅ Verification successful

Verify union variant filtering.
Calling v.is_composite().then(|| (v.name(), v.key())) may skip some variants if they are not considered “composite.” Confirm that ignoring non-composite variants is intended.


🏁 Script executed:

#!/bin/bash
# Search for the usage of `is_composite()` within the entire codebase to verify where else we rely on it.
rg "is_composite\\(" -A 5

Length of output: 10430


Union variant filtering has been verified as intentional.
The search results indicate that similar filtering logic—using is_composite() to exclude non-composite variants—is consistently used across different parts of the codebase (for example, in src/metagen/src/client_ts/node_metas.rs and other modules). This confirms that ignoring non-composite variants in the union generation is the intended behavior.

src/metagen/src/client_py/mod.rs (2)

60-72: Confirm exhaustive matching for typegraph inputs.
The match block ends with unreachable!(), which assumes either a typegraph_name or a typegraph_path must be set. Verify there's no scenario where both are missing, otherwise the program may panic.

Please confirm all call sites or configurations that set ClientPyGenConfig.base.typegraph_name or ClientPyGenConfig.base.typegraph_path.


239-245: Consider fallback logic for node_metas.
Falling back to "scalar" if there's no matching meta might be unintentional and could generate incorrect Python code. Double-check if this default is appropriate.

src/typegraph/graph/src/types/object.rs (2)

125-129: Confirm injection behavior for object properties.
Injection is retrieved from injections.as_ref(). If absent, the code silently skips injection, which may be correct or could mask issues. Ensure this is the desired approach.


149-154: Good use of OnceLock to prevent multiple sets.
Limiting property initialization to only once helps ensure correctness. This is a clean approach.

src/typegraph/graph/src/types/function.rs (3)

19-19: Consider removing runtime_config if unused.

Line 19 includes a TODO suggesting that runtime_config might no longer be necessary. If there's no current or anticipated need, removing it can reduce bloat and confusion.


42-47: Verify default effect coverage.

This function uses Read as the fallback effect type. Confirm that all calling contexts handle this default appropriately or consider adding a more explicit fallback mechanism.


130-162: Finalization logic looks solid.

The input and output types are set exactly once, and the error handling is appropriate. No additional changes required here.

tests/metagen/typegraphs/identities/rs/fdk.rs (2)

298-304: Verify potential infinite recursion in cycles.

Fields referencing each other (e.g., Cycles2, Cycles1, Cycles3) can create complex cyclic graphs. Confirm that serialization and data handling do not cause infinite recursion or stack overflows.


284-286: Naming aligns with metagen conventions.

Using aliases like Branch4 or Branch4again as String and Vec<...> is consistent with generated code. No issues found here.

src/metagen/src/client_rs/node_metas.rs (1)

277-281: Check for potential key collisions in props.

When inserting fields into the map (res.insert(name.clone(), prop.ty.name())), duplicates might overwrite existing entries if not handled. Confirm that property names are guaranteed unique upstream.

src/typegraph/graph/src/naming/mod.rs (1)

53-54: Guard against empty or default titles

You rely on item.ty.title() to create a unique name. If title() is empty or uninitialized, the newly registered name might be unclear and lead to potential naming collisions. Consider validating or providing a fallback name when title() is empty.

src/typegraph/graph/src/conv/map.rs (3)

84-88: Check initialization correctness for direct

direct.resize_with(type_count, || MapItem::Unset); initializes all slots as Unset. Ensure all valid types eventually override these placeholders, especially before any downstream code relies on these indexed positions.


180-210: Confirm variant index logic for value types

This block expects key.1 == 0 for the default variant or a strictly increasing ordinal for new variants. If there's a chance for out-of-order registrations (like concurrency or multi-pass logic), you may encounter unexpected errors (line 199). Validate that all registrations occur in a strictly monotonic sequence.


224-251: Verify reverse mapping consistency in append

self.reverse.insert(rpath, key); updates the reverse mapping after appending a path. Ensure that if the item type was re-registered or appended from multiple code paths, the previous reverse entry is not overwritten incorrectly.

src/metagen/src/fdk_py/types.rs (1)

276-286: Confirm correct usage of quoted references for optional fields

In lines 277-278, the code sets (true, true) for optional typed properties, referencing quote_ty_name logic later. If the optional item can appear outside the local module's definition, ensure that quoting the type name won't break or overshadow external references.

src/metagen/src/client_ts/node_metas.rs (5)

22-32: Confirm if no code generation for Scalar and Alias is intentional
Currently, the render method produces no output for Self::Scalar and Self::Alias. Ensure this is the desired behavior, as it might lead to incomplete or missing code for these variants in downstream pipelines or generated artifacts.


34-43: Evaluate returning "scalar" as the reference expression
For the Self::Scalar variant, the method always returns a hard-coded "scalar" string. This may cause confusion or inconsistencies if there are multiple types categorized as scalars. Verify if this literal string correctly aligns with your downstream usage or if a more specific or dynamic reference would be preferable.


126-172: Review usage of unwrap() in function code generation
In the Function::render method, the usage of page.get_ref(&self.return_ty).unwrap() may fail under abnormal circumstances. Consider whether advanced error handling or clear diagnostic messages might be beneficial for troubleshooting generation issues.


235-238: Verify ignoring non-composite variants in unions
In build_union, only composite types are inserted into the variants map, and non-composite types are effectively excluded. Confirm that skipping non-composite variants is desired in all cases. If not, consider representing them as scalar or alias variants instead.


256-259: Confirm usage of prop.ty.name() for argument fields
Using prop.ty.name() might introduce collisions for types that share a name, especially across different modules or contexts. Verify that this approach reliably distinguishes argument types or consider an alternative such as using prop.ty.key() for unique identification.

@@ -33,7 +31,7 @@ pub mod shared;

mod fdk_py;
mod fdk_rs;
mod fdk_substantial;
// mod fdk_substantial;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Clean up removed modules.
fdk_substantial is commented out. If permanently deprecated, consider removing references from build configs to maintain a clean codebase.

Comment on lines +159 to +168
// (
// "fdk_substantial".to_string(),
// GeneratorRunner {
// op: |workspace_path: &Path, val| {
// let config = fdk_substantial::FdkSubstantialGenConfig::from_json(val, workspace_path)?;
// let generator = fdk_substantial::Generator::new(config)?;
// Ok(Box::new(generator))
// },
// },
// ),
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove commented-out code if truly deprecated.
Leaving large blocks of commented code for fdk_substantial can confuse maintainers. If it’s intentionally dropped, remove it fully or leave a doc comment clarifying its future.

impl NamingEngine for DefaultNamingEngine {
fn name_value_types(&mut self, value_type: &ValueType) -> Result<()> {
if value_type.is_empty() {
unreachable!("no registered type");
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Replace or justify the unreachable!() usage

Using unreachable!("no registered type") can hide potential runtime surprises if a caller accidentally provides an empty or partially built ValueType. Consider returning an error instead, or documenting why this case is guaranteed not to occur.

Comment on lines +125 to +219
let key = node.key();
let item = std::mem::replace(&mut self.direct[key.0 as usize], MapItem::Unset);
let item = match item {
MapItem::Unset => match &rpath {
RelativePath::Function(_) => MapItem::Function(node.assert_func()?.clone()),
RelativePath::NsObject(path) => {
MapItem::Namespace(node.assert_object()?.clone(), path.clone())
}
RelativePath::Input(_) => {
let dkey = DuplicationKey::from(&node);
if dkey.is_empty() || !node.is_composite() {
MapItem::Value(ValueType {
default: Some(MapValueItem {
ty: node.clone(),
relative_paths: std::iter::once(rpath.clone().try_into().map_err(
|e| eyre!("relative path is not a value type: {:?}", e),
)?)
.collect(),
}),
variants: Default::default(),
})
} else {
let variant = MapValueItem {
ty: node.clone(),
relative_paths: std::iter::once(rpath.clone().try_into().map_err(
|e| eyre!("relative path is not a value type: {:?}", e),
)?)
.collect(),
};
let variants = std::iter::once((dkey, variant)).collect();
MapItem::Value(ValueType {
default: None,
variants,
})
}
}
RelativePath::Output(_) => {
MapItem::Value(ValueType {
default: Some(MapValueItem {
ty: node.clone(),
relative_paths: std::iter::once(rpath.clone().try_into().map_err(
|e| eyre!("relative path is not a value type: {:?}", e),
)?)
.collect(),
}),
variants: Default::default(),
})
}
},
MapItem::Namespace(_, _) => {
bail!("unexpected duplicate namespace type: {:?}", key)
}
MapItem::Function(_) => {
bail!("unexpected duplicate function type: {:?}", key)
}
MapItem::Value(mut value_type) => {
let rpath: ValueTypePath = rpath
.clone()
.try_into()
.map_err(|e| eyre!("relative path is not a value type: {:?}", e))?;
let dkey = DuplicationKey::from(&node);
if key.1 == 0 {
debug_assert!(dkey.is_empty());
if value_type.default.is_some() {
bail!("duplicate default value type: {:?}", key);
}
value_type.default = Some(MapValueItem {
ty: node.clone(),
relative_paths: std::iter::once(rpath).collect(),
});
} else {
debug_assert!(!dkey.is_empty());
let index = key.1 - 1;
if index != value_type.variants.len() as u32 {
bail!("unexpected ordinal number for type registration: {:?}", key);
}
value_type.variants.insert(
dkey,
MapValueItem {
ty: node.clone(),
relative_paths: std::iter::once(rpath).collect(),
},
);
}
MapItem::Value(value_type)
}
};
self.direct[key.0 as usize] = item;

let old = self.reverse.insert(rpath.clone(), key);
if old.is_some() {
bail!("duplicate relative path: {:?}", rpath);
}

Ok(())
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Refactor large register function for readability

The register function covers multiple cases (namespace, function, input, output, etc.) in a large match block. Splitting these branches into helper functions could improve maintainability and readability, making it easier to add new item types and debug.

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

🧹 Nitpick comments (18)
src/typegraph/graph/src/lib.rs (2)

58-70: Consider restricting public access to internal implementation details

The Typegraph struct has all fields marked as pub, which exposes implementation details and makes future refactoring more difficult. Consider making some fields private and providing accessor methods where needed.

 #[derive(Debug)]
 pub struct Typegraph {
-    pub schema: Arc<tg_schema::Typegraph>,
-    pub root: Arc<ObjectType>,
-    pub input_types: IndexMap<TypeKey, Type>,
-    pub output_types: IndexMap<TypeKey, Type>,
-    pub functions: IndexMap<u32, Arc<FunctionType>>,
-    pub namespace_objects: IndexMap<Vec<Arc<str>>, Arc<ObjectType>>,
-    pub named: HashMap<Arc<str>, Type>,
-    pub conversion_map: Vec<MapItem>,
-    pub runtimes: Vec<Arc<TGRuntime>>,
-    pub materializers: Vec<Materializer>,
+    schema: Arc<tg_schema::Typegraph>,
+    root: Arc<ObjectType>,
+    input_types: IndexMap<TypeKey, Type>,
+    output_types: IndexMap<TypeKey, Type>,
+    functions: IndexMap<u32, Arc<FunctionType>>,
+    namespace_objects: IndexMap<Vec<Arc<str>>, Arc<ObjectType>>,
+    named: HashMap<Arc<str>, Type>,
+    conversion_map: Vec<MapItem>,
+    runtimes: Vec<Arc<TGRuntime>>,
+    materializers: Vec<Materializer>,
 }

Then add accessor methods for fields that should be accessed externally.


116-116: Remove commented code

The line contains a commented-out type definition. Either use it or remove it to keep the code clean.

-    // Item = Result<Arc<FunctionType>, Error>;
     type Item = Result<(Vec<Arc<str>>, Arc<FunctionType>)>;
src/typegraph/graph/src/conv/mod.rs (2)

4-6: Correct the truncated license identifier.

The "SPDX-Lice" line is incomplete. Please fix it to ensure the license identifier is fully recognized and complies with standard formatting.


226-349: Reduce repetitive pattern matching.

The match arms handle different scalar and composite types similarly. Consider factoring out repeated logic into shared helper functions to make the code more concise.

src/typegraph/graph/src/types/mod.rs (2)

45-71: Handle potential Weak pointer upgrade failures more gracefully.

Using expect(...) might cause runtime panics if the underlying strong reference is dropped. Consider error handling or fallback logic in production settings.


112-168: Be mindful of performance in deep graphs.

The is_descendant_of method uses a traversal that can grow expensive. Memoization or early stopping could mitigate performance issues in large or heavily nested type graphs.

src/typegraph/graph/src/types/union.rs (1)

77-114: Consider removing commented-out finalization logic.

Lines 107-109 are disabled, which can cause confusion. If the code is no longer needed, removing it will help maintain clarity.

src/typegraph/graph/src/types/optional.rs (1)

16-20: Use a more descriptive error message or custom error handling.
Currently, if item is never initialized, this will cause a runtime panic. A clearer error message or custom error type can help with debugging and error handling in production.

src/typegraph/graph/src/types/list.rs (1)

17-19: Enhance the error message when item is uninitialized.
Like the optional type, it is safer to provide a more detailed error message or a custom error type to facilitate troubleshooting.

src/typegraph/graph/src/types/object.rs (2)

35-41: Consider configurable handling of empty objects.
non_empty returns None if there are no properties, implying an object cannot be empty. If empty objects are valid for some use cases, consider making this behavior configurable.


142-142: Implement outjection behavior or remove the placeholder.
There's a TODO indicating future outjection logic. If this is part of the design, consider implementing it or removing the placeholder for clarity.

Do you want me to draft a basic approach for outjection handling and open a new issue?

src/typegraph/graph/src/types/function.rs (3)

63-65: Consider adding a comment to explain the children relationship

The children() method returns both the input and output types as children of the function type. It would be helpful to add a comment explaining the semantics of this relationship, especially since you're also defining edges separately.


83-108: Add documentation to explain the conversion process

The convert_function function is a key part of the typegraph conversion process, but lacks documentation explaining its purpose, parameters, and return value. Consider adding rustdoc comments to enhance code maintainability.

/// Converts a schema function type to a graph function type.
/// 
/// # Parameters
/// * `parent` - The parent type that contains this function
/// * `key` - The unique identifier for this type
/// * `base` - Base type information from the schema
/// * `data` - Function-specific data from the schema
/// * `materializer` - The materializer responsible for executing this function
/// * `schema` - The complete typegraph schema
///
/// # Returns
/// A boxed conversion result that can be finalized later in the conversion process.
pub(crate) fn convert_function(
    parent: WeakType,
    key: TypeKey,
    base: &tg_schema::TypeNodeBase,
    data: &tg_schema::FunctionTypeData,
    materializer: Arc<MaterializerNode>,
    schema: &tg_schema::Typegraph,
) -> Box<dyn TypeConversionResult> {

13-23: Add documentation to the FunctionType struct

Consider adding rustdoc comments to the FunctionType struct and its fields to explain their purpose and usage. This would significantly improve the maintainability of the code for future developers.

/// Represents a function type in the typegraph, connecting input and output types
/// through a materializer that defines its runtime behavior.
#[derive(Debug)]
pub struct FunctionType {
    /// Base type information
    pub base: TypeBase,
    /// Input object type, lazily initialized during conversion
    pub(crate) input: Once<Arc<ObjectType>>,
    /// Output type, lazily initialized during conversion
    pub(crate) output: Once<Type>,
    /// Optional transformation applied to function parameters
    pub parameter_transform: Option<FunctionParameterTransform>,
    /// Configuration for the runtime. TODO should not this be removed?
    pub runtime_config: serde_json::Value,
    /// Materializer that defines how the function is executed
    pub materializer: Materializer,
    /// Optional weight for rate limiting
    pub rate_weight: Option<u32>,
    /// Whether to count calls for rate limiting
    pub rate_calls: bool,
}
src/metagen/src/fdk_py/types.rs (4)

15-19: Consider deriving additional traits for AliasTarget.

AliasTarget might benefit from derivations like Clone, PartialEq, or Eq for easier manipulation and testing.

 #[derive(Debug)]
+#[derive(Debug, Clone, PartialEq, Eq)]
 pub enum AliasTarget {

93-105: Leverage privacy modifiers for ObjectProperty.

If ObjectProperty is only used internally, consider making it pub(crate) rather than fully public. This helps keep the API surface small and avoid accidental misuse.


180-187: Enclose quoted type names carefully.

quote_ty_name ensures a string-literal style while avoiding double quoting. This logic looks correct, but watch out for edge cases (e.g., leading/trailing spaces).


228-333: Comprehensive match arms for each Type.

  • Great handling of Boolean, Float, Integer, etc.
  • unreachable!() for Type::Function(_) might be safer to replace with an error or fallback in unexpected edge cases.
  • Repeated code for the alias_required branches suggests a potential for factorization.

Would you like me to suggest a refactoring that reduces repetition in these match arms?

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5725a1f and 5543e54.

📒 Files selected for processing (9)
  • src/metagen/src/fdk_py/types.rs (1 hunks)
  • src/typegraph/graph/src/conv/mod.rs (1 hunks)
  • src/typegraph/graph/src/lib.rs (1 hunks)
  • src/typegraph/graph/src/types/function.rs (1 hunks)
  • src/typegraph/graph/src/types/list.rs (1 hunks)
  • src/typegraph/graph/src/types/mod.rs (1 hunks)
  • src/typegraph/graph/src/types/object.rs (1 hunks)
  • src/typegraph/graph/src/types/optional.rs (1 hunks)
  • src/typegraph/graph/src/types/union.rs (1 hunks)
🧰 Additional context used
🧬 Code Definitions (5)
src/typegraph/graph/src/conv/mod.rs (4)
src/typegraph/graph/src/policies.rs (2)
  • convert_policy (28-34)
  • convert_policy_spec (48-59)
src/typegraph/graph/src/runtimes.rs (1)
  • convert_materializer (19-27)
src/typegraph/graph/src/types/mod.rs (3)
  • key (117-117)
  • key (146-148)
  • base (101-101)
src/typegraph/graph/src/conv/map.rs (1)
  • new (85-93)
src/typegraph/graph/src/types/mod.rs (10)
src/typegraph/graph/src/types/function.rs (4)
  • base (55-57)
  • tag (59-61)
  • children (63-65)
  • edges (67-80)
src/typegraph/graph/src/types/optional.rs (4)
  • base (24-26)
  • tag (28-30)
  • children (32-34)
  • edges (36-42)
src/typegraph/graph/src/types/object.rs (4)
  • base (45-47)
  • tag (49-51)
  • children (53-55)
  • edges (57-66)
src/typegraph/graph/src/types/union.rs (4)
  • base (25-27)
  • tag (29-35)
  • children (37-39)
  • edges (41-51)
src/typegraph/graph/src/types/list.rs (4)
  • base (23-25)
  • tag (27-29)
  • children (31-33)
  • edges (35-41)
src/typegraph/graph/src/types/file.rs (2)
  • base (17-19)
  • tag (21-23)
src/typegraph/graph/src/types/float.rs (2)
  • base (19-21)
  • tag (23-25)
src/typegraph/graph/src/types/integer.rs (2)
  • base (19-21)
  • tag (23-25)
src/typegraph/graph/src/types/string.rs (2)
  • base (19-21)
  • tag (23-25)
src/typegraph/graph/src/types/boolean.rs (2)
  • base (14-16)
  • tag (18-20)
src/typegraph/graph/src/types/function.rs (1)
src/typegraph/graph/src/path.rs (2)
  • input (273-279)
  • output (281-287)
src/metagen/src/fdk_py/types.rs (4)
src/metagen/src/shared/types.rs (1)
  • type_body_required (23-38)
src/metagen/src/fdk_py/mod.rs (2)
  • from (23-28)
  • new (63-67)
src/metagen/src/shared/manifest.rs (2)
  • from (40-46)
  • get_reference_expr (22-22)
src/metagen/src/fdk_py/utils.rs (2)
  • from (16-21)
  • map (77-81)
src/typegraph/graph/src/types/optional.rs (4)
src/typegraph/graph/src/types/list.rs (4)
  • item (17-19)
  • base (23-25)
  • tag (27-29)
  • children (31-33)
src/typegraph/graph/src/types/object.rs (3)
  • base (45-47)
  • tag (49-51)
  • children (53-55)
src/typegraph/graph/src/types/union.rs (3)
  • base (25-27)
  • tag (29-35)
  • children (37-39)
src/typegraph/graph/src/types/mod.rs (3)
  • base (101-101)
  • tag (102-102)
  • children (104-106)
🔇 Additional comments (35)
src/typegraph/graph/src/lib.rs (7)

15-15: Consider using standard LazyLock instead of aliasing OnceLock

You're using pub type Once<T> = std::sync::OnceLock<T>; when Rust has LazyLock for similar functionality. This is more idiomatic and clearer for other Rust developers.

-    pub type Once<T> = std::sync::OnceLock<T>;
+    pub use std::sync::LazyLock;

139-142: Improve error messaging for unexpected root function types

Include the path in the error message to aid in debugging. This makes it easier to trace where the issue occurs in the typegraph.

            _ => Some(Err(eyre!(
-                "unexpected type for root function: '{}'",
-                item.ty.tag()
+                "unexpected type for root function: '{}' at path {:?}",
+                item.ty.tag(),
+                item.path
            ))),

4-10: LGTM! Module organization looks clean

Good module organization with clear separation of concerns. The distinction between public and private modules is appropriate for the functionality being exposed.


38-56: LGTM! MapItem enum and implementation are well-structured

The MapItem enum and its TryFrom implementation are well-designed with proper error handling. The pattern matching is comprehensive and handles all possible cases.


72-81: LGTM! The find_type method is concise and effective

The find_type method efficiently handles the retrieval of types based on their keys, with proper handling of all MapItem variants.


90-103: LGTM! Well-implemented typegraph traversal functionality

The root_functions method provides a clean interface for traversing the typegraph, and the name method is a simple and useful accessor.


105-145: Root function iterator implementation is thorough

The iterator implementation for traversing root functions is well-structured and handles various types appropriately. The recursion through the object's properties is implemented cleanly.

src/typegraph/graph/src/conv/mod.rs (4)

32-43: Good struct design for capturing conversion context.

Using Arc<tg_schema::Typegraph> and other per-conversion fields tightly groups the necessary data for type conversion, improving readability and maintainability.


45-66: Clear separation of type conversion and finalization.

Defining a dedicated trait with separate methods for retrieving types and finalizing them increases clarity in the conversion flow.


96-154:

✅ Verification successful

Ensure consistent usage throughout the codebase.

As the central entry point for type conversion, confirm that calls to Conversion::convert are properly integrated in other modules and tested for correctness.


🏁 Script executed:

#!/bin/bash
# Searching for references to `Conversion::convert`
rg -A 5 "Conversion::convert"

Length of output: 365


Verify Integration and Testing of Conversion Functionality

We confirmed that the conversion function in src/typegraph/graph/src/conv/mod.rs is properly integrated—in particular, we found its invocation in src/typegraph/graph/src/lib.rs using:

conv::Conversion::convert(schema, DefaultNamingEngine::default())

Please ensure that:

  • All modules consistently use Conversion::convert and follow the same naming/error-handling conventions.
  • Adequate tests are in place to verify the correctness of conversion across all edge cases.

156-180:

❓ Verification inconclusive

Revisit cycle-detection strategy.

The code uses cyclic = rpath.pop().contains(...) to catch recursion. Verify all edge cases where nested cycles might not be caught, ensuring robust prevention of infinite loops.


🏁 Script executed:

#!/bin/bash
# Attempt to locate any special handling or tests referencing recursion scenarios
rg -A 5 'cyclic|recursion|infinite loop'

Length of output: 11208


Revisit Cycle-Detection Implementation

Please double-check that the current strategy using rpath.pop().contains(&self.schema.types, &From::from(&ty)) reliably detects all nested cycles. For instance:

  • Ensure that deeply nested or indirect cycles are correctly flagged.
  • Verify compatibility and consistency with other cycle-detection approaches in the codebase (e.g., in visitor.rs and typegraph.rs).
  • Consider augmenting the existing tests or adding new ones to cover edge cases, especially for non-function types where recursion is applied.
src/typegraph/graph/src/types/mod.rs (2)

34-44: Well-defined edge classification.

Enumerating every relationship—for optional items, list items, object properties, and so on—makes the graph’s structure explicit and easier to maintain.


84-97: Comprehensive type coverage.

The Type enum supports a broad spectrum of cases, which effectively centralizes type logic in a single cohesive structure.

src/typegraph/graph/src/types/union.rs (2)

9-14: Clear representation of union types.

The UnionType struct fields, especially the Once<Vec<Type>> for lazy initialization, form a clean pattern for deferred population of variants.


54-75:

✅ Verification successful

Validate correct rpath usage during conversion.

The convert_union function constructs union types effectively. Run checks to ensure the rpath and variant indices remain consistent with the surrounding context.


🏁 Script executed:

#!/bin/bash
# Searching for references to `convert_union` usage
rg "convert_union"

Length of output: 355


Verified rpath propagation in union conversion

The review request to validate rpath usage has been checked:

  • In src/typegraph/graph/src/types/union.rs, the rpath is cloned for use in the base conversion and then forwarded intact into the UnionTypeConversionResult.
  • References in src/typegraph/graph/src/conv/mod.rs confirm that convert_union is invoked where a consistent and correct rpath is expected and maintained.

Based on these findings, the rpath propagation and handling of variant indices appear consistent with the surrounding code context.

src/typegraph/graph/src/types/optional.rs (2)

45-65: Validate default_value or clarify its usage.
While default_value is being propagated into the OptionalType, there's no validation or usage context shown here. Consider verifying that default_value is compatible with the underlying item type or is otherwise handled appropriately.


87-92: Confirm one-time initialization logic under concurrent conversions.
The OnceLock usage ensures item can be set exactly once, but if multiple threads attempt to call finalize for the same type simultaneously, it may create race conditions or spurious errors. Verify that such concurrent calls do not occur or are handled correctly elsewhere.

src/typegraph/graph/src/types/list.rs (2)

52-66: Validate min_items and max_items.
When both fields are set, ensure min_items <= max_items to avoid unexpected runtime issues.

+ if let (Some(min), Some(max)) = (ty.min_items, ty.max_items) {
+     assert!(
+         min <= max,
+         "min_items cannot exceed max_items. min: {}, max: {}",
+         min, max
+     );
+ }

84-86: Confirm correct finalization order.
The item is finalized, then set via OnceLock. This sequence is typically correct, but if any errors can arise during item finalization, ensure the ListType does not remain in a half‐initialized state.

src/typegraph/graph/src/types/object.rs (1)

125-128: Request verification for nested injections.
This code handles injection from the Parent by mapping children. If deeper nested injections are required, ensure the logic correctly resolves them or add tests to confirm.

src/typegraph/graph/src/types/function.rs (5)

19-19: Consider clarifying or addressing the TODO comment

The TODO comment suggests uncertainty about whether the runtime_config field should be removed. This aligns with a previous review comment asking "We don't have use for it today?". If this field is genuinely not needed, consider removing it. Otherwise, document its purpose to clarify its role.


29-36: LGTM: Efficient handling of empty input objects

Nice implementation of the non_empty_input() method, which avoids returning empty input objects. This is a useful optimization that can simplify client code when dealing with functions that don't require input parameters.


42-47: LGTM: Clear effect type retrieval

The effect() method cleanly handles the default case when no effect is specified by returning EffectType::Read. This helps maintain consistent behavior for callers.


67-80: LGTM: Comprehensive edge definition

The edges() method properly defines the relationships between the function type and its input/output types, which is crucial for traversing the type graph. Good job using weak references to avoid reference cycles.


121-162: LGTM: Thorough finalization with robust error handling

The finalize method in FunctionTypeConversionResult is well implemented with comprehensive error handling. Good job including detailed error messages that include the type key to aid in debugging, and properly ensuring both input and output types are correctly set and finalized.

src/metagen/src/fdk_py/types.rs (10)

4-7: Imports look solid.

No immediate issues spotted. The additional imports from Cow, fmt::Write, and IndexMap appear necessary given the usage in subsequent code.


21-27: Builder-like approach for Alias is clear.

Storing AliasTarget, container, and quote as separate fields is an intuitive design for flexible type definitions. No immediate concerns here.


29-38: Defaulting fields in From<AliasTarget> is convenient.

The fallback values (name: None, container: None, quote: false) streamline creation of Alias objects and reduce boilerplate.


40-61: Fluent builder methods are well-structured.

These named, container, and quote methods follow a good pattern for incremental construction. All methods return Self, promoting a user-friendly API.


107-132: TypedDict approach is correct but watch Python version constraints.

  • Good usage of total=False to make fields optional.
  • The comment notes Python 3.11’s NotRequired; consider a version check or fallback for older environments.

Would you like me to propose a script that ensures your code runs in Python 3.9+ without issues?


134-146: Union rendering is straightforward.

The function is succinct and effectively prints the typing.Union line by line. No immediate issues found.


148-178: LiteralEnum and Union design is consistent.

Both structures neatly implement render with similar patterns. This consistency enhances maintainability.


188-226: Implementation of ManifestEntry for PyType is clean.

  • The match arms are well organized and easy to follow.
  • Returning Option<String> in get_reference_expr is a practical approach for references.

335-349: Add validations or logs when generating PyTypesPage.

This block processes tg.input_types and tg.output_types. If a type fails conversion or has an unexpected variant, code might silently skip it. Add logging/validations to ensure all expected types map correctly.


9-13:

✅ Verification successful

Check for unused imports.

Although these items (normalize_struct_prop_name, normalize_type_title, ManifestEntry, ManifestPage, type_body_required) seem relevant, double-check that all are used in this file to avoid dead code or maintenance overhead.

Would you like to verify usage with a shell script?


🏁 Script executed:

#!/bin/bash
rg 'normalize_struct_prop_name|normalize_type_title|ManifestEntry|ManifestPage|type_body_required' src/metagen/src/fdk_py/types.rs

Length of output: 1430


All imported items are in use.

After verifying with the search output, each of the imported functions and types—normalize_struct_prop_name, normalize_type_title, ManifestEntry, ManifestPage, and type_body_required—is referenced in the file. No unused imports were detected.

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

🧹 Nitpick comments (3)
src/metagen/src/utils.rs (1)

4-5: Consider avoiding wildcard imports to reduce potential namespace pollution.

Although use crate::interlude::*; can be convenient, explicitly importing required items often improves clarity and prevents naming conflicts in larger projects.

tests/metagen/typegraphs/identities/py/fdk.py (2)

35-213: Consider refactoring selection_to_nodes for better readability.

This function is quite large (exceeding 150 lines) and embeds multiple nested conditionals. Splitting it into smaller, well-named helper methods could improve maintainability and clarity.


942-992: Consider adding dedicated tests for PreparedRequest.

PreparedRequest is a core class for building GraphQL queries, yet it doesn't seem to have direct unit tests. Comprehensive tests would help ensure that variable resolution, file mapping, and error handling are robust.

Do you want me to generate an example test suite for PreparedRequest to cover these scenarios?

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5543e54 and 9d6760f.

📒 Files selected for processing (8)
  • src/metagen/src/client_py/mod.rs (6 hunks)
  • src/metagen/src/client_py/static/client.py (10 hunks)
  • src/metagen/src/fdk_py/mod.rs (3 hunks)
  • src/metagen/src/fdk_py/static/main.py.jinja (0 hunks)
  • src/metagen/src/fdk_py/static/struct.py.jinja (0 hunks)
  • src/metagen/src/fdk_py/static/types.py.jinja (0 hunks)
  • src/metagen/src/utils.rs (2 hunks)
  • tests/metagen/typegraphs/identities/py/fdk.py (1 hunks)
💤 Files with no reviewable changes (3)
  • src/metagen/src/fdk_py/static/main.py.jinja
  • src/metagen/src/fdk_py/static/struct.py.jinja
  • src/metagen/src/fdk_py/static/types.py.jinja
🧰 Additional context used
🧬 Code Definitions (3)
src/metagen/src/client_py/mod.rs (3)
src/metagen/src/client_py/selections.rs (1)
  • new (144-210)
src/metagen/src/shared/node_metas.rs (1)
  • new (22-30)
src/metagen/src/shared/client.rs (1)
  • get_gql_types (7-33)
src/metagen/src/fdk_py/mod.rs (5)
src/metagen/src/fdk_py/types.rs (3)
  • from (30-37)
  • from (229-332)
  • new (336-347)
src/metagen/src/fdk_py/utils.rs (1)
  • from (16-21)
src/metagen/src/client_py/mod.rs (2)
  • new (49-53)
  • new (120-142)
src/metagen/src/client_py/selections.rs (1)
  • new (144-210)
src/metagen/src/shared/mod.rs (1)
  • filter_stubbed_funcs (23-37)
tests/metagen/typegraphs/identities/py/fdk.py (4)
src/metagen/src/fdk_py/static/fdk.py (2)
  • Ctx (16-32)
  • gql (31-32)
src/metagen/src/client_py/static/client.py (11)
  • query (687-692)
  • query (695-700)
  • query (702-711)
  • get (378-379)
  • QueryNode (250-251)
  • GraphQLTransportOptions (448-449)
  • build_gql (591-615)
  • fetch (678-684)
  • fetch (742-777)
  • fetch (852-870)
  • HostcallTransport (841-924)
src/metagen/src/lib.rs (1)
  • get (135-213)
src/metagen/src/fdk_ts/types.rs (2)
  • ty (204-216)
  • ty (224-228)
🪛 Ruff (0.8.2)
tests/metagen/typegraphs/identities/py/fdk.py

1289-1289: Undefined name Primitives

(F821)


1293-1293: Undefined name PrimitivesStrString

(F821)


1294-1294: Undefined name PrimitivesEnumStringEnum

(F821)


1295-1295: Undefined name PrimitivesUuidStringUuid

(F821)


1296-1296: Undefined name PrimitivesEmailStringEmail

(F821)


1297-1297: Undefined name PrimitivesEanStringEan

(F821)


1298-1298: Undefined name PrimitivesJsonStringJson

(F821)


1299-1299: Undefined name PrimitivesUriStringUri

(F821)


1300-1300: Undefined name PrimitivesDateStringDate

(F821)


1301-1301: Undefined name PrimitivesDatetimeStringDatetime

(F821)


1302-1302: Undefined name PrimitivesIntInteger

(F821)


1303-1303: Undefined name PrimitivesFloatFloat

(F821)


1304-1304: Undefined name PrimitivesBooleanBoolean

(F821)


1336-1336: Undefined name Composites

(F821)


1341-1341: Undefined name CompositesEitherEither

(F821)


1342-1342: Undefined name CompositesUnionUnion

(F821)


1343-1343: Undefined name CompositesListPrimitivesStrStringList

(F821)


1350-1350: Undefined name Branch2

(F821)


1358-1358: Undefined name Branch4

(F821)


1361-1361: Undefined name Branch4again

(F821)


1376-1376: Undefined name Cycles1

(F821)


1388-1388: Undefined name Cycles3

(F821)


1393-1393: Undefined name Branch33A

(F821)


1394-1394: Undefined name Branch33B

(F821)


1414-1414: Undefined name SimpleCycles1

(F821)

🔇 Additional comments (40)
src/metagen/src/utils.rs (2)

31-105: Ensure thorough testing for nested and complex directives.

The conditional parsing logic (metagen-skip, metagen-genif, etc.) is straightforward, but it might be prone to edge cases—particularly with nested or sequential directives. Add or confirm test coverage for scenarios where multiple directives appear in the same block to reduce the risk of subtle off-by-one or unbalanced stack conditions.


107-180: Implementation seems correct and well-structured.

The new utilities (collect_at_first_instance, indent_lines, and indent_lines_into) are logically sound and potentially very useful for code generation scenarios. The approach of reordering lines and straightforward indentation is efficient.

src/metagen/src/client_py/mod.rs (11)

11-17: Imports aligned with new manifest structures.

Introducing PyTypesPage, PyNodeMetasPage, PySelectionsPage, and TypeNodeExt reflects the refactored design for Python client code generation.


24-44: Validation for ClientPyGenConfig looks good.

Using #[derive(Serialize, Deserialize, Debug, garde::Validate)] ensures correctness and type-safe configuration, minimizing potential runtime misconfigurations.


49-49: Commendable approach using garde::Validate in new().

This pattern centralizes all config checks, allowing immediate feedback if the user's input is invalid.


90-100: Simple generation flow aids maintainability.

Constructing the manifest, rendering it into client.py, and inserting into the output IndexMap is clear. This streamlined process should facilitate debugging and future enhancements.


106-117: Maps struct is a concise way to gather references.

Consolidating type, node meta, and selection mappings in one place helps maintain clarity in the generated code.


119-143: Good layering of pages in ClientPyManifest::new.

Manually caching references in each page ensures efficiency, especially given the repeated lookups from node metas and selections.


145-156: Header addition with versioning notice is useful.

Adding the generated file comment ensures developers don’t inadvertently edit an auto-generated file.


160-174: render_client neatly composes sub-renders.

This modular approach—rendering static content, node metas, types, and selections—enhances code readability and reduces coupling.


178-206: render_query_graph logic is intuitive.

Mapping each type to an appropriate GraphQL string and generating a Python QueryGraph class is a clean solution and fosters consistent queries in the codegen.


208-266: render_root_functions effectively generates user-facing methods.

Auto-exposing functions as Python methods via the type graph fosters a more complete and developer-friendly SDK.


271-278: Use of processed_write for handling flags is consistent.

Passing the HOSTCALL flag helps reuse or delegate special-case logic within the same pipeline, improving maintainability.

src/metagen/src/fdk_py/mod.rs (13)

4-5: Explicit imports enhance clarity.

Using core::fmt::Write and std::borrow::Cow signals direct intention and reduces confusion around which modules are in scope.


9-16: Publicly declared modules keep structure organized.

Making types and utils public clarifies API boundaries for other crates or modules that might rely on them.


18-20: Template constants are simplified.

Defining DEFAULT_TEMPLATE as &[(&str, &str)] is straightforward and keeps the code self-contained for FDK Python generation.


22-29: FdkPythonTemplate struct introduction.

This approach decouples the template content from the rendering logic and simplifies expansions to multiple template files.


36-40: Skipping runtime validation on certain fields for FdkPythonGenConfig.

Marking fields with #[garde(skip)] is helpful when fields are optional or validated by other means. Keep an eye on potential usage expansions.


63-67: Central config validation.

Similar to the client Py approach, using garde::Validate here ensures consistent error handling during generator initialization.


70-99: render_fdk_py cleanly orchestrates output generation.

Notably, the usage of GenDestBuf for incremental string building and the flexible user choice to exclude the client code demonstrate well-structured compliance with user preferences (e.g. exclude_client).


102-108: Stubbed runtimes logic is properly integrated.

Filtering out functions by runtime and producing wrapper definitions is a robust approach, avoiding partial or incomplete stubs.


109-137: Exception handling for intermediate data is thorough.

Raises immediate errors if required fields for the stubbed function are missing, preventing incomplete code generation.


139-143: Regex usage in collect_at_first_instance.

Rearranging imports or from statements to a top location helps keep a consistent structure. This logic is a strong fit for code organization patterns.


145-155: gen_static usage with processed_write.

Combining the template content with the HOSTCALL flag is consistent with the approach in client_py. This ensures unified handling of environment-specific generation.


198-210: Generation flow builds upon FDK templates seamlessly.

Merging the template into the output under fdk.py ensures minimal duplication of logic across the codebase.


216-276: End-to-end test coverage confirms output correctness.

Running ruff as part of the generation pipeline is a neat way to verify code style and syntax, reducing manual steps for end users.

src/metagen/src/client_py/static/client.py (11)

1-2: Imports and JSON usage.

Pulling in dataclasses, http.client, JSON, and mimetypes is aligned with the new transport and multi-part form functionalities.

Also applies to: 4-5


8-10: Conditional hostcall import logic.

Using metagen-genif-not and metagen-skip ensures minimal overhead in builds that don’t require hostcall transport.


33-33: Line 33: select_all usage is consistent.

No immediate issues identified, but ensure extended coverage for complex or partial selections in test suites.


516-521: Union selection logic.

Building a single GraphQL block with multiple variant expansions is correct. The code properly appends variant fields in a type-assertion style.


580-685: GraphQLTransportBase as an abstract class.

Promoting a fetch contract with @abstractmethod clarifies that each transport must provide its own fetching logic. This is an excellent design for extension.


677-684: Optional file dict in fetch.

Accepting a None or empty files dictionary for the transport method is a flexible approach. Expand usage if partial file support arises.


741-832: GraphQLTransportUrlib enhancements.

Handling None for file uploads, then gracefully building requests or catching HTTP errors is robust. Use of request.Request fosters standard Pythonic patterns.


834-839: HostcallBinding definition.

A functional type signature clarifies usage, ensuring code generation for hostcall-based expansions remains consistent.


841-925: HostcallTransport

Rejecting file uploads with an explicit exception clarifies limitations. The specialized fetch method parallels the standard transport approach while hooking into the user-provided gql_fn.


930-980: PreparedRequest

Lazily resolving placeholders and single-node checks are well-implemented. This approach gives advanced usage scenarios for partial arguments.


992-1015: Transports utility

Providing both a graphql_sync and hostcall method ensures a consistent API for different runtime contexts.

tests/metagen/typegraphs/identities/py/fdk.py (3)

355-367: Implementation for extract_files looks solid.

The parsing logic for nested file objects appears correct, with straightforward handling of array and dictionary structures. No issues identified here.


482-536: Validate path rewriting logic in convert_query_node_gql.

re.sub is used to transform file path references, and any unexpected user input might break these references. Confirm that user input is trusted or properly sanitized, especially if there's a chance of malicious or malformed values.


17-22:

❓ Verification inconclusive

Check forward references for HostcallBinding and HostcallTransport.

The constructor type hints 'HostcallBinding' and 'HostcallTransport' rely on forward references. If they are never defined (or only defined later), it may cause runtime issues unless you use from __future__ import annotations or ensure the classes are defined prior to usage.

To confirm the presence of the definitions, you could search the codebase as follows:


🏁 Script executed:

#!/bin/bash
ast-grep --pattern $'class $_\n{\n  $$$\n}'

Length of output: 65901


Action Required: Verify Forward References for HostcallBinding and HostcallTransport

In the constructor of the Ctx class (lines 17–22 in tests/metagen/typegraphs/identities/py/fdk.py), the type hints for HostcallBinding and HostcallTransport are written as forward references. This may lead to runtime issues if these classes are not defined before the Ctx class is used. To mitigate potential errors, please verify one of the following:

  • If the classes are defined later in the code (or imported dynamically), ensure that you either import them before their use or add
    from __future__ import annotations
    at the top of the file to postpone type evaluation.
  • If they aren’t defined at all, add their implementations or adjust the design accordingly.

Since our automated repository search (using AST-based patterns) did not conclusively locate definitions for these classes, manual verification in your codebase is needed.

Comment on lines +38 to +40
path: &mut Vec<Edge>,
accumulator: &mut A,
visit_fn: V,
Copy link
Contributor

Choose a reason for hiding this comment

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

I am seeing that type V is the only point accumulator is used, why not rm it from the args?

Comment on lines +346 to +347
}
N::Any { .. } => unreachable!(), // FIXME is this still used?
Copy link
Contributor

Choose a reason for hiding this comment

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

I suppose this could be replaced by the new t.json() scalar proposal

Copy link
Contributor

@michael-0acf4 michael-0acf4 left a comment

Choose a reason for hiding this comment

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

huge PR🧠

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

♻️ Duplicate comments (1)
src/metagen/src/fdk_py/types.rs (1)

74-78: 🛠️ Refactor suggestion

Potential unwrap() failure in target_name.

The page.get_quoted_ref(ty_key) call might panic if the key is not found in the page. Consider adding error handling or a fallback option.

Replace the direct call with a more robust error handling approach:

-AliasTarget::Type(ty_key) => page.get_quoted_ref(ty_key).into(),
+AliasTarget::Type(ty_key) => match page.get_ref(ty_key) {
+    Some(r) => page.quote_if_needed(r).into(),
+    None => "typing.Any".into(), // Fall back to Any type if reference not found
+},
🧹 Nitpick comments (21)
src/metagen/src/client_rs/mod.rs (2)

181-183: Consider adding documentation for GenClientRsOpts

The new struct lacks documentation explaining its purpose and the significance of the hostcall flag.

+/// Options for client code generation
+/// 
+/// Controls specific features that should be included in the generated client.
 pub struct GenClientRsOpts {
+    /// Whether to include hostcall transport in the generated code
     pub hostcall: bool,
 }

253-352: Comprehensive root function generation

The render_root_functions method is thorough in handling different cases:

  • Distinguishes between query and mutation operations
  • Handles functions with and without arguments
  • Creates different implementations for functions with and without selections
  • Properly references the required types from the maps

The code is well-structured with clear logical branches for different cases.

However, this is quite a long method (almost 100 lines) that could potentially be refactored into smaller, more focused methods for better maintainability.

Consider breaking this method into smaller helper methods to improve readability and maintainability. For example:

 fn render_root_functions(&self, dest: &mut impl Write) -> anyhow::Result<()> {
     writeln!(dest, r#"impl QueryGraph{{"#)?;
     for func in self.tg.root_functions() {
         let (path, ty) = func?;
-        use heck::ToSnekCase;
-
-        let node_name = path.join("_");
-        let method_name = node_name.to_snek_case();
-        let out_ty_name = self.maps.output_types.get(&ty.output().key()).unwrap();
-
-        let arg_ty = ty
-            .non_empty_input()
-            .map(|ty| self.maps.input_types.get(&ty.key()).unwrap());
-
-        let select_ty = self.maps.selections.get(&ty.output().key());
-
-        let (marker_ty, node_ty) = match ty.effect() {
-            EffectType::Read => ("QueryMarker", "QueryNode"),
-            EffectType::Update | EffectType::Delete | EffectType::Create => {
-                ("MutationMarker", "MutationNode")
-            }
-        };
-
-        let meta_method = self
-            .maps
-            .node_metas
-            .get(&ty.key())
-            .map(|s| s.as_str())
-            .unwrap_or("scalar");
-
-        let args_row = match &arg_ty {
-            Some(arg_ty) => format!(
-                "
-            args: impl Into<NodeArgs<{arg_ty}>>"
-            ),
-            None => "".into(),
-        };
+        let func_info = self.collect_function_info(path, ty)?;
+        self.render_single_function(dest, &func_info)?;
     }
     writeln!(
         dest,
         "
 }}"
     )?;

     Ok(())
 }
+
+fn collect_function_info(&self, path: Vec<String>, ty: &Type) -> anyhow::Result<FunctionRenderInfo> {
+    use heck::ToSnekCase;
+
+    let node_name = path.join("_");
+    let method_name = node_name.to_snek_case();
+    let out_ty_name = self.maps.output_types.get(&ty.output().key()).unwrap();
+
+    let arg_ty = ty
+        .non_empty_input()
+        .map(|ty| self.maps.input_types.get(&ty.key()).unwrap());
+
+    let select_ty = self.maps.selections.get(&ty.output().key());
+
+    let (marker_ty, node_ty) = match ty.effect() {
+        EffectType::Read => ("QueryMarker", "QueryNode"),
+        EffectType::Update | EffectType::Delete | EffectType::Create => {
+            ("MutationMarker", "MutationNode")
+        }
+    };
+
+    let meta_method = self
+        .maps
+        .node_metas
+        .get(&ty.key())
+        .map(|s| s.as_str())
+        .unwrap_or("scalar");
+
+    let args_row = match &arg_ty {
+        Some(arg_ty) => format!(
+            "
+        args: impl Into<NodeArgs<{arg_ty}>>"
+        ),
+        None => "".into(),
+    };
+
+    Ok(FunctionRenderInfo {
+        node_name,
+        method_name,
+        out_ty_name: out_ty_name.clone(),
+        arg_ty,
+        select_ty,
+        marker_ty: marker_ty.to_string(),
+        node_ty: node_ty.to_string(),
+        meta_method: meta_method.to_string(),
+        args_row,
+    })
+}
+
+fn render_single_function(&self, dest: &mut impl Write, info: &FunctionRenderInfo) -> anyhow::Result<()> {
+    match &info.select_ty {
+        // Render logic for functions with selections...
+        // Render logic for functions without selections...
+    }
+    Ok(())
+}
src/metagen/src/client_rs/selections.rs (3)

6-6: Using TypeNodeExt trait methods

The import statement use typegraph::TypeNodeExt as _; correctly imports the trait for its methods only, but adding a brief comment explaining what extension methods are used would improve code readability.

-use typegraph::TypeNodeExt as _;
+// Import TypeNodeExt for its is_composite() and other utility methods
+use typegraph::TypeNodeExt as _;

147-149: Add explanatory comment for phantom field

The phantom field for empty props needs a clarifying comment explaining its purpose.

        if props.is_empty() {
+            // Add a phantom field to ensure the struct still has a generic parameter when there are no props
            writeln!(dest, r#"    pub phantom: std::marker::PhantomData<ATy>,"#)?;
        }

167-230: Add error handling for typegraph interactions

The manifest_page function lacks explicit error handling for potential issues when interacting with the typegraph.

Consider adding error handling or validation to ensure the function behaves predictably when encountering unexpected type structures:

 pub fn manifest_page(
     tg: &typegraph::Typegraph,
     input_types: IndexMap<TypeKey, String>,
-) -> ManifestPage<RustSelection, Extras> {
+) -> Result<ManifestPage<RustSelection, Extras>, anyhow::Error> {
     let mut map = IndexMap::new();
 
     for (key, ty) in tg.output_types.iter() {
         if !ty.is_composite() {
             continue;
         }
         match ty {
             // ... implementation ...
         }
     }
 
-    ManifestPage::with_extras(map, Extras { input_types })
+    Ok(ManifestPage::with_extras(map, Extras { input_types }))
 }

This would require updating call sites to handle the Result type.

src/metagen-client-rs/Cargo.toml (2)

6-9: Address the TODO comment about sync/async features

There's a TODO comment indicating planned work for sync/async features.

You should either implement these features now or create an issue to track this work item. Would you like me to help draft implementation options for sync/async support?


14-14: Consider relaxing exact version constraints

The exact version constraints on reqwest and url may cause dependency resolution issues.

-reqwest = { version = "=0.12.9", features = ["blocking", "json", "stream", "multipart"], optional = true }
+reqwest = { version = "0.12", features = ["blocking", "json", "stream", "multipart"], optional = true }

-url = "=2.4.1"
+url = "2.4"

Unless there are specific compatibility issues that require exact versions, it's generally better to allow patch-level updates to benefit from bug fixes.

Also applies to: 19-19

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

956-957: Remove TODO comments in test code.

The commented-out TODO and old configuration code in the tests should be removed or updated to reflect the new implementation.

Either implement the missing test functionality or remove the TODO comments to keep the code clean.

src/metagen-client-rs/src/graphql.rs (1)

684-689: Commented out code should be removed.

There are commented out lines (684-689) related to headers that should be removed for code cleanliness.

Remove the commented code if it's no longer needed, or provide a comment explaining why it's being kept.

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

128-129: Limitation in TypedDict implementation.

The comment indicates that all fields are optional due to Python 3.9 TypedDict limitations. Consider documenting this limitation more prominently or providing a version-specific implementation.

For a more robust solution, consider implementing version detection at runtime:

  1. Generate different type definitions based on the Python version
  2. Use try/except blocks to handle imports for newer typing features
  3. Document these limitations clearly in user documentation

345-357: Consider validating types during PyTypesPage creation.

The PyTypesPage::new method iterates through input and output types but doesn't include any validation logic. If a type conversion fails or produces unexpected results, this would be difficult to debug.

Add logging or validation to ensure all types are properly converted:

for (key, ty) in tg.input_types.iter() {
+    debug!("Converting input type {}: {:?}", key, ty);
    map.insert(*key, PyType::from(ty));
}
for (key, ty) in tg.output_types.iter() {
+    debug!("Converting output type {}: {:?}", key, ty);
    map.insert(*key, PyType::from(ty));
}
src/metagen-client-rs/src/files.rs (1)

4-4: Consider avoiding wildcard imports if possible.
It's often better to import only the necessary items to keep the namespace clear and avoid potential naming conflicts.

src/metagen-client-rs/src/common.rs (2)

19-25: Commented-out helper function.
Monitor or remove if it remains unused to avoid confusion.


148-180: sub_nodes expansions with Atomic and Union variants.
The usage of write! ensures structured output. Watch for panic from expect(...) in case of format/disk errors.

tests/metagen/typegraphs/identities/rs/fdk.rs (2)

235-244: Transport docs clarity.
The doc comments adequately explain the available transport methods. Keep them updated as concurrency or new features evolve.


787-800: query_graph() function
Populates ty_to_gql_ty_map with known type mappings. If additional expansions are introduced, ensure these remain updated.

tests/metagen/typegraphs/sample/rs_upload/client.rs (1)

12-26: New transports module is neatly introduced.
The graphql and graphql_sync functions cleanly encapsulate instantiation of their respective transport clients. Consider adding a brief note that states any limitations or prerequisites for these constructors, if necessary.

src/metagen-client-rs/src/hostcall.rs (3)

11-12: HostcallTransportOptions is minimal but flexible.
You may eventually extend these options (e.g., timeouts, headers).


30-64: fetch method uses a synchronous host binding.

  • Good error handling: it distinguishes between host errors vs. JSON or GraphQL errors.
  • Consider logging or capturing the actual GraphQL doc in a debug scenario to aid troubleshooting.

193-239: perform method

  • Clear separation between argument resolution and final host call.
  • Good error translation into PrepareRequestError.

Consider adding a debug log to confirm the final GraphQL doc or variable payload (sanitized for sensitive data) for diagnosing user issues.

tests/metagen/typegraphs/sample/rs/client.rs (1)

7-11: Documentation thoroughly matches the structure introduced.
Include any mention of potential environment constraints (e.g., sync vs. async) if relevant.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9d6760f and c9552f9.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (25)
  • Cargo.toml (2 hunks)
  • src/metagen-client-rs/Cargo.toml (1 hunks)
  • src/metagen-client-rs/src/common.rs (1 hunks)
  • src/metagen-client-rs/src/files.rs (5 hunks)
  • src/metagen-client-rs/src/graphql.rs (22 hunks)
  • src/metagen-client-rs/src/hostcall.rs (1 hunks)
  • src/metagen-client-rs/src/lib.rs (2 hunks)
  • src/metagen-client-rs/src/nodes.rs (1 hunks)
  • src/metagen-client-rs/src/selection.rs (7 hunks)
  • src/metagen/src/client_rs/mod.rs (8 hunks)
  • src/metagen/src/client_rs/selections.rs (2 hunks)
  • src/metagen/src/client_rs/static/client.rs (1 hunks)
  • src/metagen/src/fdk_py/types.rs (1 hunks)
  • src/metagen/src/fdk_rs/mod.rs (10 hunks)
  • src/metagen/src/fdk_rs/static/Cargo.toml (1 hunks)
  • src/metagen/src/fdk_rs/static/fdk.rs (3 hunks)
  • src/metagen/src/fdk_rs/types.rs (22 hunks)
  • tests/metagen/metagen_test.ts (5 hunks)
  • tests/metagen/typegraphs/identities/py/fdk.py (1 hunks)
  • tests/metagen/typegraphs/identities/rs/Cargo.toml (1 hunks)
  • tests/metagen/typegraphs/identities/rs/fdk.rs (6 hunks)
  • tests/metagen/typegraphs/sample/rs/client.rs (11 hunks)
  • tests/metagen/typegraphs/sample/rs/main.rs (6 hunks)
  • tests/metagen/typegraphs/sample/rs_upload/client.rs (3 hunks)
  • tests/metagen/typegraphs/sample/rs_upload/main.rs (3 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/metagen-client-rs/src/nodes.rs
🚧 Files skipped from review as they are similar to previous changes (5)
  • tests/metagen/metagen_test.ts
  • src/metagen-client-rs/src/selection.rs
  • Cargo.toml
  • tests/metagen/typegraphs/sample/rs_upload/main.rs
  • tests/metagen/typegraphs/identities/py/fdk.py
🧰 Additional context used
🧬 Code Definitions (15)
src/metagen/src/fdk_rs/mod.rs (1)
src/metagen/src/client_rs/mod.rs (3)
  • gen_cargo_toml (394-466)
  • new (64-93)
  • new (102-106)
tests/metagen/typegraphs/sample/rs/main.rs (4)
tests/metagen/typegraphs/sample/rs/client.rs (5)
  • query_graph (407-417)
  • graphql_sync (20-25)
  • Post (261-274)
  • graphql (15-17)
  • RootIdentityFnInput (146-157)
src/metagen/src/fdk_rs/static/fdk.rs (2)
  • query_graph (105-107)
  • gql (123-141)
src/metagen/src/client_rs/static/client.rs (2)
  • graphql_sync (20-25)
  • graphql (15-17)
tests/metagen/typegraphs/sample/ts/client.ts (7)
  • Post (987-995)
  • Post (1060-1064)
  • RootCompositeArgsFnInput (1065-1067)
  • graphql (886-892)
  • RootCompositeUnionFnOutputSelections (1115-1118)
  • RootIdentityFnInput (911-917)
  • RootIdentityFnInput (1068-1070)
src/metagen/src/fdk_rs/static/fdk.rs (2)
src/metagen/src/client_rs/static/client.rs (1)
  • hostcall (32-37)
src/metagen/src/client_py/static/client.py (2)
  • hostcall (1006-1012)
  • HostcallTransport (841-924)
src/metagen/src/client_rs/selections.rs (3)
src/metagen/src/client_ts/selections.rs (3)
  • render (25-51)
  • render (67-98)
  • render (104-109)
src/typegraph/graph/src/types/union.rs (1)
  • variants (17-21)
src/metagen/src/shared/client.rs (1)
  • selection_for_field (43-83)
src/metagen-client-rs/src/graphql.rs (1)
src/metagen-client-rs/src/common.rs (3)
  • resolve_prepared_variables (380-409)
  • new (62-71)
  • handle_response (238-279)
src/metagen-client-rs/src/lib.rs (6)
src/metagen-client-rs/src/selection.rs (2)
  • args (342-344)
  • selection (25-28)
src/metagen-client-rs/src/common.rs (1)
  • files (74-86)
src/metagen/src/client_rs/node_metas.rs (1)
  • files (300-303)
src/metagen/src/client_rs/static/client.rs (2)
  • graphql (15-17)
  • hostcall (32-37)
src/metagen/src/fdk_rs/static/fdk.rs (1)
  • hostcall (109-111)
tests/metagen/typegraphs/identities/rs/fdk.rs (1)
  • hostcall (248-253)
src/metagen-client-rs/src/hostcall.rs (4)
src/metagen-client-rs/src/common.rs (5)
  • new (62-71)
  • nodes_len (269-278)
  • handle_response (238-279)
  • from (310-314)
  • from (420-424)
src/metagen-client-rs/src/graphql.rs (14)
  • new (192-198)
  • new (331-337)
  • new (529-558)
  • new (624-654)
  • fetch (200-244)
  • fetch (339-385)
  • query (246-251)
  • query (387-392)
  • res (227-227)
  • res (368-368)
  • res (587-587)
  • res (685-685)
  • clone (726-738)
  • clone (741-753)
src/metagen-client-rs/src/nodes.rs (3)
  • parse_response (57-57)
  • parse_response (178-181)
  • parse_response (194-197)
src/metagen-client-rs/src/args.rs (2)
  • from (12-14)
  • from (28-33)
src/metagen/src/fdk_py/types.rs (3)
src/metagen/src/shared/types.rs (1)
  • type_body_required (23-38)
src/typegraph/graph/src/types/union.rs (1)
  • variants (17-21)
src/metagen/src/fdk_py/utils.rs (1)
  • map (77-81)
src/metagen/src/client_rs/static/client.rs (5)
tests/metagen/typegraphs/sample/rs/client.rs (2)
  • graphql (15-17)
  • graphql_sync (20-25)
src/metagen-client-rs/src/graphql.rs (4)
  • new (192-198)
  • new (331-337)
  • new (529-558)
  • new (624-654)
src/metagen-client-rs/src/hostcall.rs (2)
  • new (23-28)
  • new (163-191)
src/metagen/src/fdk_rs/mod.rs (1)
  • new (82-86)
src/metagen/src/fdk_rs/static/fdk.rs (1)
  • hostcall (109-111)
src/metagen/src/fdk_rs/types.rs (4)
src/metagen/src/shared/types.rs (1)
  • type_body_required (23-38)
src/typegraph/graph/src/types/list.rs (2)
  • item (17-19)
  • tag (27-29)
src/typegraph/graph/src/types/object.rs (2)
  • properties (29-33)
  • tag (49-51)
src/typegraph/graph/src/types/union.rs (2)
  • variants (17-21)
  • tag (29-35)
tests/metagen/typegraphs/sample/rs_upload/client.rs (3)
src/metagen/src/client_rs/static/client.rs (2)
  • graphql (15-17)
  • graphql_sync (20-25)
src/metagen-client-rs/src/graphql.rs (4)
  • new (192-198)
  • new (331-337)
  • new (529-558)
  • new (624-654)
src/metagen/src/fdk_rs/types.rs (1)
  • new (439-444)
src/metagen-client-rs/src/common.rs (4)
src/metagen-client-rs/src/selection.rs (10)
  • args (342-344)
  • fmt (212-239)
  • from (433-435)
  • from (439-441)
  • from (444-446)
  • from (449-451)
  • from (454-456)
  • from (463-465)
  • from (472-474)
  • from (482-488)
src/metagen-client-rs/src/hostcall.rs (6)
  • new (23-28)
  • new (163-191)
  • fmt (292-307)
  • from (278-282)
  • from (285-289)
  • from (312-323)
src/metagen-client-rs/src/graphql.rs (4)
  • new (192-198)
  • new (331-337)
  • new (529-558)
  • new (624-654)
src/metagen-client-rs/src/args.rs (3)
  • fmt (147-151)
  • from (12-14)
  • from (28-33)
tests/metagen/typegraphs/identities/rs/fdk.rs (7)
src/metagen/src/fdk_rs/static/fdk.rs (3)
  • default (35-37)
  • new (41-45)
  • hostcall (109-111)
src/metagen/src/fdk_rs/types.rs (1)
  • new (439-444)
src/metagen/src/fdk_ts/mod.rs (1)
  • new (64-68)
src/metagen/src/fdk_py/types.rs (1)
  • new (346-357)
src/metagen/src/fdk_ts/static/fdk.ts (1)
  • Ctx (1-14)
src/metagen/src/client_py/static/client.py (2)
  • hostcall (1006-1012)
  • HostcallTransport (841-924)
src/metagen/src/client_rs/static/client.rs (1)
  • hostcall (32-37)
tests/metagen/typegraphs/sample/rs/client.rs (3)
src/metagen/src/client_rs/static/client.rs (2)
  • graphql (15-17)
  • graphql_sync (20-25)
src/metagen/src/client_rs/mod.rs (2)
  • new (64-93)
  • new (102-106)
src/typegraph/graph/src/types/mod.rs (2)
  • title (116-116)
  • title (142-144)
src/metagen/src/client_rs/mod.rs (4)
src/metagen/src/fdk_rs/types.rs (3)
  • new (439-444)
  • partial_output_types (414-417)
  • render (63-149)
src/metagen/src/client_rs/selections.rs (2)
  • manifest_page (167-230)
  • render (36-47)
src/metagen/src/shared/manifest.rs (1)
  • render (14-18)
src/metagen/src/client_rs/static/client.rs (1)
  • hostcall (32-37)
🔇 Additional comments (101)
src/metagen/src/client_rs/mod.rs (9)

9-13: Improved import organization for manifest components

The imports have been updated to bring in the necessary components for the new manifest-based architecture. This aligns with the PR objective of expanding the typegraph and providing a more structured approach to code generation.


48-53: Good encapsulation of mapping data

The new Maps struct provides a clean way to encapsulate the various type mappings needed throughout the code generation process. This structure helps maintain the relationships between type keys and their string representations.


55-61: Well-designed manifest structure

The RsClientManifest struct encapsulates all the necessary components for generating Rust client code. This design improves cohesion by grouping related data and functionality together.


63-93: Comprehensive initialization of manifest components

The new method properly initializes all components of the manifest, including caching references for better performance. The function follows a clear stepwise approach:

  1. Build the types manifest with appropriate configuration
  2. Cache references for input and output types
  3. Build and cache node metadata
  4. Build and cache selections
  5. Combine all components into the final manifest

This structured approach enhances maintainability and readability.


130-152: Simplified Generator::generate implementation

The implementation has been improved to use the new manifest-based approach, which makes the code more concise and easier to understand. Instead of directly rendering to the output, it now delegates to the manifest's render method.


185-217: Well-structured rendering pipeline

The render and render_client methods provide a clear entry point for generating client code. The code follows a logical sequence:

  1. Add file header comments
  2. Render static content with appropriate options
  3. Render types
  4. Render node metadata
  5. Render selections
  6. Render query graph

This organization makes the code generation process more maintainable and easier to understand.


356-362: Improved render_static with parameterized hostcall

The render_static function has been updated to accept a boolean parameter for hostcall inclusion, providing better flexibility. This aligns with the new options-based approach for client generation.


366-392: Streamlined metadata namespace handling

The with_metas_namespace function provides a clean way to encapsulate node metadata within a dedicated namespace. The function now returns a std::fmt::Result for better error handling, which is a good practice.


219-251:

❓ Verification inconclusive

Good implementation of query graph rendering

The render_query_graph method provides a clean implementation for generating the query graph code. It iterates through the GraphQL types and creates a mapping with appropriate type names.

One small note: watch out for potential future merge conflicts here as mentioned in a previous review comment.


🏁 Script executed:

#!/bin/bash
# Check if there are other PRs that modify the same function
gh pr list --search "is:open render_query_graph" --json number,title,url

Length of output: 183


Query Graph Rendering: Implementation Confirmed; Coordinate with Open PR

Great implementation—the render_query_graph method cleanly generates the query graph by iterating through the GraphQL types and creating the mapping. However, note that there is an open PR (#978: feat: expanded typegraph) that touches this functionality. Please ensure to coordinate merges and verify that any overlapping changes are properly handled to avoid future merge conflicts.

src/metagen/src/client_rs/selections.rs (2)

14-19: LGTM! Clear definition for UnionProp struct

The UnionProp struct is well-defined with descriptive field names that indicate its purpose in handling union type variants.


21-31: LGTM! Well-designed RustSelection enum

The RustSelection enum with its Struct and Union variants provides a clear separation of concerns for different selection types.

src/metagen/src/fdk_rs/static/Cargo.toml (1)

10-14: LGTM! Good use of workspace dependencies

The transition to workspace dependencies improves maintainability by centralizing version management.

src/metagen-client-rs/Cargo.toml (1)

21-22: LGTM! Good use of target-specific dependencies

The target-specific configuration for tokio-util ensures it's only included when needed, optimizing build time and binary size for different platforms.

src/metagen/src/fdk_rs/mod.rs (7)

17-19: Good addition of client_rs modules for expanded typegraph support.

These imports support the new manifest-based approach for generating Rust code, which aligns with the goal of expanding the typegraph functionality.


45-46: Good addition of the exclude_client option.

This new configuration option provides flexibility by allowing users to generate FDK code without the client code, which is useful for cases where only the function interface is needed.


178-181: Improved type reference caching with the Maps struct.

The new Maps struct provides a clean way to cache input and output type references, which supports the PR's goal of streamlining type references across the expanded typegraph.


200-218: Good implementation of the manifest-based approach.

This is a significant architectural improvement that:

  1. Uses a manifest-based approach for type generation (RustTypesConfig or RsClientManifest)
  2. Conditionally includes client code based on the new exclude_client option
  3. Properly populates the Maps struct with cached references

This approach better supports the goal of the expanded typegraph by allowing more efficient type inlining.


270-277: Good addition of conditional feature flags.

The implementation uses feature flags to conditionally include hostcall functionality, providing better control over the generated code and aligning with the goal of supporting injection in metagen.


304-349: Improved cargo.toml generation with conditional dependencies.

The changes to the cargo.toml generation:

  1. Add a hostcall parameter to control client inclusion
  2. Properly handle debug vs. release dependency paths
  3. Include the metagen-client crate with appropriate features

This supports the PR's goal of allowing different injection data while maintaining a clean dependency graph.


184-184:

✅ Verification successful

Verify the change from &Typegraph to Arc<Typegraph>.

The function signature now takes an Arc<Typegraph> instead of a reference, which changes the ownership semantics. This is generally a good change for shared ownership, but ensure that all callers have been updated accordingly.


🏁 Script executed:

#!/bin/bash
# Check for any callers of gen_mod_rs that might need updating
rg --type rust "gen_mod_rs\(.*&.*Typegraph" src/

Length of output: 180


Change Verified: Usage of Arc Confirmed

The updated function signature in src/metagen/src/fdk_rs/mod.rs now correctly uses Arc<Typegraph>. Our verification via grep indicates that there are no other callers relying on the previous &Typegraph parameter—only the updated signature is present.

Please ensure that any new callers pass an Arc<Typegraph> accordingly.

src/metagen/src/fdk_rs/static/fdk.rs (4)

34-38: Good addition of Default implementation for MatBuilder.

This provides a convenient way to create a new builder using standard Rust patterns, improving ergonomics and consistency with Rust conventions.


83-90: Good use of conditional compilation for hostcall support.

The conditional blocks for HOSTCALL feature properly integrate the query graph and hostcall transport into the context, which aligns with the PR's goal of supporting injection in metagen.


102-113: Well-structured stubs for QueryGraph and transport functionality.

These stubs provide a clear structure for the generated code, demonstrating how the hostcall transport will be integrated without making the template dependent on the actual implementation. The comments clarify that these are stubs that will be replaced during code generation.


115-120: Enhanced Ctx struct with query graph and transport.

The enhanced Ctx struct now includes the query graph and hostcall transport when the HOSTCALL feature is enabled, allowing materializers to access these components. This supports the PR's goal of expanding the typegraph and providing better access to injection data.

src/metagen-client-rs/src/lib.rs (3)

4-12: Good module restructuring with feature flags.

The changes to module visibility and conditional compilation:

  1. Make args public for direct access
  2. Add common for shared functionality
  3. Conditionally compile files and graphql based on features
  4. Add hostcall to support the new injection capabilities

This modular structure with feature flags aligns well with the PR's goal of creating an expanded typegraph with better injection support.


29-34: Well-structured prelude with conditional exports.

The updated prelude properly reflects the module visibility changes and conditional compilation, ensuring that users have a consistent experience regardless of which features are enabled.


39-39: Good dependency decoupling with url::Url.

Changing from reqwest::Url to url::Url reduces coupling with the HTTP client library, making the code more flexible and potentially reducing dependency bloat when the HTTP client isn't needed.

src/metagen/src/client_rs/static/client.rs (3)

4-9: Well-documented transports module.

The new module has clear documentation explaining the different transport types and their purposes, which improves code readability and helps users understand the available options.


10-39: Good separation of transport creation logic.

Extracting transport creation into dedicated functions:

  1. Improves separation of concerns
  2. Makes the code more flexible
  3. Supports both GraphQL and hostcall transports
  4. Uses conditional compilation appropriately

This approach aligns well with the PR's goal of expanded typegraph support and injection capability.


46-48:

✅ Verification successful

Verify removal of the addr field from QueryGraph.

The QueryGraph struct no longer contains the addr field, which makes it less coupled to specific transport types. This is a good architectural change, but ensure that all code that previously used this field has been updated to use the new transport functions instead.


🏁 Script executed:

#!/bin/bash
# Check for any references to QueryGraph.addr that might need updating
rg --type rust "QueryGraph.*\.addr" src/

Length of output: 42


Action Required: Confirm Removal of Deprecated addr Field and Update of Transport Usage

The QueryGraph struct in src/metagen/src/client_rs/static/client.rs (lines 46–48) has been updated to only contain the ty_to_gql_ty_map field, successfully removing the coupling to transport-specific code. No references to a removed addr field (via lookups like QueryGraph.*\.addr) were found in the codebase. However, please manually verify that:

  • No other parts of the codebase still rely on the old addr field.
  • All previous usages of addr have been fully updated to use the new transport functions or abstractions.

If necessary, you can re-run the following command to check the actual struct definition:

Thank you!


🏁 Script executed:

#!/bin/bash
sed -n '/pub struct QueryGraph {/,/}/p' src/metagen/src/client_rs/static/client.rs

Length of output: 268


Confirmed Removal of Deprecated Field

The QueryGraph struct in src/metagen/src/client_rs/static/client.rs now only contains the ty_to_gql_ty_map field, and the addr field has been completely removed. Searches for references to QueryGraph.addr have produced no results, indicating that code depending on the old field has either been removed or updated to use the new transport functions.

  • Verified struct definition confirms the removal.
  • No lingering references to QueryGraph.addr were found in the codebase.

Please review surrounding usage to ensure that all transport-related logic now correctly leverages the new abstractions.

tests/metagen/typegraphs/sample/rs/main.rs (6)

13-14: Architecture change: Url handling is separated from QueryGraph.

The client initialization has been redesigned to separate the GraphQL server address from the query graph. The addr variable is now explicitly passed to transport functions rather than being embedded in the QueryGraph instance.


18-18: Updated transport module path.

The synchronous GraphQL transport is now accessed through a more structured path (client::transports::graphql_sync) which improves organization of the transport layer.


39-44: Complete types are now used instead of partial types.

The code has been updated to use types::Post directly instead of types::PostPartial. This is part of a broader change to eliminate partial types in favor of complete type representations.


52-56: Type signatures updated throughout for consistency.

All instances of partial types (PostPartial, RootCompositeArgsFnInputPartial, etc.) have been replaced with their complete counterparts. This change ensures type consistency across the codebase and reflects the architectural changes made to the typegraph.

Also applies to: 96-104, 111-133


69-69: Async GraphQL client creation follows same pattern.

The asynchronous GraphQL client creation has been updated to match the synchronous version, using the transport module and passing the address separately from the query graph.


171-175:

❓ Verification inconclusive

Verify the impact of type changes in mutation operations.

The mutation operations have been updated to use complete types, but ensure these changes don't break existing functionality. Test this code to verify the mutations work correctly with the new type structure.

Also applies to: 178-191


🏁 Script executed:

#!/bin/bash
# Check if there are any tests for mutations that verify functionality
rg -A 5 "test.*mutation" --glob "*.rs"

Length of output: 40


Ensure manual verification of mutation operations given missing automated tests.

The recent search for mutation-related tests (using rg -A 5 "test.*mutation" --glob "*.rs") returned no results. Please manually verify that the updated mutation operations, which now use complete types, work as intended. If automated tests for mutations exist elsewhere or under a different pattern, verify them; otherwise, consider adding targeted tests to cover this functionality.

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

11-22: New data model for type aliases.

The Alias enum introduces a structured approach to representing different kinds of type aliases, including built-in types, containers, and plain aliases. This enhances the type system's flexibility and clarity.


24-29: Enhanced struct representations with the Derive struct.

The Derive struct centralizes the management of serialization and debugging attributes, while StructProp introduces a clear structure for representing struct properties. These changes promote better code organization.

Also applies to: 51-58


31-49: Improved type representation with the RustType enum.

The RustType enum provides a more structured approach to representing Rust types with variants for aliases, structs, and enums. This replaces the former procedural approach with a more object-oriented design.


401-427: Builder pattern for RustTypesConfig.

The builder pattern implementation for RustTypesConfig provides a clean API for configuring type generation. This is a good design choice for configuration objects.


446-458: Type conversion logic in input_page and output_page.

The input_page and output_page methods handle the conversion of Typegraph types to Rust types properly. The output page also intelligently reuses input types when possible to avoid duplication.

Also applies to: 460-489

src/metagen-client-rs/src/graphql.rs (5)

4-8: Updated imports for improved modularity.

The imports have been reorganized to reflect the new module structure. The common utilities are now imported from a centralized module, improving code organization.


18-18: FoundPlaceholders type is now exported.

The FoundPlaceholders type is now marked as pub(crate), making it accessible within the crate. This improves the API's clarity for internal users.


36-37: Function visibility and naming updates.

The build_gql_req_sync function is now explicitly marked as pub(crate), and build_gql_req has been renamed to build_gql_reqwest to better reflect its purpose.

Also applies to: 108-108


176-177: Conditional compilation for WASM support.

Added #[cfg(not(target_family = "wasm"))] attributes to structures that are not compatible with WebAssembly. This improves cross-platform compatibility.

Also applies to: 514-515


471-475: Generic error handling in resolve_prepared_variables.

The resolve_prepared_variables function now uses a generic type parameter T for error handling, making it more flexible and reusable across different error types.

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

17-22: New data model for Python type aliases.

The introduction of AliasTarget enum and Alias struct with builder-pattern methods creates a more structured approach to representing Python type aliases. This improves maintainability and extensibility of the type system.

Also applies to: 23-62


218-220: Type name registration after rendering.

After rendering a type, its name is registered in the history to track what has been rendered. This is a good approach to prevent duplicate type definitions, but make sure this works correctly with conditional rendering.

src/metagen-client-rs/src/files.rs (4)

12-20: Introduce usage checks for new enum variants.
Two new variants, Reader and Async, are annotated with #[allow(dead_code], implying they're currently unused. Validate that these variants remain necessary and consider removing or testing them soon, to ensure they do not become stale.


82-93: Asynchronous reader constructor looks correct.
This constructor effectively wraps the AsyncRead in a reqwest::Body. Double-check downstream handling to confirm correct usage in the calling code.


108-139: Conditional compilation block for multipart part creation.
This conditional approach accommodates various target environments but note that async readers are unsupported here. Ensure that consumers of the File type in asynchronous contexts rely on into_reqwest_part from the async path.


150-170: Asynchronous part conversion method is well-organized.
Checks for sync-only variants early and gracefully returns an error. This clarifies usage expectations for async contexts.

src/metagen-client-rs/src/common.rs (18)

4-5: Refactor large import lists if references grow.
Currently minimal, but if more crates or items are needed in the future, consider grouping or selectively importing to retain readability.


9-14: Well-defined segments for type paths.
Using an enum for TypePathSegment clarifies the path logic. Check if the enumeration covers all needed variants for future expansions.


16-17: TypePath clarity.
Wrapping a slice of TypePathSegment ensures the path is strongly typed. Good approach for predictable pattern matching later.


27-29: PathToInputFiles struct correctness.
Holds multiple TypePath references. Make sure code using this structure properly handles the slice to avoid out-of-bounds access during iteration.


35-37: ValuePath usage.
An approach that parallels TypePath. Useful for mapping user input to typed structures. Validate index handling in arrays.


39-40: TyToGqlTyMap name implies GraphQL usage.
Arc-wrapped HashMap is a good way to share references. Confirm concurrency patterns if mutated in the future.


42-49: FoundPlaceholders and GqlRequest pairing.
Storing placeholders alongside variables fosters clarity. Ensure logic consistently updates or removes placeholders after usage.


51-60: GqlRequestBuilder: good struct for incremental request building.
Clearly captures variable values, path-to-files, doc string. Keep watch on memory usage if requests become large.


62-71: GqlRequestBuilder::new
Straightforward constructor. Uses default placeholders and doc. Implementation is crisp.


73-88: register_path_to_files
Filtering logic is correct. Confirm that partial matches on prop_key are handled properly (e.g., keys not found).


90-100: select_node_to_gql (args block): initial argument parsing.
Writes arguments into doc and sets up variable mappings. No immediate red flags.


102-146: select_node_to_gql (placeholder logic).
Handles placeholders elegantly, with separate variable name generation. Good approach to avoid collisions.


182-224: build method finalizes doc and variables.
Generates a GraphQL document string with variable type checks. Consider verifying that all types in variable_types have corresponding ty_to_gql_ty_map entries to avoid runtime errors.


226-229: BuildReqError
Holds a single variant for file upload errors. Ensure new error types remain in sync if new build-time issues arise.


231-345: handle_response and GraphQLRequestError
Solid approach for HTTP and GraphQL error handling. Checking for 200..300 status codes is standard. Good job returning typed errors for various failure modes.


380-409: resolve_prepared_variables
Neatly processes placeholder closures. Check for potential collisions if the same key is inserted multiple times.


411-429: PrepareRequestError
Captures both request-building and file-upload issues. No concerns here, though keep an eye on expansions that might require additional variants.


431-446: Forwarding BuildReqError into PrepareRequestError
Direct mapping is straightforward. Safe and consistent approach.

tests/metagen/typegraphs/identities/rs/fdk.rs (7)

88-92: Default implementation for MatBuilder.
Returning Self::new() is sensible. This keeps initialization consistent with other code paths.


137-141: Creation of query_graph and Ctx.
Instantiating the query graph before building Ctx is clear. Confirm concurrency handling in host.


153-156: New Ctx struct fields.
Embedding QueryGraph and HostcallTransport in the context can simplify shared logic. Good design.


248-253: hostcall(qg: &QueryGraph)
Returns a HostcallTransport using the provided type map. This pattern is consistent with the file I/O from metagen_client.


260-263: QueryGraph struct
Holds an Arc to a type map. Straightforward. Validate that future expansions won’t need additional concurrency locks.


703-716: PrimitivesSelections
A default struct with typed scalar selects. Good for typed query building. Confirm each field is tested.


802-946: Auto-generated code for root functions
These methods (py_primitives, rs_primitives, etc.) are consistent with the design of typed queries. No immediate issues.

tests/metagen/typegraphs/sample/rs_upload/client.rs (7)

7-11: Documentation looks good.
These doc comments clearly outline the purpose of the new transport module and its usage.


40-57: New input structs and type aliases are consistent.
The definitions for RootUploadFnInput, RootUploadManyFnInput, and related type aliases appear coherent and align well with typical GraphQL patterns for file uploads. Ensure you include coverage for edge cases (e.g., empty lists, null paths) in unit tests.


71-92: RootUploadManyFn node meta is well-structured.
No issues found. It successfully maps the function arguments and input file paths. Good job including the array item path for file references.


93-110: RootUploadFn node meta is similarly well-structured.
Clear mapping of "file" -> "file_bf9b7" ensures consistent references. This is good for both serialization and runtime checks.


138-153:

❓ Verification inconclusive

Consider verifying calls to upload.
Switching from partial inputs to RootUploadFnInput can cause breaks in external code if not updated.


🏁 Script executed:

#!/bin/bash
# Search for all references to `upload(` calls
rg 'upload\s*\(' 

Length of output: 3474


Action Required: Verify External "upload" Calls for Compatibility

Based on the search results, we’ve confirmed that the new Rust client function in
tests/metagen/typegraphs/sample/rs_upload/client.rs now expects an argument of type
impl Into<NodeArgs<RootUploadFnInput>>. However, there are numerous other references to upload( in the repository (e.g., in TypeScript, Python, and other Rust tests). Please verify that all external invocations—especially in files like tests/metagen/typegraphs/sample/rs_upload/main.rs and similar test files—are updated to provide complete RootUploadFnInput instances rather than partial inputs. This check is necessary to prevent potential breakage in external code using the legacy input pattern.


113-133:

✅ Verification successful

query_graph() initialization is straightforward.
All relevant type mappings are visible. Verify that no mapping is missing or accidentally left out.


🏁 Script executed:

#!/bin/bash
# Confirm that each type or alias defined in the `types` module is added to the map
rg -A 3 'pub type ' tests/metagen/typegraphs/sample/rs_upload

Length of output: 1133


Verified: All expected input type mappings are present in query_graph().

Based on the shell script output, the following type aliases for input types:

  • FileBf9b7
  • RootUploadFnInputPathString25e51Optional
  • RootUploadManyFnInputPrefixString25e51Optional
  • RootUploadManyFnInputFilesFileBf9b7List

are all accounted for in the mapping initialization. The additional alias RootUploadFnOutput appears intentionally omitted, as it likely does not require a GraphQL type mapping.


156-175:

❓ Verification inconclusive

Consider verifying calls to upload_many.
Same rationale as above—ensure all calling sites have been updated to pass RootUploadManyFnInput.


🏁 Script executed:

#!/bin/bash
# Search for all references to `upload_many(` calls
rg 'upload_many\s*\('

Length of output: 507


Verify all upload_many call sites for correct input conversion

The search confirmed that every Rust usage of upload_many appears consistent with the update—most notably, the explicit call in tests/metagen/typegraphs/sample/rs_upload/main.rs clearly passes a RootUploadManyFnInput. However, the lambda usage in the same file:

  • api1.upload_many(args.get("files", |files: Vec<FileId>| { ... )

remains a potential risk if the conversion from the lambda isn’t yielding a proper RootUploadManyFnInput. Please double-check that this call site—and any similar patterns—indeed produces the expected type. (Note: The Python call sites are likely unrelated to this Rust-specific change.)

src/metagen-client-rs/src/hostcall.rs (15)

14-14: HostcallBinding type alias is clear.
Be mindful of potential concurrency or reentrancy if the closure internally mutates state.


16-20: HostcallTransport struct ensures clarity around hostcall usage.
This is a clean approach to grouping ty_to_gql_ty_map and the binding.


22-28: new constructor is straightforward.
No concerns here. Implementation is succinct.


66-85: query and query_with_opts methods are consistent.
They correctly leverage fetch for reading data. Possibly unify code paths if you expect more “opts” usage in the future.


87-106: Asynchronous mutation usage is forward-compatible.
This layout is good for future expansions like concurrency or advanced networking features.


108-127: Prepared queries straightforwardly delegate to prepare_query_with_opts.
Implementation is conventional for a “preparation + usage” pattern.


129-148: prepare_mutation parallels prepare_query effectively.
No structural issues found.


151-160: PreparedRequestHostcall captures necessary context.
Storing placeholders and path-to-files ensures this can handle advanced scenarios later.


162-191: new constructor for PreparedRequestHostcall
This is well-structured. The usage of map_err to unify errors is neat.


241-256: Manual clone impl
This approach is correct given that Doc might not be cloneable.


258-275: HostcallError enumerates essential categories.
It’s a well-rounded design for capturing request errors, body parsing issues, and hostcall failures.


277-283: impl From<serde_json::Error> for HostcallError
Great example of bridging JSON parsing errors to domain-specific error types.


284-290: impl From<serde_json::Error> for PrepareRequestError<HostcallError>
Avoids repeated manual error conversions.


291-310: Display + Error for HostcallError
Output ensures errors are summarized well, with partial detail on each error scenario.


311-324: GraphQL errors consolidated into HostcallError.
This is a consistent approach to unify higher-level error types with the domain logic.

tests/metagen/typegraphs/sample/rs/client.rs (2)

12-26: transports module addition is well aligned with the rest of the codebase.
Same pattern as in rs_upload/client.rs – consistent, easy to maintain.


40-57: New types usage
All struct and enum definitions appear consistent with the design from previous files. Double-check that partial vs. non-partial usage is correct across the entire test suite.

Comment on lines +309 to +313
PyType::Alias(
Alias::from(AliasTarget::Type(ty.item().key()))
.container("Optional")
.quote(), // TODO handle cyclic case where entire cycle is aliases
)
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

Multiple TODOs for cyclic reference handling.

There are several TODOs related to handling cyclic references in the Python type generation. This is a critical issue that should be addressed to prevent infinite recursion.

Implement cyclic reference detection similar to what's needed in the Rust type generator to prevent infinite recursion during type generation.

Also applies to: 315-320, 326-331, 334-339

Comment on lines +121 to +122
if prop.optional {
// writeln!(dest, r#" "{name}": typing.NotRequired[{ty_name}],"#)?;
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

Python version compatibility issue with NotRequired.

The code correctly notes that typing.NotRequired is only available in Python 3.11+, but the fallback solution doesn't provide equivalent functionality. This could lead to unexpected behavior in older Python versions.

Implement a polyfill or version-specific logic to handle optional fields correctly across Python versions.

-// FIXME: NotRequired is only avail on python 3.11
-if prop.optional {
-    // writeln!(dest, r#"    "{name}": typing.NotRequired[{ty_ref}],"#)?;
-    writeln!(dest, r#"    "{prop_key}": {ty_ref},"#)?;
+if prop.optional {
+    writeln!(dest, r#"    "{prop_key}": typing.Optional[{ty_ref}],"#)?;
📝 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
if prop.optional {
// writeln!(dest, r#" "{name}": typing.NotRequired[{ty_name}],"#)?;
if prop.optional {
- // writeln!(dest, r#" "{name}": typing.NotRequired[{ty_name}],"#)?;
- writeln!(dest, r#" "{prop_key}": {ty_ref},"#)?;
+ writeln!(dest, r#" "{prop_key}": typing.Optional[{ty_ref}],"#)?;
}

@@ -435,7 +461,7 @@ impl QueryGraph {
}
pub fn scalar_args(
&self,
args: impl Into<NodeArgs<PostPartial>>
args: impl Into<NodeArgs<Post>>
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Method signature updates to complete (non-partial) types
Swapping from partial to complete types is a beneficial step to enforce better type safety. Confirm that all call sites, especially older tests, are updated.

Also applies to: 496-496, 508-508, 529-529, 541-541, 564-564, 576-576


🏁 Script executed:

#!/bin/bash
# Search for references to old partial types in this specific test folder
rg 'PostPartial|RootCompositeArgsFnInputPartial|RootIdentityFnInputPartial'

Length of output: 1370


Action Required: Update All Call Sites to Use Complete Types

The method signature update at line 464 (using Post via impl Into<NodeArgs<Post>>) is correct. However, the verification revealed that several call sites in the tests still reference legacy partial types. For example, in tests/metagen/typegraphs/sample/rs/client.rs you still have:

  • pub type UserPostsPostListPartial = Vec<Box<PostPartial>>;
  • The definition of struct PostPartial
  • Function return types still listing PostPartial and RootIdentityFnInputPartial (e.g., lines 496, 508, 529, 541, 564, 576)

Please update these to their complete type counterparts (e.g., change PostPartial to Post and RootIdentityFnInputPartial to the complete type) to maintain consistent type safety across all modules. Also, double-check other related files (like src/metagen/fixtures/client_rs/main.rs, which references types::PostPartial) to ensure that every call site is updated accordingly.

# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	src/metagen/src/client_py/mod.rs
#	src/metagen/src/client_py/types.rs
#	src/metagen/src/client_rs/mod.rs
#	src/metagen/src/client_rs/selections.rs
#	src/metagen/src/client_ts/mod.rs
#	src/metagen/src/client_ts/static/mod.ts
#	src/metagen/src/fdk_py/mod.rs
#	src/metagen/src/fdk_py/types.rs
#	src/metagen/src/fdk_rs/mod.rs
#	src/metagen/src/fdk_rs/stubs.rs
#	src/metagen/src/fdk_rs/types.rs
#	src/metagen/src/fdk_ts/mod.rs
#	src/metagen/src/shared/client.rs
#	src/metagen/src/shared/types.rs
#	src/metagen/src/tests/fixtures.rs
#	src/metagen/src/utils.rs
#	tests/metagen/typegraphs/identities/py/fdk.py
#	tests/metagen/typegraphs/identities/rs/Cargo.toml
#	tests/metagen/typegraphs/identities/rs/fdk.rs
#	tests/metagen/typegraphs/identities/ts/fdk.ts
#	tests/metagen/typegraphs/sample/rs/client.rs
#	tests/metagen/typegraphs/sample/rs_upload/client.rs
#	tests/metagen/typegraphs/sample/ts/client.ts
#	tests/metagen/typegraphs/sample/ts_upload/client.ts
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: 13

🔭 Outside diff range comments (3)
src/metagen/src/client_ts/static/mod.ts (1)

30-39: ⚠️ Potential issue

Remove the duplicate for loop declaration

There's a redundant duplicate declaration of the for loop. The code is duplicated exactly, with the first instance at lines 30-34 and an identical second instance at lines 35-39.

Apply this diff to fix the duplication:

for (
  const [instanceName, instanceSelection] of Object.entries(
    nodeInstances,
  )
) {
- for (
-  const [instanceName, instanceSelection] of Object.entries(
-    nodeInstances,
-  )
- ) {
tests/metagen/typegraphs/identities/py/fdk.py (1)

1031-1565: ⚠️ Potential issue

Resolve the merge conflict markers to restore valid Python code.

Multiple merge conflict markers (<<<<<<< HEAD, =======, >>>>>>> main) remain in this file, causing numerous syntax errors and preventing the code from compiling. You must decide which changes to keep from each side of the conflict and remove or reconcile the rest. For example:

-<<<<<<< HEAD
 def RsSimpleCycles():
     ...
-=======
 # Alternate version
 def RsSimpleCycles():
     ...
->>>>>>> main
+def RsSimpleCycles():
+    # Merged implementation details here...

Please review the differences between your HEAD and main branches, reconcile them manually, and remove all conflict markers to produce valid Python code.

🧰 Tools
🪛 Ruff (0.8.2)

1031-1031: SyntaxError: Expected class, function definition or async function definition after decorator


1031-1031: SyntaxError: Expected a statement


1031-1031: SyntaxError: Expected a statement


1031-1031: SyntaxError: Expected a statement


1032-1032: SyntaxError: Unexpected indentation


1166-1166: SyntaxError: Expected class, function definition or async function definition after decorator


1166-1166: SyntaxError: Expected a statement


1166-1166: SyntaxError: Expected a statement


1166-1166: SyntaxError: Expected a statement


1166-1167: SyntaxError: Expected a statement


1167-1167: SyntaxError: Expected a statement


1167-1167: SyntaxError: Expected a statement


1167-1167: SyntaxError: Expected a statement


1167-1167: SyntaxError: Expected a statement


1168-1168: SyntaxError: Unexpected indentation


1187-1187: SyntaxError: Expected class, function definition or async function definition after decorator


1187-1187: SyntaxError: Expected a statement


1187-1187: SyntaxError: Expected a statement


1187-1187: SyntaxError: Expected a statement


1188-1188: SyntaxError: Unexpected indentation


1188-1189: SyntaxError: Expected an indented block after function definition


1189-1189: SyntaxError: Expected a statement


1189-1189: SyntaxError: Expected a statement


1189-1189: SyntaxError: Expected a statement


1189-1189: SyntaxError: Expected a statement


1189-1190: SyntaxError: Expected a statement


1190-1190: SyntaxError: Unexpected indentation


1190-1191: SyntaxError: Expected an indented block after function definition


1191-1191: SyntaxError: Expected a statement


1191-1191: SyntaxError: Expected a statement


1191-1191: SyntaxError: Expected a statement


1191-1191: SyntaxError: Expected a statement


1192-1192: SyntaxError: Unexpected indentation


1197-1197: SyntaxError: Expected an expression


1197-1197: SyntaxError: Expected an expression


1197-1197: SyntaxError: Expected an expression


1197-1197: SyntaxError: Expected an expression


1198-1198: SyntaxError: Expected ',', found string


1198-1198: SyntaxError: Expected ',', found ':'


1199-1199: SyntaxError: Expected ',', found '=='


1199-1199: SyntaxError: Expected ',', found '=='


1199-1199: SyntaxError: Expected ',', found '=='


1199-1199: SyntaxError: Expected ',', found '='


1200-1200: SyntaxError: Expected ',', found ':'


1201-1201: SyntaxError: Expected ',', found '>>'


1201-1201: SyntaxError: Expected ',', found '>>'


1201-1201: SyntaxError: Expected ',', found '>>'


1201-1201: SyntaxError: Expected ',', found '>'


1205-1205: SyntaxError: unindent does not match any outer indentation level


1206-1206: SyntaxError: Expected class, function definition or async function definition after decorator


1206-1206: SyntaxError: Expected an expression


1206-1206: SyntaxError: Expected an expression


1206-1206: SyntaxError: Expected an expression


1207-1207: SyntaxError: Unexpected indentation


1214-1214: SyntaxError: Expected an expression or a '}'


1214-1214: SyntaxError: Expected an expression or a '}'


1214-1214: SyntaxError: Expected an expression or a '}'


1214-1214: SyntaxError: Expected an expression or a '}'


1214-1215: SyntaxError: Expected '}', found NonLogicalNewline


1219-1219: SyntaxError: Expected an expression or a '}'


1219-1219: SyntaxError: Expected an expression or a '}'


1219-1219: SyntaxError: Expected an expression or a '}'


1219-1219: SyntaxError: Expected an expression or a '}'


1220-1220: SyntaxError: Expected ':', found '}'


1224-1224: SyntaxError: Expected class, function definition or async function definition after decorator


1224-1224: SyntaxError: Expected a statement


1224-1224: SyntaxError: Expected a statement


1224-1224: SyntaxError: Expected a statement


1225-1225: SyntaxError: Unexpected indentation


1232-1232: SyntaxError: Expected an expression or a '}'


1232-1232: SyntaxError: Expected an expression or a '}'


1232-1232: SyntaxError: Expected an expression or a '}'


1232-1232: SyntaxError: Expected an expression or a '}'


1232-1233: SyntaxError: Expected '}', found NonLogicalNewline


1238-1238: SyntaxError: Expected ',', found '>>'


1238-1238: SyntaxError: Expected ',', found '>>'


1238-1238: SyntaxError: Expected ',', found '>>'


1238-1238: SyntaxError: Expected ',', found '>'


1239-1239: SyntaxError: Expected ':', found '}'


1243-1243: SyntaxError: Expected class, function definition or async function definition after decorator


1243-1243: SyntaxError: Expected a statement


1243-1243: SyntaxError: Expected a statement


1243-1243: SyntaxError: Expected a statement


1244-1244: SyntaxError: Unexpected indentation


1284-1284: SyntaxError: Expected an expression or a '}'


1284-1284: SyntaxError: Expected an expression or a '}'


1284-1284: SyntaxError: Expected an expression or a '}'


1284-1284: SyntaxError: Expected an expression or a '}'


1284-1285: SyntaxError: Expected '}', found NonLogicalNewline


1292-1292: SyntaxError: Expected ',', found '>>'


1292-1292: SyntaxError: Expected ',', found '>>'


1292-1292: SyntaxError: Expected ',', found '>>'


1292-1292: SyntaxError: Expected ',', found '>'


1293-1293: SyntaxError: Expected ':', found '}'


1303-1303: SyntaxError: Expected an expression


1303-1303: SyntaxError: Expected an expression


1303-1303: SyntaxError: Expected an expression


1303-1303: SyntaxError: Expected an expression


1304-1304: SyntaxError: Expected ',', found string


1304-1304: SyntaxError: Expected ',', found ':'


1305-1305: SyntaxError: Expected ',', found '=='


1305-1305: SyntaxError: Expected ',', found '=='


1305-1305: SyntaxError: Expected ',', found '=='


1305-1305: SyntaxError: Expected ',', found '='


1306-1306: SyntaxError: Expected ',', found ':'


1307-1307: SyntaxError: Expected ',', found '>>'


1307-1307: SyntaxError: Expected ',', found '>>'


1307-1307: SyntaxError: Expected ',', found '>>'


1307-1307: SyntaxError: Expected ',', found '>'


1312-1312: SyntaxError: Expected class, function definition or async function definition after decorator


1312-1312: SyntaxError: Expected a statement


1312-1312: SyntaxError: Expected a statement


1312-1312: SyntaxError: Expected a statement


1313-1313: SyntaxError: Unexpected indentation


1313-1314: SyntaxError: Expected an indented block after function definition


1314-1314: SyntaxError: Expected a statement


1314-1314: SyntaxError: Expected a statement


1314-1314: SyntaxError: Expected a statement


1314-1314: SyntaxError: Expected a statement


1314-1315: SyntaxError: Expected a statement


1315-1315: SyntaxError: Unexpected indentation


1410-1411: SyntaxError: Expected an indented block after function definition


1411-1411: SyntaxError: Expected a statement


1411-1411: SyntaxError: Expected a statement


1411-1411: SyntaxError: Expected a statement


1411-1411: SyntaxError: Expected a statement


1412-1412: SyntaxError: Unexpected indentation


1417-1417: SyntaxError: Expected an expression


1417-1417: SyntaxError: Expected an expression


1417-1417: SyntaxError: Expected an expression


1417-1417: SyntaxError: Expected an expression


1418-1418: SyntaxError: Expected ',', found string


1418-1418: SyntaxError: Expected ',', found ':'


1423-1423: SyntaxError: Expected a statement


1449-1449: SyntaxError: Expected a statement


1449-1449: SyntaxError: Expected a statement


1449-1449: SyntaxError: Expected a statement


1449-1449: SyntaxError: Expected a statement


1449-1450: SyntaxError: Expected a statement


1450-1450: SyntaxError: Unexpected indentation


1450-1450: SyntaxError: Invalid annotated assignment target


1450-1450: SyntaxError: Expected a statement


1450-1451: SyntaxError: Expected a statement


1451-1451: SyntaxError: unindent does not match any outer indentation level


1451-1451: SyntaxError: Expected a statement


1451-1451: SyntaxError: Expected a statement


1451-1452: SyntaxError: Expected a statement


1452-1452: SyntaxError: Unexpected indentation


1452-1452: SyntaxError: Expected a statement


1452-1453: SyntaxError: Expected a statement


1454-1454: SyntaxError: unindent does not match any outer indentation level


1455-1455: SyntaxError: Expected class, function definition or async function definition after decorator


1564-1564: SyntaxError: Expected a statement


1564-1564: SyntaxError: Expected a statement


1564-1564: SyntaxError: Expected a statement


1564-1564: SyntaxError: Expected a statement

tests/metagen/typegraphs/sample/rs/client.rs (1)

7-47: ⚠️ Potential issue

Fix the duplicated transports module

The transports module is duplicated with identical content defined twice: once at lines 7-26 and again at lines 28-47. This appears to be an error in code generation.

Remove one of the duplicate implementations:

// Keep the first implementation
pub mod transports {
    use super::*;

    pub fn graphql(qg: &QueryGraph, addr: Url) -> metagen_client::graphql::GraphQlTransportReqwest {
        metagen_client::graphql::GraphQlTransportReqwest::new(addr, qg.ty_to_gql_ty_map.clone())
    }

    #[cfg(not(target_family = "wasm"))]
    pub fn graphql_sync(
        qg: &QueryGraph,
        addr: Url,
    ) -> metagen_client::graphql::GraphQlTransportReqwestSync {
        metagen_client::graphql::GraphQlTransportReqwestSync::new(addr, qg.ty_to_gql_ty_map.clone())
    }
}

-/// Contains constructors for the different transports supported
-/// by the typegate. Namely:
-/// - GraphQl transports ([sync](transports::graphql)/[async](transports::graphql_sync)): reqwest
-///   based transports that talk to the typegate using GraphQl over HTTP.
-/// - [Hostcall transport](transports::hostcall): used by custom functions running in the typegate to access typegraphs.
-pub mod transports {
-    use super::*;
-
-    pub fn graphql(qg: &QueryGraph, addr: Url) -> metagen_client::graphql::GraphQlTransportReqwest {
-        metagen_client::graphql::GraphQlTransportReqwest::new(addr, qg.ty_to_gql_ty_map.clone())
-    }
-
-    #[cfg(not(target_family = "wasm"))]
-    pub fn graphql_sync(
-        qg: &QueryGraph,
-        addr: Url,
-    ) -> metagen_client::graphql::GraphQlTransportReqwestSync {
-        metagen_client::graphql::GraphQlTransportReqwestSync::new(addr, qg.ty_to_gql_ty_map.clone())
-    }
-}
♻️ Duplicate comments (2)
tests/metagen/typegraphs/sample/rs/client.rs (2)

610-616: 🛠️ Refactor suggestion

Parameter type updated but return type still uses partial

Similar to the identity method, the identity_update method has been updated to use RootIdentityFnInput for parameters but still uses RootIdentityFnInputPartial for the return type.

Update the return type to use the complete type for consistency:

    ) -> UnselectedNode<
        RootIdentityFnInputSelections,
        RootIdentityFnInputSelections<HasAlias>,
        MutationMarker,
-       RootIdentityFnInputPartial,
+       RootIdentityFnInput,
    > {

514-515: 🛠️ Refactor suggestion

Inconsistent use of partial and complete types

Line 515 uses PostPartial as a return type, but line 514 uses RootCompositeArgsFnInput (a complete type) as an input type. This inconsistency may cause confusion.

For consistency with the PR objectives, update all return types to use complete types rather than partial types:

-    ) -> UnselectedNode<PostSelections, PostSelections<HasAlias>, MutationMarker, PostPartial> {
+    ) -> UnselectedNode<PostSelections, PostSelections<HasAlias>, MutationMarker, Post> {
🧹 Nitpick comments (5)
src/metagen/src/client_ts/static/mod.ts (1)

496-526: Variable naming could create confusion with shadowed parameter

In the convertQueryNodeGql function, the destructured parameter name subNodes in the mapping function shadows the outer subNodes variable. This could lead to confusion when reading or maintaining the code.

Consider renaming the destructured parameter to maintain clarity:

out = `${out} { ${
  Object.entries(subNodes)
-   .map(([variantTy, subNodes]) => {
+   .map(([variantTy, variantSubNodes]) => {
      let gqlTy = typeToGqlTypeMap[variantTy];
      if (!gqlTy) {
        throw new Error(
          `unreachable: no graphql type found for variant ${variantTy}`,
        );
      }
      gqlTy = gqlTy.replace(/[!]+$/, "");

      return `... on ${gqlTy} {${
-       subNodes
+       variantSubNodes
          .map((node) =>
            convertQueryNodeGql(typeToGqlTypeMap, node, variables, files)
          )
          .join(" ")
      }}`;
    })
    .join(" ")
} }`;
src/metagen/src/fdk_rs/mod.rs (2)

206-216: Conditional block for generating a standalone manifest when exclude_client is true.
This appears consistent with skipping client code. Consider verifying both branches are thoroughly tested.

Optionally, log or comment around this branch to clarify its behavior.


289-298: Use of HOSTCALL flag keyed by exclude_client is consistent.
This is a sensible place to centralize the condition. You may want a comment explaining the logic for future maintainers.

src/metagen/src/fdk_ts/mod.rs (1)

225-228: Printing generated file content for debugging.
This is helpful for test logs. Consider wrapping with a debug flag if less noise is preferred in CI.

tests/metagen/typegraphs/sample/rs/client.rs (1)

63-144: Implementing the expanded typegraph

The new types module implements the expanded typegraph approach described in the PR. However, it contains a mix of complete and partial types which doesn't fully align with the goal of eliminating references to the typegraph object.

Consider refactoring the types module to:

  1. Use only complete types instead of a mix of partial and complete types
  2. Ensure all type definitions are consistently structured
  3. Remove redundant partial type definitions where complete types already exist

This will make the implementation more maintainable and consistent with the PR objectives of inlining all numeric references related to types and eliminating the need to maintain a reference to the typegraph object itself.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 6a384ab and 42baffe.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (15)
  • Cargo.toml (2 hunks)
  • src/metagen/src/client_rs/mod.rs (8 hunks)
  • src/metagen/src/client_ts/static/mod.ts (3 hunks)
  • src/metagen/src/fdk_py/mod.rs (6 hunks)
  • src/metagen/src/fdk_rs/mod.rs (12 hunks)
  • src/metagen/src/fdk_ts/mod.rs (5 hunks)
  • src/metagen/src/utils.rs (3 hunks)
  • tests/metagen/metagen_test.ts (4 hunks)
  • tests/metagen/typegraphs/identities/py/fdk.py (28 hunks)
  • tests/metagen/typegraphs/identities/rs/fdk.rs (21 hunks)
  • tests/metagen/typegraphs/identities/ts/fdk.ts (1 hunks)
  • tests/metagen/typegraphs/sample/rs/client.rs (14 hunks)
  • tests/metagen/typegraphs/sample/rs_upload/client.rs (5 hunks)
  • tests/metagen/typegraphs/sample/ts/client.ts (3 hunks)
  • tests/metagen/typegraphs/sample/ts_upload/client.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • Cargo.toml
  • src/metagen/src/utils.rs
  • tests/metagen/metagen_test.ts
  • tests/metagen/typegraphs/sample/rs_upload/client.rs
🧰 Additional context used
🧠 Learnings (1)
src/metagen/src/client_ts/static/mod.ts (1)
Learnt from: Yohe-Am
PR: metatypedev/metatype#982
File: tests/metagen/typegraphs/sample/ts/client.ts:211-217
Timestamp: 2025-03-20T10:10:05.329Z
Learning: In TypeScript conditional types, using the same inferred type variable name multiple times across a union (like `QueryNode<infer O> | MutationNode<infer O>`) is a valid pattern, even though some linters may flag it as a redeclaration. TypeScript correctly understands that these refer to the same type parameter.
🧬 Code Definitions (9)
src/metagen/src/client_ts/static/mod.ts (2)
tests/metagen/typegraphs/sample/ts/client.ts (1)
  • Alias (372-380)
tests/metagen/typegraphs/sample/py/client.py (1)
  • Alias (386-393)
src/metagen/src/fdk_rs/mod.rs (4)
src/metagen/src/fdk_rs/types.rs (1)
  • new (439-444)
src/metagen/src/fdk_rs/stubs.rs (1)
  • gen_stub (14-54)
src/metagen/src/utils.rs (1)
  • processed_write (49-107)
src/metagen/src/client_rs/static/client.rs (1)
  • hostcall (32-37)
src/metagen/src/fdk_ts/mod.rs (3)
src/metagen/src/fdk_ts/types.rs (1)
  • manifest_page (248-268)
src/metagen/src/shared/mod.rs (1)
  • filter_stubbed_funcs (23-37)
src/metagen/src/fdk_ts/utils.rs (1)
  • normalize_type_title (101-113)
src/metagen/src/fdk_py/mod.rs (3)
src/metagen/src/fdk_py/types.rs (3)
  • from (31-38)
  • from (239-342)
  • new (346-357)
src/metagen/src/client_py/mod.rs (2)
  • new (49-53)
  • new (120-142)
src/metagen/src/shared/mod.rs (1)
  • filter_stubbed_funcs (23-37)
tests/metagen/typegraphs/identities/rs/fdk.rs (3)
src/metagen/src/fdk_rs/static/fdk.rs (3)
  • default (35-37)
  • new (41-45)
  • hostcall (109-111)
src/metagen/src/fdk_rs/types.rs (1)
  • new (439-444)
src/metagen/src/client_rs/static/client.rs (1)
  • hostcall (32-37)
tests/metagen/typegraphs/identities/py/fdk.py (1)
tests/metagen/typegraphs/identities/rs/fdk.rs (23)
  • RsSimpleCycles (429-438)
  • SimpleCycles1 (439-451)
  • scalar (421-428)
  • SimpleCycles2 (452-464)
  • SimpleCycles3 (465-477)
  • RsCycles (478-487)
  • Cycles1 (488-501)
  • Cycles2 (528-540)
  • Cycles3 (502-514)
  • Branch33A (541-553)
  • Branch33B (515-527)
  • RsComposites (554-563)
  • Composites (564-578)
  • CompositesEitherEither (579-591)
  • Primitives (604-626)
  • Branch2 (592-603)
  • RsPrimitives (627-636)
  • TsSimpleCycles (637-646)
  • TsCycles (647-656)
  • TsComposites (657-666)
  • TsPrimitives (667-676)
  • PySimpleCycles (677-686)
  • PyCycles (687-696)
tests/metagen/typegraphs/sample/ts/client.ts (3)
tests/metagen/typegraphs/sample/py/client.py (6)
  • NodeMeta (262-266)
  • Post (918-925)
  • RootNestedCompositeFnOutput (1070-1077)
  • RootNestedCompositeFnOutputCompositeStruct (1053-1059)
  • RootNestedCompositeFnOutputCompositeStructNestedStruct (1045-1050)
  • RootNestedCompositeFnOutputListStruct (1062-1067)
src/metagen/src/client_py/static/client.py (1)
  • NodeMeta (263-267)
tests/metagen/typegraphs/sample/rs/client.rs (5)
  • Post (271-285)
  • RootNestedCompositeFnOutput (182-202)
  • RootNestedCompositeFnOutputCompositeStruct (211-227)
  • RootNestedCompositeFnOutputCompositeStructNestedStruct (228-235)
  • RootNestedCompositeFnOutputListStruct (203-210)
tests/metagen/typegraphs/sample/rs/client.rs (2)
src/metagen/src/client_rs/static/client.rs (2)
  • graphql (15-17)
  • graphql_sync (20-25)
src/metagen/src/client_rs/mod.rs (2)
  • new (64-93)
  • new (102-106)
src/metagen/src/client_rs/mod.rs (2)
src/metagen/src/client_rs/selections.rs (1)
  • manifest_page (167-230)
src/metagen/src/shared/client.rs (1)
  • get_gql_types (7-33)
🪛 Biome (1.9.4)
src/metagen/src/client_ts/static/mod.ts

[error] 26-26: Shouldn't redeclare 'nodeInstances'. Consider to delete it or rename it.

'nodeInstances' is defined here:

(lint/suspicious/noRedeclare)

tests/metagen/typegraphs/sample/ts/client.ts

[error] 1080-1080: Shouldn't redeclare 'UserPostsPostList'. Consider to delete it or rename it.

'UserPostsPostList' is defined here:

(lint/suspicious/noRedeclare)

🪛 Ruff (0.8.2)
tests/metagen/typegraphs/identities/py/fdk.py

1031-1031: SyntaxError: Expected class, function definition or async function definition after decorator


1031-1031: SyntaxError: Expected a statement


1031-1031: SyntaxError: Expected a statement


1031-1031: SyntaxError: Expected a statement


1032-1032: SyntaxError: Unexpected indentation


1166-1166: SyntaxError: Expected class, function definition or async function definition after decorator


1166-1166: SyntaxError: Expected a statement


1166-1166: SyntaxError: Expected a statement


1166-1166: SyntaxError: Expected a statement


1166-1167: SyntaxError: Expected a statement


1167-1167: SyntaxError: Expected a statement


1167-1167: SyntaxError: Expected a statement


1167-1167: SyntaxError: Expected a statement


1167-1167: SyntaxError: Expected a statement


1187-1187: SyntaxError: Expected class, function definition or async function definition after decorator


1187-1187: SyntaxError: Expected a statement


1187-1187: SyntaxError: Expected a statement


1187-1187: SyntaxError: Expected a statement


1188-1188: SyntaxError: Unexpected indentation


1188-1189: SyntaxError: Expected an indented block after function definition


1189-1189: SyntaxError: Expected a statement


1189-1189: SyntaxError: Expected a statement


1189-1189: SyntaxError: Expected a statement


1189-1189: SyntaxError: Expected a statement


1189-1190: SyntaxError: Expected a statement


1190-1190: SyntaxError: Unexpected indentation


1190-1191: SyntaxError: Expected an indented block after function definition


1191-1191: SyntaxError: Expected a statement


1191-1191: SyntaxError: Expected a statement


1191-1191: SyntaxError: Expected a statement


1191-1191: SyntaxError: Expected a statement


1192-1192: SyntaxError: Unexpected indentation


1197-1197: SyntaxError: Expected an expression


1197-1197: SyntaxError: Expected an expression


1197-1197: SyntaxError: Expected an expression


1197-1197: SyntaxError: Expected an expression


1198-1198: SyntaxError: Expected ',', found string


1198-1198: SyntaxError: Expected ',', found ':'


1199-1199: SyntaxError: Expected ',', found '=='


1199-1199: SyntaxError: Expected ',', found '=='


1199-1199: SyntaxError: Expected ',', found '=='


1199-1199: SyntaxError: Expected ',', found '='


1200-1200: SyntaxError: Expected ',', found ':'


1201-1201: SyntaxError: Expected ',', found '>>'


1201-1201: SyntaxError: Expected ',', found '>>'


1201-1201: SyntaxError: Expected ',', found '>>'


1201-1201: SyntaxError: Expected ',', found '>'


1205-1205: SyntaxError: unindent does not match any outer indentation level


1206-1206: SyntaxError: Expected class, function definition or async function definition after decorator


1206-1206: SyntaxError: Expected an expression


1206-1206: SyntaxError: Expected an expression


1206-1206: SyntaxError: Expected an expression


1207-1207: SyntaxError: Unexpected indentation


1214-1214: SyntaxError: Expected an expression or a '}'


1214-1214: SyntaxError: Expected an expression or a '}'


1214-1214: SyntaxError: Expected an expression or a '}'


1214-1214: SyntaxError: Expected an expression or a '}'


1214-1215: SyntaxError: Expected '}', found NonLogicalNewline


1219-1219: SyntaxError: Expected an expression or a '}'


1219-1219: SyntaxError: Expected an expression or a '}'


1219-1219: SyntaxError: Expected an expression or a '}'


1219-1219: SyntaxError: Expected an expression or a '}'


1220-1220: SyntaxError: Expected ':', found '}'


1224-1224: SyntaxError: Expected class, function definition or async function definition after decorator


1224-1224: SyntaxError: Expected a statement


1224-1224: SyntaxError: Expected a statement


1224-1224: SyntaxError: Expected a statement


1225-1225: SyntaxError: Unexpected indentation


1232-1232: SyntaxError: Expected an expression or a '}'


1232-1232: SyntaxError: Expected an expression or a '}'


1232-1232: SyntaxError: Expected an expression or a '}'


1232-1232: SyntaxError: Expected an expression or a '}'


1232-1233: SyntaxError: Expected '}', found NonLogicalNewline


1238-1238: SyntaxError: Expected ',', found '>>'


1238-1238: SyntaxError: Expected ',', found '>>'


1238-1238: SyntaxError: Expected ',', found '>>'


1238-1238: SyntaxError: Expected ',', found '>'


1239-1239: SyntaxError: Expected ':', found '}'


1243-1243: SyntaxError: Expected class, function definition or async function definition after decorator


1243-1243: SyntaxError: Expected a statement


1243-1243: SyntaxError: Expected a statement


1243-1243: SyntaxError: Expected a statement


1244-1244: SyntaxError: Unexpected indentation


1284-1284: SyntaxError: Expected an expression or a '}'


1284-1284: SyntaxError: Expected an expression or a '}'


1284-1284: SyntaxError: Expected an expression or a '}'


1284-1284: SyntaxError: Expected an expression or a '}'


1284-1285: SyntaxError: Expected '}', found NonLogicalNewline


1292-1292: SyntaxError: Expected ',', found '>>'


1292-1292: SyntaxError: Expected ',', found '>>'


1292-1292: SyntaxError: Expected ',', found '>>'


1292-1292: SyntaxError: Expected ',', found '>'


1303-1303: SyntaxError: Expected an expression


1303-1303: SyntaxError: Expected an expression


1303-1303: SyntaxError: Expected an expression


1303-1303: SyntaxError: Expected an expression


1304-1304: SyntaxError: Expected ',', found string


1304-1304: SyntaxError: Expected ',', found ':'


1305-1305: SyntaxError: Expected ',', found '=='


1305-1305: SyntaxError: Expected ',', found '=='


1305-1305: SyntaxError: Expected ',', found '=='


1305-1305: SyntaxError: Expected ',', found '='


1306-1306: SyntaxError: Expected ',', found ':'


1307-1307: SyntaxError: Expected ',', found '>>'


1307-1307: SyntaxError: Expected ',', found '>>'


1307-1307: SyntaxError: Expected ',', found '>>'


1307-1307: SyntaxError: Expected ',', found '>'


1312-1312: SyntaxError: Expected class, function definition or async function definition after decorator


1312-1312: SyntaxError: Expected a statement


1312-1312: SyntaxError: Expected a statement


1312-1312: SyntaxError: Expected a statement


1313-1313: SyntaxError: Unexpected indentation


1313-1314: SyntaxError: Expected an indented block after function definition


1314-1314: SyntaxError: Expected a statement


1314-1314: SyntaxError: Expected a statement


1314-1314: SyntaxError: Expected a statement


1314-1314: SyntaxError: Expected a statement


1411-1411: SyntaxError: Expected a statement


1411-1411: SyntaxError: Expected a statement


1411-1411: SyntaxError: Expected a statement


1411-1411: SyntaxError: Expected a statement


1412-1412: SyntaxError: Unexpected indentation


1417-1417: SyntaxError: Expected an expression


1417-1417: SyntaxError: Expected an expression


1417-1417: SyntaxError: Expected an expression


1417-1417: SyntaxError: Expected an expression


1418-1418: SyntaxError: Expected ',', found string


1418-1418: SyntaxError: Expected ',', found ':'


1423-1423: SyntaxError: Expected a statement


1449-1449: SyntaxError: Expected a statement


1449-1449: SyntaxError: Expected a statement


1449-1449: SyntaxError: Expected a statement


1449-1449: SyntaxError: Expected a statement


1564-1564: SyntaxError: Expected a statement


1564-1564: SyntaxError: Expected a statement


1564-1564: SyntaxError: Expected a statement


1564-1564: SyntaxError: Expected a statement


1574-1574: SyntaxError: Expected a statement


1574-1574: SyntaxError: Expected a statement


1574-1574: SyntaxError: Expected a statement


1574-1574: SyntaxError: Expected a statement


1575-1575: SyntaxError: Expected a statement


1575-1575: SyntaxError: Expected a statement


1575-1575: SyntaxError: Expected a statement


1575-1575: SyntaxError: Expected a statement


1575-1576: SyntaxError: Expected a statement


1577-1577: SyntaxError: Expected a statement


1577-1577: SyntaxError: Expected a statement


1577-1577: SyntaxError: Expected a statement


1577-1577: SyntaxError: Expected a statement


1598-1598: SyntaxError: Expected a statement


1598-1598: SyntaxError: Expected a statement


1598-1598: SyntaxError: Expected a statement


1598-1598: SyntaxError: Expected a statement


1603-1603: SyntaxError: Expected an expression or a '}'


1603-1603: SyntaxError: Expected an expression or a '}'


1603-1603: SyntaxError: Expected an expression or a '}'


1603-1603: SyntaxError: Expected an expression or a '}'


1619-1619: SyntaxError: Expected ',', found '>>'


1619-1619: SyntaxError: Expected ',', found '>>'


1619-1619: SyntaxError: Expected ',', found '>>'


1619-1619: SyntaxError: Expected ',', found '>'


1620-1620: SyntaxError: Expected ':', found '}'


1624-1624: SyntaxError: Expected an expression


1624-1624: SyntaxError: Expected an expression


1624-1624: SyntaxError: Expected an expression


1625-1625: SyntaxError: Expected ':', found name


1625-1625: SyntaxError: Expected ',', found '='


1632-1632: SyntaxError: Expected ',', found '=='


1632-1632: SyntaxError: Expected ',', found '=='


1632-1632: SyntaxError: Expected ',', found '=='


1632-1632: SyntaxError: Expected ',', found '='


1633-1633: SyntaxError: Expected ':', found '='


1637-1637: SyntaxError: Expected an expression or a '}'


1637-1637: SyntaxError: Expected an expression or a '}'


1637-1637: SyntaxError: Expected an expression or a '}'


1637-1637: SyntaxError: Expected an expression or a '}'


1638-1638: SyntaxError: Expected ':', found '}'


1642-1642: SyntaxError: Expected an expression


1642-1642: SyntaxError: Expected an expression


1642-1642: SyntaxError: Expected an expression


1643-1643: SyntaxError: Expected ':', found name


1643-1643: SyntaxError: Expected ',', found '='


1645-1645: SyntaxError: Expected ':', found name


1645-1645: SyntaxError: Expected ',', found '='


1649-1649: SyntaxError: Expected an expression


1649-1649: SyntaxError: Expected an expression


1649-1649: SyntaxError: Expected an expression


1650-1650: SyntaxError: Expected ':', found '='


1651-1651: SyntaxError: Expected an expression


1651-1651: SyntaxError: Expected an expression


1651-1651: SyntaxError: Expected an expression


1661-1661: SyntaxError: Expected an expression


1661-1661: SyntaxError: Expected an expression


1661-1661: SyntaxError: Expected an expression


1662-1662: SyntaxError: Expected ':', found name


1662-1662: SyntaxError: Expected ',', found '='


1669-1669: SyntaxError: Expected ':', found name


1669-1669: SyntaxError: Expected ',', found '='


1670-1670: SyntaxError: Expected an expression


1670-1670: SyntaxError: Expected an expression


1670-1670: SyntaxError: Expected an expression


1671-1671: SyntaxError: Expected ':', found '='


1676-1676: SyntaxError: Expected an expression


1676-1676: SyntaxError: Expected an expression


1676-1676: SyntaxError: Expected an expression


1678-1678: SyntaxError: Expected ':', found name


1678-1678: SyntaxError: Expected ',', found '='


1683-1683: SyntaxError: Expected an expression


1683-1683: SyntaxError: Expected an expression


1683-1683: SyntaxError: Expected an expression


1684-1684: SyntaxError: Expected ':', found name


1684-1684: SyntaxError: Expected ',', found '='


1686-1686: SyntaxError: Expected ':', found name


1686-1686: SyntaxError: Expected ',', found '='


1688-1688: SyntaxError: Expected ':', found name


1688-1688: SyntaxError: Expected ',', found '='


1692-1692: SyntaxError: Expected an expression or a '}'


1692-1692: SyntaxError: Expected an expression or a '}'


1692-1692: SyntaxError: Expected an expression or a '}'


1692-1692: SyntaxError: Expected an expression or a '}'


1715-1715: SyntaxError: Expected ',', found '>>'


1715-1715: SyntaxError: Expected ',', found '>>'


1715-1715: SyntaxError: Expected ',', found '>>'


1715-1715: SyntaxError: Expected ',', found '>'


1716-1716: SyntaxError: Expected ':', found '}'


1720-1720: SyntaxError: Expected an expression


1720-1720: SyntaxError: Expected an expression


1720-1720: SyntaxError: Expected an expression


1721-1721: SyntaxError: Expected ':', found name


1721-1721: SyntaxError: Expected ',', found '='


1727-1727: SyntaxError: Expected ',', found '=='


1727-1727: SyntaxError: Expected ',', found '=='


1727-1727: SyntaxError: Expected ',', found '=='


1727-1727: SyntaxError: Expected ',', found '='


1728-1728: SyntaxError: Expected ':', found '='


1732-1732: SyntaxError: Expected an expression or a '}'


1732-1732: SyntaxError: Expected an expression or a '}'


1732-1732: SyntaxError: Expected an expression or a '}'


1732-1732: SyntaxError: Expected an expression or a '}'


1733-1733: SyntaxError: Expected ':', found '}'


1737-1737: SyntaxError: Expected an expression


1737-1737: SyntaxError: Expected an expression


1737-1737: SyntaxError: Expected an expression


1738-1738: SyntaxError: Expected ':', found name


1738-1738: SyntaxError: Expected ',', found '='


1740-1740: SyntaxError: Expected ':', found name


1740-1740: SyntaxError: Expected ',', found '='


1745-1745: SyntaxError: Expected ':', found name


1745-1745: SyntaxError: Expected ',', found '='


1749-1749: SyntaxError: Expected an expression


1749-1749: SyntaxError: Expected an expression


1749-1749: SyntaxError: Expected an expression


1750-1750: SyntaxError: Expected ':', found '='


1751-1751: SyntaxError: Expected an expression


1751-1751: SyntaxError: Expected an expression


1751-1751: SyntaxError: Expected an expression


1753-1753: SyntaxError: Expected ':', found name


1753-1753: SyntaxError: Expected ',', found '='


1756-1756: SyntaxError: Expected an expression


1756-1756: SyntaxError: Expected an expression


1756-1756: SyntaxError: Expected an expression


1756-1756: SyntaxError: Expected an expression


1757-1757: SyntaxError: Expected ',', found string


1757-1757: SyntaxError: Expected ',', found ':'


1758-1758: SyntaxError: Expected ',', found ':'


1759-1759: SyntaxError: Expected ',', found '=='


1759-1759: SyntaxError: Expected ',', found '=='


1759-1759: SyntaxError: Expected ',', found '=='


1759-1759: SyntaxError: Expected ',', found '='


1760-1760: SyntaxError: Expected ',', found ':'


1761-1761: SyntaxError: Expected ',', found ':'


1762-1762: SyntaxError: Expected ',', found '>>'


1762-1762: SyntaxError: Expected ',', found '>>'


1762-1762: SyntaxError: Expected ',', found '>>'


1762-1762: SyntaxError: Expected ',', found '>'


1767-1767: SyntaxError: Expected an expression


1767-1767: SyntaxError: Expected an expression


1767-1767: SyntaxError: Expected an expression


1768-1768: SyntaxError: Expected ':', found name


1768-1768: SyntaxError: Expected ',', found '='


1770-1770: SyntaxError: Expected ':', found name


1770-1770: SyntaxError: Expected ',', found '='


1774-1774: SyntaxError: Expected an expression or a '}'


1774-1774: SyntaxError: Expected an expression or a '}'


1774-1774: SyntaxError: Expected an expression or a '}'


1774-1774: SyntaxError: Expected an expression or a '}'


1775-1775: SyntaxError: Expected ':', found '='


1779-1779: SyntaxError: Expected an expression or a '}'


1779-1779: SyntaxError: Expected an expression or a '}'


1779-1779: SyntaxError: Expected an expression or a '}'


1779-1779: SyntaxError: Expected an expression or a '}'


1780-1780: SyntaxError: Expected ':', found string


1780-1780: SyntaxError: Expected ',', found ':'


1780-1780: SyntaxError: Expected ':', found ','


1785-1785: SyntaxError: Expected an expression


1785-1785: SyntaxError: Expected an expression


1785-1785: SyntaxError: Expected an expression


1786-1786: SyntaxError: Expected ':', found name


1786-1786: SyntaxError: Expected ',', found '='


1788-1788: SyntaxError: Expected ':', found name


1788-1788: SyntaxError: Expected ',', found '='


1790-1790: SyntaxError: Expected ':', found name


1790-1790: SyntaxError: Expected ',', found '='


1794-1794: SyntaxError: Expected an expression or a '}'


1794-1794: SyntaxError: Expected an expression or a '}'


1794-1794: SyntaxError: Expected an expression or a '}'


1794-1794: SyntaxError: Expected an expression or a '}'


1821-1821: SyntaxError: Expected ',', found '>>'


1821-1821: SyntaxError: Expected ',', found '>>'


1821-1821: SyntaxError: Expected ',', found '>>'


1821-1821: SyntaxError: Expected ',', found '>'


1822-1822: SyntaxError: Expected ':', found '}'


1826-1826: SyntaxError: Expected an expression


1826-1826: SyntaxError: Expected an expression


1826-1826: SyntaxError: Expected an expression


1827-1827: SyntaxError: Expected ':', found name


1827-1827: SyntaxError: Expected ',', found '='


1831-1831: SyntaxError: Expected an expression or a '}'


1831-1831: SyntaxError: Expected an expression or a '}'


1831-1831: SyntaxError: Expected an expression or a '}'


1831-1831: SyntaxError: Expected an expression or a '}'


1868-1868: SyntaxError: Expected an expression or a '}'


1868-1868: SyntaxError: Expected an expression or a '}'


1868-1868: SyntaxError: Expected an expression or a '}'


1868-1868: SyntaxError: Expected an expression or a '}'


1869-1869: SyntaxError: Expected ':', found string


1869-1869: SyntaxError: Expected ',', found ':'


1869-1869: SyntaxError: Expected ':', found ','


1874-1874: SyntaxError: Expected an expression


1874-1874: SyntaxError: Expected an expression


1874-1874: SyntaxError: Expected an expression


1875-1875: SyntaxError: Expected ':', found name


1875-1875: SyntaxError: Expected ',', found '='


1877-1877: SyntaxError: Expected ':', found name


1877-1877: SyntaxError: Expected ',', found '='


1882-1882: SyntaxError: Expected ',', found '=='


1882-1882: SyntaxError: Expected ',', found '=='


1882-1882: SyntaxError: Expected ',', found '=='


1882-1882: SyntaxError: Expected ',', found '='


1883-1883: SyntaxError: Expected ':', found '='


1887-1887: SyntaxError: Expected an expression or a '}'


1887-1887: SyntaxError: Expected an expression or a '}'


1887-1887: SyntaxError: Expected an expression or a '}'


1887-1887: SyntaxError: Expected an expression or a '}'


1888-1888: SyntaxError: Expected ':', found '}'


1892-1892: SyntaxError: Expected an expression


1892-1892: SyntaxError: Expected an expression


1892-1892: SyntaxError: Expected an expression


1893-1893: SyntaxError: Expected ':', found name


1893-1893: SyntaxError: Expected ',', found '='


1895-1895: SyntaxError: Expected ':', found name


1895-1895: SyntaxError: Expected ',', found '='


1904-1904: SyntaxError: Expected ':', found name


1904-1904: SyntaxError: Expected ',', found '='


1905-1905: SyntaxError: Expected an expression


1905-1905: SyntaxError: Expected an expression


1905-1905: SyntaxError: Expected an expression


1906-1906: SyntaxError: Expected ',', found '>>'


1906-1906: SyntaxError: Expected ',', found '>>'


1906-1906: SyntaxError: Expected ',', found '>>'


1906-1906: SyntaxError: Expected ',', found '>'


1947-1947: SyntaxError: Expected an expression


1947-1947: SyntaxError: Expected an expression


1947-1947: SyntaxError: Expected an expression


1948-1948: SyntaxError: Expected an expression


1948-1948: SyntaxError: Expected an expression


1948-1948: SyntaxError: Expected an expression


1957-1957: SyntaxError: Expected an expression


1957-1957: SyntaxError: Expected an expression


1957-1957: SyntaxError: Expected an expression


1970-1970: SyntaxError: Expected an expression


1970-1970: SyntaxError: Expected an expression


1970-1970: SyntaxError: Expected an expression


1971-1971: SyntaxError: Expected ':', found name


1971-1971: SyntaxError: Expected ',', found '='


1981-1981: SyntaxError: Expected ':', found name


1981-1981: SyntaxError: Expected ',', found '='


1992-1992: SyntaxError: Expected an expression


1992-1992: SyntaxError: Expected an expression


1992-1992: SyntaxError: Expected an expression


1993-1993: SyntaxError: Expected ',', found '>>'


1993-1993: SyntaxError: Expected ',', found '>>'


1993-1993: SyntaxError: Expected ',', found '>>'


1993-1993: SyntaxError: Expected ',', found '>'


2014-2014: SyntaxError: Expected an expression


2014-2014: SyntaxError: Expected an expression


2014-2014: SyntaxError: Expected an expression


2015-2015: SyntaxError: Expected an expression


2015-2015: SyntaxError: Expected an expression


2015-2015: SyntaxError: Expected an expression


2026-2026: SyntaxError: Expected an expression


2026-2026: SyntaxError: Expected an expression


2026-2026: SyntaxError: Expected an expression


2037-2037: SyntaxError: Expected an expression


2037-2037: SyntaxError: Expected an expression


2037-2037: SyntaxError: Expected an expression


2038-2038: SyntaxError: Expected ':', found name


2038-2038: SyntaxError: Expected ',', found '='


2044-2044: SyntaxError: Expected ',', found '=='


2044-2044: SyntaxError: Expected ',', found '=='


2044-2044: SyntaxError: Expected ',', found '=='


2044-2044: SyntaxError: Expected ',', found '='


2045-2045: SyntaxError: Expected ':', found '='


2052-2052: SyntaxError: Expected ',', found '>>'


2052-2052: SyntaxError: Expected ',', found '>>'


2052-2052: SyntaxError: Expected ',', found '>>'


2052-2052: SyntaxError: Expected ',', found '>'


2077-2077: SyntaxError: Expected an expression


2077-2077: SyntaxError: Expected an expression


2077-2077: SyntaxError: Expected an expression


2078-2078: SyntaxError: Expected an expression


2078-2078: SyntaxError: Expected an expression


2078-2078: SyntaxError: Expected an expression


2089-2089: SyntaxError: Expected an expression


2089-2089: SyntaxError: Expected an expression


2089-2089: SyntaxError: Expected an expression


2091-2091: SyntaxError: Expected ':', found 'class'


2091-2091: SyntaxError: Expected ',', found name


2092-2092: SyntaxError: Expected an identifier, but found a keyword 'def' that cannot be used here


2092-2092: SyntaxError: Expected ',', found name


2095-2095: SyntaxError: Expected an expression


2095-2095: SyntaxError: Expected an expression


2095-2095: SyntaxError: Expected an expression


2095-2095: SyntaxError: Expected an expression


2096-2096: SyntaxError: Expected ',', found string


2096-2096: SyntaxError: Expected ',', found ':'


2097-2097: SyntaxError: Expected ',', found ':'


2098-2098: SyntaxError: Expected ',', found ':'


2099-2099: SyntaxError: Expected ',', found ':'


2100-2100: SyntaxError: Expected ',', found '=='


2100-2100: SyntaxError: Expected ',', found '=='


2100-2100: SyntaxError: Expected ',', found '=='


2100-2100: SyntaxError: Expected ',', found '='


2101-2101: SyntaxError: Expected ',', found ':'


2102-2102: SyntaxError: Expected ',', found ':'


2103-2103: SyntaxError: Expected ',', found ':'


2104-2104: SyntaxError: Expected ',', found ':'


2105-2105: SyntaxError: Expected ',', found ':'


2106-2106: SyntaxError: Expected ',', found '>>'


2106-2106: SyntaxError: Expected ',', found '>>'


2106-2106: SyntaxError: Expected ',', found '>>'


2106-2106: SyntaxError: Expected ',', found '>'


2107-2107: SyntaxError: Expected ',', found string


2107-2107: SyntaxError: Expected ',', found ':'


2108-2108: SyntaxError: Expected ',', found ':'


2109-2109: SyntaxError: Expected ',', found ':'


2110-2110: SyntaxError: Expected ',', found ':'


2111-2111: SyntaxError: Expected ',', found '<<'


2111-2111: SyntaxError: Expected ',', found '<<'


2111-2111: SyntaxError: Expected ',', found '<<'


2111-2111: SyntaxError: Expected ',', found '<'


2112-2112: SyntaxError: Expected an expression


2112-2112: SyntaxError: Expected an expression


2112-2112: SyntaxError: Expected an expression


2113-2113: SyntaxError: Expected ',', found ':'


2114-2114: SyntaxError: Expected ',', found '>>'


2114-2114: SyntaxError: Expected ',', found '>>'


2114-2114: SyntaxError: Expected ',', found '>>'


2114-2114: SyntaxError: Expected ',', found '>'


2172-2172: SyntaxError: Expected a statement


2172-2172: SyntaxError: Expected a statement


2172-2172: SyntaxError: Expected a statement


2172-2172: SyntaxError: Expected a statement


2173-2173: SyntaxError: Expected a statement


2173-2173: SyntaxError: Expected a statement


2173-2173: SyntaxError: Expected a statement


2173-2173: SyntaxError: Expected a statement


2188-2188: SyntaxError: Expected a statement


2188-2188: SyntaxError: Expected a statement


2188-2188: SyntaxError: Expected a statement


2188-2188: SyntaxError: Expected a statement


2243-2243: SyntaxError: Expected a statement


2243-2243: SyntaxError: Expected a statement


2243-2243: SyntaxError: Expected a statement


2243-2243: SyntaxError: Expected a statement


2244-2244: SyntaxError: Expected a statement


2244-2244: SyntaxError: Expected a statement


2244-2244: SyntaxError: Expected a statement


2244-2244: SyntaxError: Expected a statement


2259-2259: SyntaxError: Expected a statement


2259-2259: SyntaxError: Expected a statement


2259-2259: SyntaxError: Expected a statement


2259-2259: SyntaxError: Expected a statement


2314-2314: SyntaxError: Expected a statement


2314-2314: SyntaxError: Expected a statement


2314-2314: SyntaxError: Expected a statement


2314-2314: SyntaxError: Expected a statement


2315-2315: SyntaxError: Expected a statement


2315-2315: SyntaxError: Expected a statement


2315-2315: SyntaxError: Expected a statement


2315-2315: SyntaxError: Expected a statement


2330-2330: SyntaxError: Expected a statement


2330-2330: SyntaxError: Expected a statement


2330-2330: SyntaxError: Expected a statement


2330-2330: SyntaxError: Expected a statement


2372-2372: SyntaxError: Expected a statement


2372-2372: SyntaxError: Expected a statement


2372-2372: SyntaxError: Expected a statement


2372-2372: SyntaxError: Expected a statement


2373-2373: SyntaxError: Expected a statement


2373-2373: SyntaxError: Expected a statement


2373-2373: SyntaxError: Expected a statement


2373-2373: SyntaxError: Expected a statement


2386-2386: SyntaxError: Expected a statement


2386-2386: SyntaxError: Expected a statement


2386-2386: SyntaxError: Expected a statement


2386-2386: SyntaxError: Expected a statement

⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: bulid-docker (linux/arm64, custom-arm)
  • GitHub Check: bulid-docker (linux/amd64, custom-ubuntu-large)
  • GitHub Check: lint-compat (macos-14, aarch64-apple-darwin, false)
  • GitHub Check: lint-compat (macos-13, x86_64-apple-darwin, false)
  • GitHub Check: test-full
  • GitHub Check: pre-commit
🔇 Additional comments (68)
src/metagen/src/client_ts/static/mod.ts (1)

216-217: The inference variable pattern is valid TypeScript

Regarding the type definition using the union with the same inferred type variable O - this is a valid TypeScript pattern. Although some linters might flag it as a redeclaration issue, TypeScript correctly understands that these refer to the same type parameter in the union context.

🧰 Tools
🪛 Biome (1.9.4)

[error] 216-216: Shouldn't redeclare 'O'. Consider to delete it or rename it.

'O' is defined here:

(lint/suspicious/noRedeclare)

tests/metagen/typegraphs/identities/py/fdk.py (1)

1197-1201: Verify the correct type references for “data” fields.

Some definitions use lowercase strings like "data": "primitives" while others use uppercase like "data": "Primitives" or "data": "Composites". Ensure consistency with the corresponding TypedDict keys to prevent runtime issues or mismatched type annotations.

Would you like a script that searches the entire codebase for these references to confirm they match the definitions in your typed dicts?

Also applies to: 1298-1307

🧰 Tools
🪛 Ruff (0.8.2)

1197-1197: SyntaxError: Expected an expression


1197-1197: SyntaxError: Expected an expression


1197-1197: SyntaxError: Expected an expression


1197-1197: SyntaxError: Expected an expression


1198-1198: SyntaxError: Expected ',', found string


1198-1198: SyntaxError: Expected ',', found ':'


1199-1199: SyntaxError: Expected ',', found '=='


1199-1199: SyntaxError: Expected ',', found '=='


1199-1199: SyntaxError: Expected ',', found '=='


1199-1199: SyntaxError: Expected ',', found '='


1200-1200: SyntaxError: Expected ',', found ':'


1201-1201: SyntaxError: Expected ',', found '>>'


1201-1201: SyntaxError: Expected ',', found '>>'


1201-1201: SyntaxError: Expected ',', found '>>'


1201-1201: SyntaxError: Expected ',', found '>'

tests/metagen/typegraphs/sample/ts/client.ts (27)

903-910: No concerns with the merged argument types.
The function correctly composes RootIdentityFnInput and sets the argumentTypes to accept an integer-based argument.


911-917: Subnodes look good.
The sub-node for "input" is clearly defined as a scalar.


918-925: Mirroring logic from RootIdentityUpdateFn.
Both functions share a similar pattern, and the approach to expand RootIdentityFnInput plus arguments appears consistent.


926-930: Chained composition of node metas is correct.
The function forwards the NodeMeta from RootNestedCompositeFnOutput.


931-939: Defining subNodes “scalar”, “composite”, “list” is clear.
The code is consistent with typical NodeMeta usage for nested composite structures.


940-946: Single sub-node pattern is straightforward.
The structure for RootNestedCompositeFnOutputListStruct neatly points to "value".


947-954: Composite struct with “value” and “nested.”
This accurately models deeper nesting under “nested.”


955-961: Innermost nested scalar looks correct.
No concerns regarding the final level of nesting.


962-969: Union function merges the correct output.
Argument type “string_e1a43” is aligned with the type map.


970-977: Variants “post” and “user.”
No concerns with the union definition.


978-986: User node meta references the expected sub-nodes.
The sub-nodes match the user structure: id, email, posts.


987-995: Post node meta has the correct sub-nodes.
id, slug, title all referencing scalars.


996-1003: Union function with “RootCompositeUnionFnOutput.”
Argument “id: string_e1a43” aligns with the global map.


1004-1011: Composite union’s variants are properly mapped.
The “post” and “user” variants are consistent with the rest of the code.


1012-1019: Extending scalar node with an argument.
RootScalarUnionFn merges nodeMetas.scalar() and sets an argument “id.”


1020-1027: Composite function reusing “Post.”
No issues with referencing Post as the underlying NodeMeta.


1028-1032: No-args composite returning “Post.”
Pattern is consistent in simpler multi‑function definitions.


1033-1042: Scalar with multiple arguments.
The “id,” “slug,” and “title” argument mapping is correct.


1043-1047: No-args scalar node.
The code merges nodeMetas.scalar() as expected.


1048-1052: GetPosts function referencing “Post.”
Implementation remains consistent with the overall approach.


1053-1057: GetUser function referencing “User.”
Keeps the code symmetrical with other query definitions.


1059-1064: String-based UUID usage is straightforward.
Defining StringUuid4 as string and using it for id in Post is valid.


1075-1076: Defining id and email in User as typed fields.
No concerns: StringUuid4 and StringEmail5 are suitably typed.


1092-1095: Adding explicit fields for RootNestedCompositeFnOutput.
This structure, including scalar, composite, and list, aligns with the subNodes definitions.


1102-1104: Nested struct type clarifies the inner field.
All definitions appear well-formed.


1109-1111: UserSelections type updated with optional fields.
The fields id? and email? match the scalar usage pattern.


1148-1150: Type-to-GraphQL type mapping is aligned.
user_id_string_uuidID!, string_e1a43String!, and integer_64be4Int! are consistent with standard GraphQL schema usage.

src/metagen/src/fdk_rs/mod.rs (12)

17-19: No issues with the new imports.
They appear necessary for the new manifest-based approach and seem properly placed.


47-48: Check for potential field duplication.
It looks like exclude_client is declared here, but please verify that there isn't another declaration elsewhere in the code that might cause conflicts or confusion.


146-146: No immediate concerns with calling gen_mod_rs.
Ensure that passing tg.clone() is indeed necessary and doesn’t add unnecessary overhead.


152-152: Retrieving the typegraph name looks straightforward.
No concerns with storing it in tg_name.


159-162: Usage of !exclude_client.unwrap_or_default() is logical.
Passing the inverse of exclude_client to indicate the need for a hostcall is consistent with the intended behavior.


184-187: New Maps struct is a clear way to bundle references.
Encapsulating input/output references promotes clarity and reusability.


190-190: Switching to Arc<Typegraph> is appropriate for shared ownership.
This aligns with the approach used elsewhere to reduce excessive copying.


232-244: Filtering and generating stubs for specific runtimes is well-structured.
filter_stubbed_funcs ensures correctness, and gen_stub usage is straightforward. Double-check that map(|val| val.as_str()) does not silently skip any needed functions if the key is missing.


263-267: gen_static now accepting config seems prudent.
This provides flexibility if you need to branch logic based on config.


305-306: Reapplying the same flags to the next processed_write call.
Keeps code generation unified under one conditional approach.


330-351: Conditional logic for metagen-client in gen_cargo_toml.
Differentiating debug vs. release paths is a neat technique. Confirm that the local path is valid in all dev environments.


398-399: String block formatting appears correct.
No immediate concerns regarding the final format.

src/metagen/src/fdk_ts/mod.rs (6)

10-12: New imports for TypeNodeExt and manifest_page.
They appear to enable extended typegraph functionalities and manifest-based rendering.


77-77: Switching to Arc<Typegraph> in render_fdk_ts.
This follows the same pattern for shared ownership seen in other modules.


92-95: Leveraging manifest_page and render_all centralizes type rendering.
This is a more maintainable approach than manual type assembly.


102-102: Excellent use of wrap_err_with for contextual errors.
No concerns—this makes debugging easier.


106-108: Using normalize_type_title for input/output/function type names.
Ensures consistent naming conventions for generated stubs.


174-174: Refactoring fdk.ts generation via render_fdk_ts.
Clear approach to produce the output in a single pass.

tests/metagen/typegraphs/sample/ts_upload/client.ts (4)

903-910: RootUploadManyFn updated to handle multiple files.
Replacing file with a files array clarifies multi-upload usage. Verify correct processing logic for inputFiles: [[".files","[]"]].


913-920: RootUploadFn updated for single-file handling.
Transitioning from multi-file to single upload is consistent with the method name. Ensure path is properly utilized downstream.


928-935: Exported type definitions for optional strings and file arrays.
This enhances clarity around file arguments and optional paths/prefixes.


941-944: Updated GraphQL type mappings for new file references.
Ensures alignment between TypeScript definitions and the underlying GraphQL schema.

src/metagen/src/fdk_py/mod.rs (3)

94-121: Improved type handling in render_fdk_py

The function now accepts an Arc<Typegraph> instead of a reference, which allows for better sharing of the Typegraph across different components. The code now properly separates the rendering logic based on whether a client should be excluded, using either PyTypesPage or ClientPyManifest accordingly.


128-139: Enhanced error handling for stubbed functions

The change uses wrap_err_with to provide more context-rich error messages when collecting materializers fails, which improves debugging capabilities.


232-232: Update to pass Arc to render_fdk_py

The code now correctly passes the Typegraph as an Arc instead of a reference, matching the updated function signature.

tests/metagen/typegraphs/identities/rs/fdk.rs (2)

285-716: Clean implementation of detailed type system

The introduction of a rich type system with proper Rust types for primitives, composites, and cycles is well-structured. The code defines clear relationships between types, including optional fields, enums for variants, and proper serialization/deserialization annotations.

This implementation will greatly enhance type safety and ensure proper data handling across language boundaries.


804-817: Well-structured QueryGraph implementation

The query_graph() function provides a clean way to initialize the mapping between Rust types and GraphQL types, facilitating proper type conversions during queries.

src/metagen/src/client_rs/mod.rs (6)

48-61: Good modular architecture with Maps struct

The introduction of the Maps struct provides a clean way to organize different types of mappings (input types, output types, node metas, selections) needed for code generation. This enhances code organization and makes the relationships between different components more explicit.


63-93: Well-structured RsClientManifest implementation

The RsClientManifest struct and its implementation provide a clean way to initialize and manage the client generation process. The new method properly sets up all required components and constructs the maps needed for type and metadata lookups.


143-152: Simplified client generation implementation

The changes to the generate method simplify the code by leveraging the new RsClientManifest structure. This makes the code more readable and maintainable.


253-352: Comprehensive implementation of root function generation

The render_root_functions method provides a thorough approach to generating code for root functions, handling different types of arguments, selections, and effects. The code correctly maps between types and generates appropriate client methods.


219-251: Clean QueryGraph rendering implementation

The render_query_graph method provides a well-structured way to generate code for the QueryGraph, properly mapping type names to their GraphQL representations.


370-370: Careful with function implementation as noted in previous review

As mentioned in a previous review, be cautious with the implementation of this function during merges.

tests/metagen/typegraphs/identities/ts/fdk.ts (4)

42-48: Improved type definitions with specific string subtypes

The updated type definitions for uuid, email, ean, json, uri, date, and datetime use more specific type aliases (StringUuid6, StringEmail7, etc.) rather than just string. This enhances type safety and makes the code more self-documenting.


69-77: Well-structured composite type definitions

The CompositesArgs and Composites types provide a clean way to handle composite data structures with optional fields and references to other composite types, enhancing type safety and data validation.


97-104: Good implementation of cycle types

The Cycles1Args and Cycles1 types properly handle cyclic references between types, an important feature for complex data structures. The types use optional fields and references to other cycle types, providing a flexible and type-safe approach.


123-140: Clean implementation of simplified cycle types

The SimpleCycles1Args and related types provide a cleaner, more simplified approach to cyclic references, making them easier to understand and use while maintaining type safety.

tests/metagen/typegraphs/sample/rs/client.rs (2)

88-94: Update partial types to complete types

The PostPartial struct is still being used, but based on previous review comments and the PR objectives, partial types should be updated to complete types.

Please update these partial types to their complete type counterparts (e.g., change PostPartial to Post) to maintain consistent type safety across all modules.

#!/bin/bash
# Search for remaining partial types throughout the codebase
rg 'Partial' --type rust

476-478:

❓ Verification inconclusive

Method signature update needs matching data structures

Line 478 references NodeArgs<Post> but a Post struct is used as input arguments to a function that seems to expect field values like id, slug, and title.

Verify that this implementation correctly matches the intended design where complete types (rather than partial types) are used for method arguments.


🏁 Script executed:

#!/bin/bash
# Check how Post is used as arguments elsewhere
rg 'NodeArgs<Post>' --type rust

Length of output: 167


Attention: Verify Data Structure Consistency in Method Signature

The scalar_args method currently accepts an argument of type impl Into<NodeArgs<Post>>, which implies that a complete Post type (including fields such as id, slug, and title) is being provided. However, the context suggests that the method might be expecting field-level arguments instead of the full structure. There’s no alternative usage of NodeArgs<Post> elsewhere to indicate a different intent, so please confirm that using the complete Post type here aligns with the intended design. If a partial type (or a different approach to passing only the required fields) was expected, the signature should be updated accordingly.

  • File: tests/metagen/typegraphs/sample/rs/client.rs
  • Lines: 476–478

Comment on lines 4 to 7
use core::fmt::Write;
use std::borrow::Cow;
use core::fmt::Write;
use std::borrow::Cow;
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

Remove duplicate import statements

There are duplicated imports between lines 4-7 and 6-7. This is likely a merge conflict that wasn't properly resolved.

-use core::fmt::Write;
-use std::borrow::Cow;
 use core::fmt::Write;
 use std::borrow::Cow;
📝 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
use core::fmt::Write;
use std::borrow::Cow;
use core::fmt::Write;
use std::borrow::Cow;
use core::fmt::Write;
use std::borrow::Cow;

Comment on lines 594 to 600
args: impl Into<NodeArgs<RootIdentityFnInput>>,
) -> UnselectedNode<
RootIdentityFnInputSelections,
RootIdentityFnInputSelections<HasAlias>,
QueryMarker,
RootIdentityFnInputPartial,
> {
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Parameter type updated but return type still uses partial

The identity method has been updated to use RootIdentityFnInput instead of RootIdentityFnInputPartial for its parameters, but the return type still references RootIdentityFnInputPartial.

Update the return type to use the complete type for consistency:

    ) -> UnselectedNode<
        RootIdentityFnInputSelections,
        RootIdentityFnInputSelections<HasAlias>,
        QueryMarker,
-       RootIdentityFnInputPartial,
+       RootIdentityFnInput,
    > {
📝 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
args: impl Into<NodeArgs<RootIdentityFnInput>>,
) -> UnselectedNode<
RootIdentityFnInputSelections,
RootIdentityFnInputSelections<HasAlias>,
QueryMarker,
RootIdentityFnInputPartial,
> {
args: impl Into<NodeArgs<RootIdentityFnInput>>,
) -> UnselectedNode<
RootIdentityFnInputSelections,
RootIdentityFnInputSelections<HasAlias>,
QueryMarker,
RootIdentityFnInput,
> {

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

♻️ Duplicate comments (3)
src/metagen/src/fdk_rs/types.rs (3)

186-201: ⚠️ Potential issue

Missing cyclic reference handling in container_def method.

The container_def method handles the construction of container types but does not implement the cyclic reference detection logic that was present in the previous implementation. This could lead to infinite recursion in type definitions with self-referential structures.

As noted in previous comments, the cyclic detection logic was difficult to replicate. Consider implementing a mechanism to detect and handle cyclic references, possibly based on the previous is_path_unfortunately_cyclic logic mentioned in the PR comments.


276-293: ⚠️ Potential issue

Missing cyclic reference handling for optional types.

The TODO comments on lines 283 and 290 indicate that cyclic reference handling is still needed for optional types.

Implement the cyclic reference detection logic to prevent infinite recursion in type definitions. This is particularly important for optional types that might contain self-references.


295-327: ⚠️ Potential issue

Missing cyclic reference handling for list types.

Similar to the optional types, the list types implementation also needs cyclic reference handling as indicated by the TODO comment on line 323.

Implement the cyclic reference detection logic for list types to prevent infinite recursion in type definitions with circular dependencies.

🧹 Nitpick comments (38)
src/metagen/src/fdk_rs/types.rs (1)

977-990: Clean up commented out code in tests.

There's commented out code referencing the old RustTypeRenderer configuration. Since the implementation has been completely refactored, this code should be removed or updated to match the new structure.

-            // TODO
-            // let config = Arc::new(RustTypeRenderer {
-            //     derive_serde: true,
-            //     derive_debug: true,
-            //     all_fields_optional: false,
-            // });
tests/metagen/typegraphs/sample/ts_upload/client.ts (3)

932-933: Improved type definitions.

The explicit type definitions for FileBf9b7 and RootUploadFnInputPathString25e51Optional enhance type safety. However, the parentheses around (string) in the optional type definition are unnecessary and can be removed.

-export type RootUploadFnInputPathString25e51Optional = (string) | null | undefined;
+export type RootUploadFnInputPathString25e51Optional = string | null | undefined;

938-939: Improved type definitions with consistent naming.

The type definitions for the upload many function parameters follow the same pattern as the single upload function, providing consistency across the codebase.

-export type RootUploadManyFnInputPrefixString25e51Optional = (string) | null | undefined;
+export type RootUploadManyFnInputPrefixString25e51Optional = string | null | undefined;

951-951: Remove excessive whitespace.

There's an unnecessary whitespace line that should be removed.

-            
src/metagen/src/fdk_ts/mod.rs (2)

96-102: Improved implementation with cleaner conditional logic

The refactored code now conditionally uses either TsTypesPage or TsClientManifest based on the exclude_client flag, which is more modular and leverages existing components instead of custom rendering logic.

One minor note about line 100:

-            let manif = TsClientManifest::new(tg.clone())?;
+            let manif = TsClientManifest::new(tg)?;

Since tg is already an Arc, the .clone() call is redundant as Arc is designed for cheap cloning and would be cloned implicitly when needed.


237-240: Consider using debug logs instead of println

These debug print statements are useful during development but might not be appropriate for production code.

-                        println!(
-                            "file content:fdk.ts:\n{}\n--end--",
-                            std::fs::read_to_string(args.path.join("fdk.ts"))?
-                        );
+                        log::debug!(
+                            "file content:fdk.ts:\n{}\n--end--",
+                            std::fs::read_to_string(args.path.join("fdk.ts"))?
+                        );

Using the logging framework rather than direct println would allow for better control of log verbosity in different environments.

src/metagen/src/fdk_ts/types.rs (4)

92-93: Consider more robust optional property detection

The current implementation determines if a property is optional by checking if its type is Optional, which is correct in most cases. However, in TypeScript, a property could be marked as optional even if its type isn't explicitly wrapped in an Optional type (e.g., when a property has a default value).

Consider enhancing the optional detection to also check if the property has a default value or other conditions that would make it optional in the TypeScript context:

-let optional = matches!(prop.ty, Type::Optional(_));
+let optional = matches!(prop.ty, Type::Optional(_)) || prop.required.is_some_and(|required| !required);

164-171: Consider simplifying union type rendering

The current implementation wraps each union variant in parentheses. While this is safer for complex types, it might lead to unnecessarily verbose output for simple types.

Consider conditionally adding parentheses only when needed:

-write!(out, "\n  | ({variant_name})")?;
+write!(out, "\n  | {variant_name}")?;

If there's a specific reason for always using parentheses, consider adding a comment explaining why.


228-228: Add explanation for unreachable function type

The code marks function types as unreachable, but it would be helpful to add a comment explaining why function types are not expected in this context.

-Type::Function(_) => unreachable!("unexpected function type"),
+Type::Function(_) => unreachable!("Function types should not be processed by the TypeScript type renderer - they are handled separately"),

251-253: Consider documenting the empty object type skip

The code skips empty object types during processing, which is likely an optimization. Consider adding a comment explaining why empty object types are skipped to help future maintainers understand the reasoning.

if ty.properties().is_empty() {
+    // Skip empty object types as they don't need TypeScript type definitions
    continue;
}
src/metagen/src/fdk_rs/mod.rs (3)

140-147: Consider refactoring shared logic.

A “TODO” at line 121 mentions removing code duplication in FDK generators. This insertion of gen_mod_rs content might further contribute to duplication. Factor common steps into a helper function or shared module when feasible.


178-182: Add doc comments or clarify naming.

The Maps struct is a helpful container for default and partial references. Consider adding a brief doc comment or a more descriptive name (e.g., TypeRefMaps) to enhance maintainability.


185-224: Consolidate map-building logic and remove debug prints.

The if-else block produces Maps differently based on exclude_client. Consider extracting this logic into a dedicated helper to avoid complexity. Also, replace or remove the eprintln!("maps: {maps:#?}"); debug statement to maintain consistent logging practices.

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

80-242: Revisit or remove commented-out tests.

Commenting out a large block of tests can reduce coverage. If these tests are now obsolete, remove them. Otherwise, consider updating and reenabling them.

src/metagen/src/fdk_py/mod.rs (3)

10-12: Confirm necessity of wildcard imports

These newly introduced imports appear broad. Verify that each is needed and consider limiting the scope or removing any unused imports if possible.


66-66: Remove duplicate validation call

config.validate()? is called twice, potentially increasing runtime overhead. Unless there's a specific reason, consider removing the second call.

     config.validate()?;
-    config.validate()?;

96-98: ClientPyManifest fallback

When exclude_client is false, the code initializes a ClientPyManifest and renders client stubs. Double-check that the subsequent references to manif.maps.types are valid if no client is needed.

tests/metagen/typegraphs/sample/rs_upload/client.rs (4)

71-71: Ensure consistent naming

RootUploadManyFn is introduced here, labeled as a function returning NodeMeta. Confirm naming consistency with related “uploadMany” logic in the codebase.


97-97: File argument type resolution

("file".into(), "file_bf9b7".into()) is consistent with FileBf9b7 = super::FileId. Double-check the actual FileId type is correct for the intended File usage.


106-106: Nested file property

TypePathSegment::ObjectProp("file") is used for input file references. Ensure the same property is consistently named in the actual serialization or deserialization layers.


123-123: Optional prefix mapped to GraphQL String

Double-check that any required prefix validations are enforced if used. A String type in GraphQL typically remains optional unless explicitly flagged as non-null.

src/metagen/src/client_ts/mod.rs (4)

9-13: Added specialized imports

These imports (TsType, TsNodeMeta, TsSelection, ManifestPage, MetasPageBuilder) likely support the new manifest-based workflow. Ensure no redundancy if narrower imports might suffice.


133-135: Render invocation sequence

Creating a TsClientManifest and immediately calling render is straightforward. Consider logging or additional error context if rendering fails.


195-206: Node metas injection

render_node_metas wraps the raw string in a JavaScript object. Confirm that any complex nested metas are handled properly. If needed, consider partial code generation for clarity.


356-359: Diagnostic printing for debugging

The code logs the generated client.ts lines if the check fails. This is helpful for development, but consider conditionally suppressing these logs for production CI pipelines.

src/metagen/src/client_rs/mod.rs (4)

48-53: Consider verifying potential key collisions in Maps.
Storing multiple IndexMap<TypeKey, String> structures is convenient. However, confirm that the same TypeKey does not inadvertently appear in multiple maps leading to confusion (especially the partial vs. full type scenarios). It may be beneficial to validate or cross-check them if expected usage spans multiple data structures in tandem.


63-98: Constructor RsClientManifest::new is comprehensive but consider error-handling clarity.
The function builds submanifests, node metas, and selections, then stores references in Maps. While it’s correct, it’s quite lengthy. Splitting out smaller helper methods may improve readability, especially for the partial vs. full type logic.


223-255: render_query_graph elegantly materializes the GQL map.
This function provides a clear approach to creating a QueryGraph for GQL usage. Consider using helper validation for unexpected or missing types from the typegraph (e.g. logging or errors) if mismatches arise.


360-369: render_static merges static client code effectively.
Injecting the hostcall logic is well done. Validate if repeated references to the same static snippet might lead to duplication or version mismatch in different contexts.

tests/metagen/typegraphs/sample/ts/client.ts (3)

915-921: RootIdentityFnInput defines a single sub-node “input.”
This minimal structure is clear. Adding additional validation or argument checks might be helpful if “input” evolves to more complex needs.


935-943: RootNestedCompositeFnOutput includes scalar, composite, and list sub-nodes.
It properly sets up a more complex NodeMeta structure. Consider unit tests covering nested selections with optional fields.


974-981: RootMixedUnionFnOutput: post/user variants for the union.
Aligns with the previously defined approach to union types. Confirm the correct usage of scalar or numeric unions if expansions occur.

tests/metagen/typegraphs/sample/rs/client.rs (4)

41-41: Re-export usage of types::*.
Brings in all newly defined types. This is handy, but watch out for name collisions if the code expands to include more modules.


528-529: composite_no_args returns partial Post.
Check that no-arg usage is consistent with the typegraph’s required fields.


572-573: composite_union similarly reuses RootCompositeArgsFnInput.
Again, consistent yet unusual naming. If the input structure differs from typical “composite” usage, a rename might help.


584-585: mixed_union also builds on RootCompositeArgsFnInput.
Same pattern as composite_union. If it’s truly universal, consider a more generic name for the input type.

tests/metagen/typegraphs/identities/py/fdk.py (1)

1128-1152: Create Branch33B and update Branch33A for cycles.

These methods follow the same NodeMeta approach with sub_nodes referencing scalar or further cyclical calls. No immediate issues. Consider adding docstrings or comments explaining these branches, especially if they hold complex cyclical relationships.

tests/metagen/typegraphs/identities/rs/fdk.rs (1)

854-856: Cycles3Selections definition
Introduces top-level selections for "branch33A" and "branch33B". The underscored naming is a bit unusual but not incorrect.

Consider renaming branch33_abranch33A or consistently using snake_case for all fields.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 42baffe and bb5e3fe.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (19)
  • src/meta-cli/src/typegraph/rpc/mod.rs (1 hunks)
  • src/metagen/src/client_rs/mod.rs (8 hunks)
  • src/metagen/src/client_ts/mod.rs (6 hunks)
  • src/metagen/src/client_ts/static/mod.ts (1 hunks)
  • src/metagen/src/fdk_py/mod.rs (4 hunks)
  • src/metagen/src/fdk_rs/mod.rs (6 hunks)
  • src/metagen/src/fdk_rs/stubs.rs (2 hunks)
  • src/metagen/src/fdk_rs/types.rs (22 hunks)
  • src/metagen/src/fdk_ts/mod.rs (6 hunks)
  • src/metagen/src/fdk_ts/types.rs (1 hunks)
  • src/metagen/src/utils.rs (2 hunks)
  • tests/metagen/metagen_test.ts (4 hunks)
  • tests/metagen/typegraphs/identities/py/fdk.py (10 hunks)
  • tests/metagen/typegraphs/identities/rs/fdk.rs (21 hunks)
  • tests/metagen/typegraphs/identities/ts/fdk.ts (6 hunks)
  • tests/metagen/typegraphs/sample/rs/client.rs (15 hunks)
  • tests/metagen/typegraphs/sample/rs_upload/client.rs (2 hunks)
  • tests/metagen/typegraphs/sample/ts/client.ts (4 hunks)
  • tests/metagen/typegraphs/sample/ts_upload/client.ts (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/metagen/src/client_ts/static/mod.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/metagen/src/utils.rs
  • tests/metagen/metagen_test.ts
🧰 Additional context used
🧬 Code Definitions (15)
src/metagen/src/fdk_py/mod.rs (3)
src/metagen/src/client_py/mod.rs (2)
  • new (49-53)
  • new (120-142)
src/metagen/src/fdk_py/types.rs (1)
  • new (346-357)
src/metagen/src/shared/mod.rs (1)
  • filter_stubbed_funcs (23-37)
src/metagen/src/fdk_ts/mod.rs (4)
src/metagen/src/client_ts/mod.rs (2)
  • new (59-83)
  • new (92-96)
src/metagen/src/fdk_ts/types.rs (1)
  • new (246-263)
src/metagen/src/shared/mod.rs (1)
  • filter_stubbed_funcs (23-37)
src/metagen/src/fdk_ts/utils.rs (1)
  • normalize_type_title (101-113)
src/metagen/src/fdk_rs/mod.rs (4)
src/metagen-client-rs/src/selection.rs (6)
  • default (254-256)
  • default (326-328)
  • default (410-412)
  • default (415-417)
  • default (420-422)
  • default (425-427)
src/metagen/src/fdk_rs/types.rs (1)
  • new (440-457)
src/metagen-client-rs/src/common.rs (1)
  • new (62-71)
src/metagen/src/shared/mod.rs (1)
  • filter_stubbed_funcs (23-37)
src/metagen/src/client_ts/mod.rs (3)
src/metagen/src/shared/node_metas.rs (1)
  • new (22-30)
src/metagen/src/client_ts/selections.rs (4)
  • manifest_page (119-175)
  • render (25-51)
  • render (67-98)
  • render (104-109)
src/metagen/src/shared/manifest.rs (1)
  • render (14-18)
src/metagen/src/fdk_rs/types.rs (4)
src/metagen/src/shared/types.rs (1)
  • type_body_required (23-38)
src/typegraph/graph/src/types/list.rs (2)
  • item (17-19)
  • tag (27-29)
src/typegraph/graph/src/types/object.rs (2)
  • properties (29-33)
  • tag (49-51)
src/typegraph/graph/src/types/union.rs (2)
  • variants (17-21)
  • tag (29-35)
src/metagen/src/fdk_ts/types.rs (4)
src/metagen/src/shared/types.rs (1)
  • type_body_required (23-38)
src/typegraph/graph/src/types/union.rs (2)
  • variants (17-21)
  • tag (29-35)
src/typegraph/graph/src/types/object.rs (2)
  • properties (29-33)
  • tag (49-51)
src/metagen/src/shared/manifest.rs (2)
  • get_reference_expr (22-22)
  • from (40-46)
tests/metagen/typegraphs/sample/rs_upload/client.rs (1)
tests/metagen/typegraphs/sample/ts_upload/client.ts (10)
  • RootUploadFnInput (928-931)
  • FileBf9b7 (932-932)
  • RootUploadFnInputPathString25e51Optional (933-933)
  • RootUploadManyFnInput (934-937)
  • RootUploadManyFnInputPrefixString25e51Optional (938-938)
  • RootUploadManyFnInputFilesFileBf9b7List (939-939)
  • RootUploadFnOutput (940-940)
  • RootUploadManyFn (907-916)
  • scalar (903-905)
  • RootUploadFn (917-926)
tests/metagen/typegraphs/sample/ts_upload/client.ts (3)
tests/metagen/typegraphs/sample/py/client.py (3)
  • NodeMeta (262-266)
  • File (213-219)
  • QueryGraph (1319-1463)
src/metagen/src/client_py/static/client.py (2)
  • NodeMeta (263-267)
  • File (214-220)
tests/metagen/typegraphs/sample/ts/client.ts (1)
  • QueryGraph (1146-1253)
tests/metagen/typegraphs/identities/ts/fdk.ts (1)
tests/metagen/typegraphs/identities/rs/fdk.rs (12)
  • Primitives (508-530)
  • Composites (666-680)
  • CompositesEitherEither (681-693)
  • Branch2 (694-705)
  • Cycles1 (590-603)
  • Cycles2 (630-642)
  • Cycles3 (604-616)
  • Branch33A (643-655)
  • Branch33B (617-629)
  • SimpleCycles1 (541-553)
  • SimpleCycles2 (554-566)
  • SimpleCycles3 (567-579)
src/metagen/src/fdk_rs/stubs.rs (3)
src/metagen/src/fdk_rs/utils.rs (1)
  • normalize_type_title (26-43)
src/metagen/src/fdk_ts/utils.rs (1)
  • normalize_type_title (101-113)
src/typegraph/schema/src/types.rs (1)
  • fmt (118-131)
tests/metagen/typegraphs/sample/rs/client.rs (1)
tests/metagen/typegraphs/sample/ts/client.ts (26)
  • Post (991-999)
  • Post (1064-1068)
  • RootIdentityFnInput (915-921)
  • RootIdentityFnInput (1072-1074)
  • User (982-990)
  • User (1075-1079)
  • RootCompositeUnionFnOutput (1008-1015)
  • RootCompositeUnionFnOutput (1085-1087)
  • RootMixedUnionFnOutput (974-981)
  • RootMixedUnionFnOutput (1088-1092)
  • RootNestedCompositeFnOutput (935-943)
  • RootNestedCompositeFnOutput (1093-1097)
  • RootNestedCompositeFnOutputCompositeStruct (951-958)
  • RootNestedCompositeFnOutputCompositeStruct (1098-1101)
  • RootNestedCompositeFnOutputCompositeStructNestedStruct (959-965)
  • RootNestedCompositeFnOutputCompositeStructNestedStruct (1102-1104)
  • RootNestedCompositeFnOutputListStruct (944-950)
  • RootNestedCompositeFnOutputListStruct (1106-1108)
  • scalar (903-905)
  • RootIdentityFn (922-929)
  • RootNestedCompositeFn (930-934)
  • RootMixedUnionFn (966-973)
  • RootCompositeUnionFn (1000-1007)
  • value (243-279)
  • inner (195-197)
  • inner (206-208)
src/metagen/src/client_rs/mod.rs (3)
src/metagen/src/client_rs/selections.rs (2)
  • manifest_page (167-230)
  • render (36-47)
src/metagen/src/client_rs/node_metas.rs (4)
  • render (46-61)
  • render (75-109)
  • render (113-147)
  • render (151-202)
src/metagen/src/shared/manifest.rs (1)
  • render (14-18)
tests/metagen/typegraphs/identities/py/fdk.py (1)
tests/metagen/typegraphs/identities/rs/fdk.rs (26)
  • RsProxyPrimitives (498-507)
  • Primitives (508-530)
  • RsSimpleCycles (531-540)
  • SimpleCycles1 (541-553)
  • scalar (490-497)
  • SimpleCycles2 (554-566)
  • RsCycles (580-589)
  • Cycles1 (590-603)
  • Cycles2 (630-642)
  • Cycles3 (604-616)
  • Branch33B (617-629)
  • Branch33A (643-655)
  • RsComposites (656-665)
  • Composites (666-680)
  • CompositesEitherEither (681-693)
  • Branch2 (694-705)
  • RsPrimitives (706-715)
  • TsProxyPrimitives (716-725)
  • TsSimpleCycles (726-735)
  • TsComposites (746-755)
  • TsPrimitives (756-765)
  • PyProxyPrimitives (766-775)
  • PySimpleCycles (776-785)
  • PyCycles (786-795)
  • PyComposites (796-805)
  • PyPrimitives (806-815)
tests/metagen/typegraphs/sample/ts/client.ts (1)
tests/metagen/typegraphs/sample/py/client.py (6)
  • NodeMeta (262-266)
  • Post (918-925)
  • RootNestedCompositeFnOutput (1070-1077)
  • RootNestedCompositeFnOutputCompositeStruct (1053-1059)
  • RootNestedCompositeFnOutputCompositeStructNestedStruct (1045-1050)
  • RootNestedCompositeFnOutputListStruct (1062-1067)
tests/metagen/typegraphs/identities/rs/fdk.rs (4)
tests/metagen/typegraphs/identities/ts/fdk.ts (36)
  • PrimitivesArgs (1214-1216)
  • Primitives (993-1010)
  • Primitives (1217-1230)
  • PrimitivesStrString (1231-1231)
  • PrimitivesEnumStringEnum (1232-1236)
  • PrimitivesIntInteger (1244-1244)
  • PrimitivesFloatFloat (1245-1245)
  • PrimitivesBooleanBoolean (1246-1246)
  • Composites (1100-1109)
  • Composites (1250-1255)
  • CompositesEitherEither (1110-1117)
  • CompositesEitherEither (1257-1259)
  • Branch2 (1118-1124)
  • Branch2 (1260-1262)
  • Cycles1 (1051-1059)
  • Cycles1 (1278-1282)
  • Cycles2 (1076-1083)
  • Cycles2 (1284-1286)
  • Cycles3 (1060-1067)
  • Cycles3 (1287-1289)
  • Branch33A (1084-1091)
  • Branch33A (1290-1293)
  • Branch33B (1068-1075)
  • Branch33B (1295-1298)
  • SimpleCycles1 (1019-1026)
  • SimpleCycles1 (1304-1307)
  • SimpleCycles2 (1027-1034)
  • SimpleCycles2 (1309-1312)
  • SimpleCycles3 (1035-1042)
  • SimpleCycles3 (1314-1317)
  • RsProxyPrimitives (985-992)
  • RsSimpleCycles (1011-1018)
  • scalar (981-983)
  • RsCycles (1043-1050)
  • RsComposites (1092-1099)
  • RsPrimitives (1125-1132)
tests/metagen/typegraphs/identities/py/fdk.py (19)
  • Primitives (1042-1058)
  • Composites (1167-1175)
  • CompositesEitherEither (1178-1184)
  • Branch2 (1187-1192)
  • Cycles1 (1110-1117)
  • Cycles2 (1138-1144)
  • Cycles3 (1120-1126)
  • Branch33A (1147-1153)
  • Branch33B (1129-1135)
  • SimpleCycles1 (1072-1078)
  • SimpleCycles2 (1081-1087)
  • SimpleCycles3 (1090-1096)
  • RsProxyPrimitives (1031-1039)
  • NodeMeta (275-279)
  • RsSimpleCycles (1061-1069)
  • scalar (1027-1028)
  • RsCycles (1099-1107)
  • RsComposites (1156-1164)
  • RsPrimitives (1195-1203)
tests/metagen/typegraphs/sample/rs/client.rs (1)
  • scalar (171-178)
src/metagen-client-rs/src/selection.rs (1)
  • args (342-344)
🔇 Additional comments (130)
src/metagen/src/fdk_rs/types.rs (5)

12-60: Clean implementation of the new type system.

The newly introduced enums and structs (Alias, Derive, RustType, StructProp) provide a more flexible and maintainable approach to representing Rust types compared to the previous implementation. The separation of concerns between different type variants is well-designed.


61-183: Well-structured type rendering logic.

The implementation of ManifestEntry for RustType is clean and covers all the different type variants. The code is readable and follows a consistent pattern for each variant, making it maintainable.


329-362: Well-implemented object type handling.

The object type handling logic correctly maps properties, handles renames, and detects when properties should be boxed due to being a descendant. This is a robust implementation.


430-457: Clean implementation of the configuration and manifest building.

The build_manifest method and initialization of the RustTypesSubmanifest are well-structured. The conditional handling of partial output types with proper messages is a good practice.


508-528: Well-structured rendering methods.

The render_all and render_full methods provide a clean interface for generating the complete type definitions with proper indentation and module structure.

tests/metagen/typegraphs/sample/ts_upload/client.ts (5)

504-509: Good formatting improvement.

Breaking arguments onto separate lines improves readability, especially for functions with multiple parameters.


907-915: Function definition now matches its name.

The RootUploadManyFn has been correctly refactored to handle multiple files (files) with an optional prefix, which properly aligns with its "Many" naming. The input file path structure now correctly reflects an array of files with [".files","[]"].


917-925: Function definition now matches its name.

The RootUploadFn has been correctly refactored to handle a single file (file) with an optional path parameter, which properly aligns with its singular naming. The input file path structure now correctly reflects a single file with [".file"].


945-948: Updated type mappings in QueryGraph constructor.

The type mappings in the QueryGraph constructor have been properly updated to match the new parameter structures and types, ensuring consistency between the TypeScript client and the GraphQL schema.


952-967: Verify that corresponding server-side changes are in place.

The client methods upload and uploadMany correctly use the new parameter structure, but we need to ensure that the server-side implementations have been updated to match these changes.

Since this is a breaking change to the API interface (swapping single and multiple upload functionality), verify that all consumers of these functions are updated accordingly.

src/metagen/src/fdk_ts/mod.rs (4)

10-13: Updated imports align with the refactoring of type rendering

The imports now utilize TsClientManifest and TsTypesPage from the client_ts module instead of custom type rendering logic. The import of TypeNodeExt trait also enables direct access to type information.


80-80: Function signature changed to use Arc

The function now takes an Arc<Typegraph> instead of a reference (&Typegraph), which supports shared ownership of the typegraph across component boundaries. This change is consistent with the updated rendering approach that uses TsClientManifest which requires an Arc<Typegraph>.


110-116: Improved type name access with TypeNodeExt trait

The code now uses the TypeNodeExt trait's methods like input().name() and output().name() to directly access type names, which is cleaner than the previous approach of extracting types manually. This change leverages trait extensions appropriately.


126-133: Enhanced error handling with anyhow and improved template processing

The return type change from core::fmt::Result to anyhow::Result<()> allows for more detailed error reporting. Additionally, the implementation now uses processed_write which provides more sophisticated template handling with the ability to replace placeholders based on the provided key-value pairs.

src/metagen/src/fdk_ts/types.rs (9)

6-11: Clean import organization with the new type alias

The new TsTypesPage type alias simplifies the codebase by providing a descriptive type for ManifestPage<TsType>, making the code more maintainable and easier to understand. Good use of type aliasing.


13-39: Well-structured type representation with enums

The enums Alias and TsType provide a clear, type-safe way to represent TypeScript types, which is a significant improvement over the previous approach. The design elegantly handles different scenarios like built-in types, optional types, containers, objects, and various enum types.


41-104: Clean builder methods for TypeScript types

The implementation of various builder methods for different TypeScript types is well-structured. Each method handles its specific type conversion logic clearly, with good attention to edge cases like string enumerations and optional types.

A few observations:

  • Good handling of explicit aliases based on type properties
  • Appropriate normalization of type names
  • Proper extraction of properties from object types

106-113: Clean union type handling

The build_union method correctly maps union types to TypeScript's enum representation, collecting all variant keys for later rendering.


116-121: Well-defined ObjectProp struct

The ObjectProp struct is a clean representation of an object property with all the necessary information (name, type, optional flag) for TypeScript code generation.


126-182: Comprehensive type rendering implementation

The render method implementation is thorough and handles all possible TypeScript type variants correctly. The formatting with proper indentation and newlines ensures readable TypeScript output.

Particularly good handling of:

  • Conditional rendering based on alias names
  • Optional properties with question marks
  • Union types with proper formatting
  • String literal enums

184-210: Clean reference expression generation

The get_reference_expr method correctly handles references to different types of TypeScript definitions, ensuring proper type references throughout the generated code.


213-243: Comprehensive type conversion implementation

The From<&Type> implementation for TsType handles all possible type conversions cleanly, with appropriate handling of basic types (boolean, integer, float, string) and composite types (optional, list, object, union).

Good use of the type_body_required function to determine when to create a named type versus an inlined type.


245-263: Efficient TsTypesPage creation

The new method efficiently creates a TsTypesPage from a Typegraph by processing both input and output types. The optimization to skip empty object types is a good performance consideration.

src/meta-cli/src/typegraph/rpc/mod.rs (2)

25-25:

❓ Verification inconclusive

Ensure references to Aws(aws::RpcCall) remain valid.

Restoring or relocating this variant can similarly affect untagged deserialization. Confirm that upstream/downstream code using RpcCall::Aws still behaves as intended.


🏁 Script executed:

#!/bin/bash
# Searching for all references to RpcCall::Aws in the repo.
rg "RpcCall::Aws"

Length of output: 17


Action Required: Confirm Unaltered Deserialization for Aws(aws::RpcCall)

The automated search did not reveal explicit references to RpcCall::Aws, which may be due to its implicit use in untagged deserialization. Please verify that:

  • The untagged deserialization handling for this variant (likely driven by Serde) remains correct.
  • Any upstream or downstream logic that depends on the behavior of RpcCall::Aws is still functioning as intended.

Manual confirmation is advised to ensure no side effects in deserialization occur after refactoring.


23-23:

❓ Verification inconclusive

Be mindful of untagged enum variant order.

Adding or reintroducing the Utils(utils::RpcCall) variant can alter how Serde resolves this untagged enum. If your deserialization logic relies on variant order, please verify this change doesn't introduce ambiguities or regressions.


🏁 Script executed:

#!/bin/bash
# Searching for all references to RpcCall::Utils in the repo to ensure correctness.
rg "RpcCall::Utils"

Length of output: 19


Manual Verification Required: Untagged Enum Variant Order

The reintroduction of the Utils(utils::RpcCall) variant may impact serde’s resolution of this untagged enum, as variant order is significant. Our previous search for references (using rg RpcCall::Utils) did not yield any outputs, which is inconclusive. Please manually verify that the ordering of variants in the enum declared in src/meta-cli/src/typegraph/rpc/mod.rs (including Utils(utils::RpcCall)) does not introduce ambiguities or regressions in deserialization behavior.

  • Confirm the position of the Utils(utils::RpcCall) variant relative to other variants.
  • Ensure that serde’s untagged deserialization does not misinterpret inputs due to this variant’s placement.
  • Reassess any changes in logic that depend on the variant order.
src/metagen/src/fdk_rs/mod.rs (3)

17-19: New imports look correct.

These client-related imports are required for subsequent logic and do not pose any obvious concerns.


150-150: No issues with retrieving tg_name.

This line properly retrieves the typegraph name for crate naming. Looks good.


303-303: No functional changes.

This minor line modification does not appear to introduce issues.

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

4-6: New imports for FunctionType and TypeNodeExt.

These imports are aligned with updated usage in gen_stub. They appear necessary and correct.


15-17: Updated signature aligns with new structures.

Switching to Arc<FunctionType> and passing in &super::Maps is consistent with the rest of the refactor. This simplifies retrieving input/output type references.

src/metagen/src/fdk_py/mod.rs (6)

14-14: Module exposure check

pub mod types; could introduce confusion if the same symbols are re-exported or overshadowed elsewhere. Confirm there’s no naming conflict with any other module or import.


72-76: Check ownership and concurrency requirements

Switching to Arc<Typegraph> suggests shared ownership, possibly enabling concurrent usage. Confirm this is intentional and all references to tg support thread-safe operations or are never used across threads if not needed.


91-94: Validate PyTypesPage usage

Retrieving and rendering type references looks correct. Ensure all required input types are properly cached and rendered. Missing or invalid references may cause runtime errors.


106-106: Filter stubbed functions carefully

Filtering functions by runtimes is correct, but make sure to handle edge cases (e.g., empty or nonexistent runtimes). Confirm the error message is adequate if this fails.


119-122: Check type references

These lookups for input and output type keys are correct, but ensure all function signatures and type keys are registered. Missing keys could lead to ok_or_eyre errors.


208-208: Validate external call success

The call to template.render_fdk_py(&self.config, tg)? is the sole content generator. Validate that any subsequent usage aligns with the final buffer output for the new fdk.py file.

tests/metagen/typegraphs/sample/rs_upload/client.rs (8)

40-58: New type definitions for upload inputs

The new RootUploadFnInput and RootUploadManyFnInput structs, along with their aliases, appear correct for file upload scenarios. Just confirm that optional vs. required fields align with runtime expectations.


76-81: Check argument type references

Passing "files".into() and "prefix".into() is valid, but verify these match the actual fields in RootUploadManyFnInput. Mismatched names could break the underlying mapping.


87-88: Multiple array items for input files

TypePathSegment::ArrayItem references an array of file items. Ensure array parsing logic in other modules (e.g., Python or TS clients) matches this expected structure.


93-93: Adding RootUploadFn node meta

RootUploadFn() function is consistent with the typical NodeMeta pattern. Validate that the final usage in function calls matches the input logic (e.g., handling optional path).


100-100: Optional path mapping

"root_upload_fn_input_path_string_25e51_optional".into() is mapped to Option<String>. Confirm any default or fallback behavior if not provided by the user.


117-117: GraphQL non-nullable file reference

"file_bf9b7" => "file_bf9b7!" indicates a non-nullable file. Confirm the server enforces this to avoid null references at runtime.


119-119: String type mapping

Mapping "root_upload_fn_input_path_string_25e51_optional" to "String" is valid for GraphQL. Check that optional usage is handled by the GraphQL schema if the user omits this field.


127-128: Array of non-null file references

"[file_bf9b7!]!" means each array item must be a valid file. Confirm this aligns with the code’s expectations for bulk file upload.

src/metagen/src/client_ts/mod.rs (12)

15-15: Extension trait usage

use typegraph::TypeNodeExt is helpful for extended node methods. Double-check that each extension method is necessary to avoid confusion with standard trait implementations.


18-18: Processed write utility

use crate::utils::processed_write; references a specialized text transformation. Ensure it’s applied consistently and watch out for partial application in other contexts.


44-48: Introducing Maps struct

Maps organizes references for types, node metas, and selections within a single struct. This is a clear improvement for maintainability. Just confirm each field is always properly initialized.


50-56: TsClientManifest struct

Encapsulating the typegraph and related pages within TsClientManifest clarifies ownership of these resources. Confirm the struct remains consistent with any future expansions (e.g., caching, references).


58-83: Manifest initialization

The new method caches references from each page for types, node_metas, and selections. Validate that all type keys are recognized and that no references are missed.


139-139: Direct buffer injection

Storing buf as contents is suitable. Double-check that subsequent toolchains (e.g., deno check) can handle all newly generated code without issues.


148-150: GenClientTsOpts struct usage

pub hostcall: bool could be extended in future for additional toggles. Validate that each new toggle is implemented in render_client.


152-163: High-level render method

render prints a warning header and delegates to render_client. This is a good encapsulation. Ensure that future expansions (such as inlined docs) are appended in a consistent manner.


165-193: render_client changes

This method writes static code, rendered types, node metas, selections, and the query graph. Verify that placeholders (like HOSTCALL) are replaced correctly, especially if hostcall is set to true.


208-210: Load GraphQL types

get_gql_types(&self.tg) populates a mapping for code generation. Validate that each type key is recognized, especially for nested or composite structures.


235-235: Rendering meta functions here

self.render_meta_functions(out)?; adds additional methods to the generated code. Ensure that each function name is unique and collisions do not occur for large typegraphs.


246-305: Handling root functions in render_meta_functions

This block dynamically creates query or mutation nodes with optional arguments and selections. Confirm that empty arguments (no input) or single-scalar outputs do not break the generated code.

src/metagen/src/client_rs/mod.rs (7)

9-11: Imports appear consistent and necessary.
These added imports properly align with the usage of RustTypesConfig, RustTypesSubmanifest, RsNodeMeta, and RustSelectionManifestPage. No conflicts or unused imports are detected.


55-61: Struct RsClientManifest organizes code generation details effectively.
This structure consolidates the typegraph, submanifests, node metas, and selections. The design appears coherent and maintainable.


147-149: Verify usage of RsClientManifest::new in the generation pipeline.
These lines create the RsClientManifest and render it into a buffer. Overall, the flow is correct. However, ensure that future code references the new file path (client.rs) consistently, and that tg_name is used in other relevant places if necessary.

Also applies to: 153-153, 159-159


185-187: GenClientRsOpts introduced for hostcall control.
This struct holds a boolean controlling hostcall usage, which cleanly extends configurability. No immediate concerns.


189-221: render and render_client methods unify generation steps.
Centralizing rendering steps inside RsClientManifest is logical and reduces reliance on scattered helper functions. The approach fosters clarity. Keep an eye on large method complexity if these grow further; modular breakdown could help.


257-356: render_root_functions effectively handles root function selection.
Constructing unselected or selected nodes for each root function is straightforward and consistent with the code’s pattern. Ensure that appended phantom type usage remains aligned with the correct partial or full types.


370-396: with_metas_namespace builds a nested module structure.
This approach helps isolate node meta methods. Be sure that nested scoping and the generated function references remain stable if any re-exports are introduced elsewhere.

tests/metagen/typegraphs/sample/ts/client.ts (24)

504-509: Flatten nested arguments when calling convertQueryNodeGql.
These new lines inside the function call split arguments for easier reading, but require consistent ordering with the preceding local variables. Double-check potential argument reordering if refactoring.


907-913: RootIdentityUpdateFn reuses RootIdentityFnInput plus argumentTypes.
Extending base NodeMeta with extra arguments is good. Confirm that the input argument is consistently recognized in all related queries.


922-929: RootIdentityFn reuses RootIdentityFnInput and sets argumentTypes.
Similar to RootIdentityUpdateFn, keep consistent usage patterns across code references. No immediate concerns.


930-933: RootNestedCompositeFn aliasing RootNestedCompositeFnOutput.
Straightforward approach to unify naming. No issues identified.


944-950: RootNestedCompositeFnOutputListStruct with a single “value” sub-node.
Straightforward definition. No structural conflicts detected.


951-958: RootNestedCompositeFnOutputCompositeStruct extends sub-nodes with “value” and “nested.”
Structure is well-defined. No issues noticed.


959-965: RootNestedCompositeFnOutputCompositeStructNestedStruct for deeper recursion.
Cleanly references “inner.” Potential expansions for deeper nesting can be approached similarly.


966-973: RootMixedUnionFn sets an argument “id” plus union output.
This design is consistent with the NodeMeta approach for union transitions. No concerns.


982-990: User node includes id, email, and posts.
Matches the definitions for new user fields. No issues identified.


991-999: Post node with “id,” “slug,” and “title.”
Mirrors other node definitions. Nothing problematic.


1000-1007: RootCompositeUnionFn sets argument “id” and references union output.
Consistent with the union approach. Everything appears correct.


1008-1015: RootCompositeUnionFnOutput: post/user variants.
Checks out with the code pattern for union expansions. Good consistency.


1016-1023: RootScalarUnionFn extends from scalar() with an “id.”
No immediate problem. Maintaining a uniform approach to argument naming is recommended.


1024-1031: RootCompositeArgsFn: argument “id” plus the Post sub-node.
Combining arguments with sub-nodes is coherent. Looks fine.


1032-1036: RootCompositeNoArgsFn references Post.
Straightforward function. No concerns.


1037-1046: RootScalarArgsFn merges scalar() with new argument types.
Uses “user_id_string_uuid,” “slug,” and “title.” Implementation is consistent.


1047-1051: RootScalarNoArgsFn extends scalar().
No arguments needed. Everything is minimal and correct.


1052-1056: RootGetPostsFn references Post with no arguments.
In sync with the rest of the structure. No issues.


1057-1061: RootGetUserFn references User with no arguments.
Similar approach as RootGetPostsFn, looks good.


1063-1065: New alias StringUuid4 integrated with Post.
Declaring StringUuid4 as a simple string is acceptable. Confirm that future expansions for ID validations or specialized types remain consistent.


1076-1081: User fields updated to StringUuid4 and StringEmail5.
Shifting these to typed aliases is more descriptive. Good move for clarity.


1093-1097: RootNestedCompositeFnOutput typed sections for scalar, composite, and list.
Ensures a well-defined structure for multi-nested data. Implementation is consistent.


1102-1104: RootNestedCompositeFnOutputCompositeStructNestedStruct uses an inner: number.
Confirms single nested field. Straightforward.


1109-1113: UserSelections adds optional fields for “id,” “email,” and “posts.”
Accurately reflects the possibility of partial selection. This is typical for GraphQL-like approaches.

tests/metagen/typegraphs/sample/rs/client.rs (10)

395-400: UserSelections structure references partial and alias logic.
Implements typed selection traits. No immediate problems, but ensure thorough coverage in selection usage tests.


450-460: query_graph() sets up type-to-GQL map references.
Mapping these “ID!”, “String!”, and “Int!” types is consistent. Keep an eye on custom types or expansions that might require unique naming logic.


463-473: get_user returns UnselectedNode<..., UserPartial>
Using partial output type for the final result suggests the resolver might not always supply all fields. This approach is correct if partial resolution is indeed intended.


475-484: get_posts returns UnselectedNode<..., PostPartial>
Similarly references partial data for “posts.” Confirm that consumers expect partial data.


507-508: scalar_args uses impl Into<NodeArgs<Post>>.
This signature ensures flexible argument passing for Post. The usage looks fine.


539-540: composite_args references RootCompositeArgsFnInput.
Solid approach to pass structured arguments. No concerns.


551-552: scalar_union references RootCompositeArgsFnInput for arguments.
Reusing RootCompositeArgsFnInput is interesting—please confirm that union behavior with these arguments is always expected.


596-597: nested_composite references RootNestedCompositeFnOutputPartial.
Straightforward partial usage, no issues.


607-608: identity uses RootIdentityFnInput with partial return.
Ensures partial output. Confirm that partial usage is intentional.


619-620: identity_update parallels identity, passing RootIdentityFnInput.
Matches the pattern, returning partial data.

tests/metagen/typegraphs/identities/py/fdk.py (7)

1030-1040: Add method RsProxyPrimitives for specialized NodeMeta creation.

This new static method is consistent with the existing pattern of returning a NodeMeta object referencing NodeDescs.Primitives(). The arg_types configuration for {"data": "primitives"} is appropriate and aligns with other methods.


1062-1090: Introduce RsSimpleCycles and define SimpleCycles1, SimpleCycles2, and SimpleCycles3.

These methods follow the established NodeMeta pattern and set arg_types to handle "data": "simple_cycles_1". The sub_nodes referencing phantom1, phantom2, phantom3, and the chained calls (to2, to3) appear correct for cyclical references.


1099-1115: Add RsCycles and update Cycles1 sub_nodes.

The new approach of setting arg_types to "data": "cycles1" and referencing sub_nodes like phantom1, to2, and list3 for cyclical structures is consistent with other cycle definitions. Looks logically sound.


1156-1192: Add RsComposites, Composites, CompositesEitherEither, and Branch2.

This block extends the composites structure with optional sub_nodes or variants. The usage of {"data": "composites"} in RsComposites is consistent. The either/union pattern referencing Primitives and Branch2 is coherent.


1193-1314: Expand or introduce RsPrimitives, TsProxyPrimitives, TsSimpleCycles, TsCycles, TsComposites, TsPrimitives, PyProxyPrimitives, PySimpleCycles, PyCycles, PyComposites, and PyPrimitives.

All methods follow the same structural pattern: retrieving a base NodeMeta, then adding arg_types. Harmonizes well across languages (TS, Py, Rs naming). Ensure consistent testing across each new function if not already covered.


1316-1370: Add typed dict definitions for PrimitivesArgs, Primitives, etc.

These TypedDicts solidify the schema for user inputs (like the “data” field). The usage of Python’s type checks for scalars (string, int, etc.) helps ensure correctness. Minor note: consider docstrings for clarity.


1371-1517: Extend typed dicts for CompositesArgs, Composites, Cycles1, SimpleCycles1, etc.

A large family of typed dict definitions covering composite structures, optional references, and cyclical fields. The pattern is clear and methodical. Verify thorough test coverage to ensure these types are used correctly.

tests/metagen/typegraphs/identities/ts/fdk.ts (6)

985-992: Implement RsProxyPrimitives in nodeMetas.

Merges a base Primitives() NodeMeta with argumentTypes: { data: "primitives" }. Matches the cross-language pattern. No issues spotted.


1011-1042: Introduce RsSimpleCycles and SimpleCycles1/2/3.

Similar to the Python counterpart, these definitions detail cyclical references (phantom1, phantom2, phantom3) and chain into each other. The structured approach appears consistent.


1043-1091: Add RsCycles, define/extend Cycles1, Branch33B, Cycles2, Branch33A, and RsComposites, plus composite/either logic.

This segment introduces or expands cyclical and composite references in TypeScript, mirroring the approach in Python and Rust. All additions align with the existing design patterns.


1214-1275: Refine typed definitions for Primitives, Composites, and their arguments.

The shift to typed fields like StringUuid6, StringEmail7, etc., enhances clarity. Using narrower string aliases promotes type safety. The expansions for optional fields appear coherent.


1276-1390: Extend cyclical type definitions (Cycles1, Cycles2, Cycles3, SimpleCycles1, etc.) and their respective selection types.

Consistent cyclical pattern. The union representations (| (Cycles3) | (Cycles1)) provide clarity on possible variants. Looks structurally sound.


1394-1521: Enhance QueryGraph and associated handlers for TS side (e.g., pyPrimitives, tsPrimitives, rsPrimitives, etc.).

Each function arrays a consistent usage of _selectionToNodeSet, hooking in new nodeMetas references. The approach stays parallel with the Python code. The overall expansions look correct.

tests/metagen/typegraphs/identities/rs/fdk.rs (20)

268-485: Introduce expanded types module
This new module structures numerous data types (primitives, composites, cycles, partial variants), which significantly expands the typegraph. The approach looks solid. One caution: using #[serde(untagged)] for large enum variants (e.g. CompositesEitherEither) can sometimes result in ambiguous deserialization if fields overlap.

Would you like to run a quick test or verification script on all variant branches to confirm no collisions?


498-507: Define RsProxyPrimitives NodeMeta
Establishes a convenient entry point for Rust-based "proxy_primitives" operation. This looks correct and matches the pattern used for other typed endpoints.


535-538: RsSimpleCycles function
Adding "data" => "simple_cycles_1" ensures the correct argument type, then forwarding to SimpleCycles1(). Logical and coherent.


547-548: SimpleCycles1 sub-nodes
Registering "phantom1" and "to2" is consistent with the typed expansions. No issues found.


557-557: SimpleCycles2 initialization
Storing variants: None and linking "phantom2", "to3" to SimpleCycles3 is consistent. All good.

Also applies to: 561-562


573-574: SimpleCycles3 sub-nodes
Defines "phantom3" mapping to scalar, "to1" linking back to SimpleCycles1, forming a cycle. Implementation seems fine.


584-584: RsCycles addition
Specifies "data" => "cycles1" with ..Cycles1(). This integration with the cyclical types is consistent.

Also applies to: 587-587


596-598: Cycles1 sub-nodes
Attaches "phantom1", "to2", and "list3" references. No issues noted.


607-607: Cycles3 union variant
sub_nodes: None with variants "branch33A" and "branch33B" is a clean approach for branching. Looks good.

Also applies to: 610-611


620-620: Branch33B
No variants, but new sub-nodes for "phantom3b" and "to2". Straightforward implementation.

Also applies to: 623-624


649-650: Branch33A
Adds "phantom3a" scalar and "to1" recursion. No concerns here.


660-660: RsComposites
Assigns "data" => "composites" and delegates to Composites(). Matches the established pattern for typed entries.

Also applies to: 663-663


672-675: Composites sub-nodes
Links "opt", "either", "union", and "list" to the correct definitions. Implementation is consistent.


684-684: CompositesEitherEither
sub_nodes: None with variants referencing Primitives and Branch2. Implementation is straightforward.

Also applies to: 687-688


700-700: Branch2 sub-node
Defines "branch2" as a scalar field. No issues.


706-715: RsPrimitives argument registration
Attaches ("data", "primitives") and delegates to Primitives(). This leverages the same pattern used in other typed entry points.


716-726: Repeated patterns for ts_, py_ NodeMeta registrations
These lines replicate the same pattern of "data" => <type> followed by a delegating spread (..Xxx()). All are consistent with the approach in RsPrimitives.

Also applies to: 730-730, 733-733, 740-740, 750-750, 760-760, 770-770, 780-780, 783-783, 790-790, 800-800, 810-810


861-864: Cycles1Selections
Selecting "phantom1", "to2", and "list3" ensures correct reflection of the cyclical data. No functional issues.


919-919: py_primitives argument type
Uses a generic NodeArgs<PrimitivesArgs> to build py_primitives. This straightforward approach is repeated in subsequent py_, ts_, and rs_ functions.

Also applies to: 921-922


933-934: Repeated query function definitions
These lines mirror the same pattern of args: impl Into<NodeArgs<...>> followed by returning a typed UnselectedNode. They align consistently with the py_primitives approach.

Also applies to: 945-946, 957-958, 969-970, 981-982, 993-994, 1005-1006, 1017-1018, 1029-1030, 1041-1042, 1053-1054, 1065-1066, 1077-1078, 1089-1090

Comment on lines 20 to 27
let inp_ty = maps
.default
.get(&fun.input().key())
.map(|s| s.as_str())
.unwrap_or("()");
let out_ty = maps.default.get(&fun.output().key()).unwrap();
let title = &fun.name();
let trait_name: String = normalize_type_title(title);
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Handle missing types more gracefully.

  • Defaulting the input type to () could mask missing or erroneous inputs.
  • Using unwrap() for the output type can cause runtime panics if it’s missing in maps.

Consider returning an error with context instead of relying on () or unwrap().


🏁 Script executed:

#!/bin/bash
# Searching the codebase for usage of `gen_stub` to confirm no panic or silent fallback.
rg "gen_stub"

Length of output: 390


Action: Revise error handling in type mappings within src/metagen/src/fdk_rs/stubs.rs.

  • The current implementation defaults the input type to "()" (lines 20–27), which can silently mask missing or malformed inputs.
  • Using .unwrap() for the output type risks a runtime panic if the key is absent in maps.default.
  • Since gen_stub is used in multiple locations (see src/metagen/src/fdk_rs/mod.rs), any changes to error handling here should be propagated consistently without breaking caller expectations.

Recommendation:
Refactor the code to return an error with context when an expected type is missing rather than falling back to a default or panicking. This will improve the robustness of type handling across the codebase.

let def_name = serde_json::from_value::<String>(
fun.mat
fun.materializer
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Warn on direct unwrap of materializer data

fun.materializer.data.get("name").unwrap() may panic if "name" is missing. Consider using more robust error handling or a default value for resilience.

- let def_name = serde_json::from_value::<String>(
-     fun.materializer.data.get("name").unwrap().clone(),
- )?;
+ let def_val = fun.materializer
+    .data
+    .get("name")
+    .ok_or_else(|| eyre::eyre!("missing python mod name"))?;
+ let def_name = serde_json::from_value::<String>(def_val.clone())?;
📝 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
fun.materializer
// ... preceding code remains unchanged
let def_val = fun.materializer
.data
.get("name")
.ok_or_else(|| eyre::eyre!("missing python mod name"))?;
let def_name = serde_json::from_value::<String>(def_val.clone())?;
// ... following code remains unchanged

Comment on lines 41 to 165
pub posts: UserPostsPostList,
}
pub type UserEmailStringEmail = String;
pub type UserPostsPostList = Vec<Box<Post>>;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
#[allow(clippy::large_enum_variant)]
#[serde(untagged)]
pub enum RootScalarUnionFnOutput {
StringE1a43(String),
Integer64be4(i64),
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
#[allow(clippy::large_enum_variant)]
#[serde(untagged)]
pub enum RootCompositeUnionFnOutput {
Post(Post),
User(User),
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
#[allow(clippy::large_enum_variant)]
#[serde(untagged)]
pub enum RootMixedUnionFnOutput {
Post(Post),
User(User),
StringE1a43(String),
Integer64be4(i64),
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct RootNestedCompositeFnOutput {
pub scalar: i64,
pub composite: RootNestedCompositeFnOutputCompositeStruct,
pub list: RootNestedCompositeFnOutputListRootNestedCompositeFnOutputListStructList,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct RootNestedCompositeFnOutputCompositeStruct {
pub value: i64,
pub nested: RootNestedCompositeFnOutputCompositeStructNestedStruct,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct RootNestedCompositeFnOutputCompositeStructNestedStruct {
pub inner: i64,
}
pub type RootNestedCompositeFnOutputListRootNestedCompositeFnOutputListStructList = Vec<Box<RootNestedCompositeFnOutputListStruct>>;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct RootNestedCompositeFnOutputListStruct {
pub value: i64,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct UserPartial {
pub id: Option<UserIdStringUuid>,
pub email: Option<UserEmailStringEmail>,
pub posts: Option<UserPostsPostListPartial>,
}
pub type UserPostsPostListPartial = Vec<Box<PostPartial>>;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct PostPartial {
pub id: Option<UserIdStringUuid>,
pub slug: Option<String>,
pub title: Option<String>,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
#[allow(clippy::large_enum_variant)]
#[serde(untagged)]
pub enum RootCompositeUnionFnOutputPartial {
Post(PostPartial),
User(UserPartial),
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
#[allow(clippy::large_enum_variant)]
#[serde(untagged)]
pub enum RootMixedUnionFnOutputPartial {
Post(PostPartial),
User(UserPartial),
StringE1a43(String),
Integer64be4(i64),
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct RootNestedCompositeFnOutputPartial {
pub scalar: Option<i64>,
pub composite: Option<RootNestedCompositeFnOutputCompositeStructPartial>,
pub list: Option<RootNestedCompositeFnOutputListRootNestedCompositeFnOutputListStructListPartial>,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct RootNestedCompositeFnOutputCompositeStructPartial {
pub value: Option<i64>,
pub nested: Option<RootNestedCompositeFnOutputCompositeStructNestedStructPartial>,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct RootNestedCompositeFnOutputCompositeStructNestedStructPartial {
pub inner: Option<i64>,
}
pub type RootNestedCompositeFnOutputListRootNestedCompositeFnOutputListStructListPartial = Vec<Box<RootNestedCompositeFnOutputListStructPartial>>;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct RootNestedCompositeFnOutputListStructPartial {
pub value: Option<i64>,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct RootIdentityFnInputPartial {
pub input: Option<i64>,
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Newly added or refactored types, partial types, and associated enums.

  1. The distinction between full vs. partial types (e.g., User vs. UserPartial) promotes clarity, but be sure all call sites consistently rely on the correct variant.
  2. Sizable enumerations like RootMixedUnionFnOutputPartial might benefit from comments describing each variant’s usage to reduce confusion.
  3. Consider adding dedicated tests for partial vs. non-partial states, ensuring the serialization logic matches expected usage.

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

♻️ Duplicate comments (3)
src/metagen/src/fdk_rs/stubs.rs (1)

20-25: ⚠️ Potential issue

Handle missing types more gracefully.

Defaulting the input type to () could mask missing or erroneous inputs, and using unwrap() for the output type can cause runtime panics if it's missing in maps.

Apply this diff to add proper error handling:

-    let inp_ty = maps
-        .inputs
-        .get(&fun.input().key())
-        .map(|s| s.as_str())
-        .unwrap_or("()");
-    let out_ty = maps.outputs.get(&fun.output().key()).unwrap();
+    let inp_ty = maps
+        .inputs
+        .get(&fun.input().key())
+        .map(|s| s.as_str())
+        .unwrap_or_else(|| {
+            log::warn!("Input type for function {:?} not found, defaulting to '()'", fun.name());
+            "()"
+        });
+    let out_ty = maps.outputs.get(&fun.output().key())
+        .ok_or_else(|| anyhow::anyhow!("Output type for function {:?} not found", fun.name()))?;
src/metagen/src/fdk_rs/types.rs (2)

183-200: ⚠️ Potential issue

Missing cyclic reference handling for container types.

The container_def method doesn't handle cyclic references, which could lead to infinite recursion in type definitions with self-references.

Based on the PR comments, there used to be a mechanism for detecting cycles (is_path_unfortunately_cyclic), but it hasn't been replicated in the new implementation. This needs to be addressed to prevent potential stack overflows.

As a temporary solution, you could add a depth limit or a set to track visited types.


282-283: ⚠️ Potential issue

Implement cyclic reference detection in container types.

The TODO comments in both Optional and List type handling indicate that cyclic reference detection still needs to be implemented.

This is critical for preventing infinite recursion in type definitions. Based on the PR comments, there was previously a mechanism (is_path_unfortunately_cyclic) that needs to be re-implemented.

Also applies to: 289-290

🧹 Nitpick comments (13)
tests/metagen/typegraphs/identities/rs/fdk.rs (1)

268-488: Consider clarifying large enum variants and verifying untagged enum cases.

This newly introduced types module defines numerous interlinked structs and enums (e.g. Cycles1, Cycles2, Cycles3) with cyclical references and several #[serde(untagged)] enums. While this structure appears intentional, untagged enums can produce ambiguous deserialization if two variants share the same shape. Also, large enum variants can increase memory overhead.

  1. Consider adding doc comments for these exported types to clarify usage.
  2. Assess whether #[serde(tag = "...")] might reduce ambiguity in certain enums or if the untagged approach remains strictly necessary.
src/metagen/src/fdk_rs/mod.rs (1)

204-238: Consider refactoring conditional maps creation to reduce code duplication.

The conditional creation of maps based on config.exclude_client creates two parallel code paths with similar structure. This might become difficult to maintain if the logic evolves differently in the future.

Consider extracting the common logic and only conditionally executing the different parts:

-    let maps = if config.exclude_client.unwrap_or_default() {
-        let manifest = RustTypesConfig::default()
-            .output_types(OutputTypes::NonPartial)
-            .derive_serde(true)
-            .derive_debug(true)
-            .build_manifest(&tg);
-        manifest.render_full(&mut mod_rs.buf)?;
-
-        Maps {
-            inputs: manifest.inputs.get_cached_refs(),
-            outputs: manifest
-                .outputs
-                .as_ref()
-                .map(|p| p.get_cached_refs())
-                .unwrap_or_default(),
-            // partial_outputs: manifest
-            //     .partial_outputs
-            //     .as_ref()
-            //     .map(|p| p.get_cached_refs())
-            //     .unwrap_or_default(),
-        }
-    } else {
-        let manifest = RsClientManifest::new(
-            tg.clone(),
-            &RsClientManifestOpts {
-                non_partial_output_types: true,
-            },
-        )?;
-        manifest.render_client(&mut mod_rs.buf, &GenClientRsOpts { hostcall: true })?;
-        Maps {
-            inputs: manifest.maps.input_types,
-            outputs: manifest.maps.output_types,
-            // partial_outputs: manifest.maps.partial_output_types,
-        }
-    };
+    let exclude_client = config.exclude_client.unwrap_or_default();
+    let maps = if exclude_client {
+        let manifest = RustTypesConfig::default()
+            .output_types(OutputTypes::NonPartial)
+            .derive_serde(true)
+            .derive_debug(true)
+            .build_manifest(&tg);
+        manifest.render_full(&mut mod_rs.buf)?;
+        
+        Maps {
+            inputs: manifest.inputs.get_cached_refs(),
+            outputs: manifest
+                .outputs
+                .as_ref()
+                .map(|p| p.get_cached_refs())
+                .unwrap_or_default(),
+        }
+    } else {
+        let manifest = RsClientManifest::new(
+            tg.clone(),
+            &RsClientManifestOpts {
+                non_partial_output_types: true,
+            },
+        )?;
+        manifest.render_client(&mut mod_rs.buf, &GenClientRsOpts { hostcall: true })?;
+        Maps {
+            inputs: manifest.maps.input_types,
+            outputs: manifest.maps.output_types,
+        }
+    };
src/metagen/src/fdk_rs/types.rs (2)

80-97: Consider handling the empty alias case more explicitly.

When an alias name is None, the render method simply returns Ok(()) without any explanation. This makes the code harder to understand.

Consider adding a comment explaining why an empty result is appropriate in this case, or handle this case more explicitly:

                if let Some(alias_name) = alias_name {
                    match alias {
                        // ... existing code ...
                    }
                } else {
-                    Ok(())
+                    // This is an inlined type, so no explicit alias definition is needed
+                    Ok(())
                }

1026-1032: Clean up commented test code.

There are TODOs and commented-out lines in the test code, indicating incomplete migration.

Either complete the migration of the test code or remove the commented parts if they're no longer needed. This will improve code readability and maintainability.

src/metagen/src/client_ts/mod.rs (2)

356-360: Remove debugging code from production error handling.

The error handling code that prints the file line by line seems like a debugging aid rather than a production error handling strategy.

Consider using a more concise error message or logging the file content at a debug level:

                        if !status.success() {
-                            let code = std::fs::read_to_string(args.path.join("client.ts"))?;
-                            for line in code.lines().enumerate() {
-                                eprintln!("{:04}: {}", line.0, line.1);
-                            }
+                            log::debug!("File content: {}", std::fs::read_to_string(args.path.join("client.ts"))?);
                            anyhow::bail!("error checking generated crate");
                        }

169-178: Consider expanding GenClientTsOpts for future extensibility.

Currently, GenClientTsOpts only contains a hostcall field, but it's set up as a struct, suggesting it might be expanded in the future.

If there are plans to add more options, consider adding a comment indicating what options might be added in the future. If not, a simple boolean parameter might be clearer.

src/metagen/src/client_rs/mod.rs (5)

48-54: Consider adding doc comments to clarify the role of Maps.
Though the fields are self-explanatory, a top-level doc comment would help future maintainers understand how this struct is used to store type references.


56-66: Ensure consistent visibility and naming across RsClientManifest and RsClientManifestOpts.
pub(super) fields are mixed with a public maps field. Verify it is intentional to expose only maps but hide other fields. Adding doc comments for these public items would also improve clarity.


205-207: Add doc comments for GenClientRsOpts.
Providing a short summary, especially around the hostcall flag, would make usage more transparent.


277-380: Long function handling root functions—but structurally fine.
Overall it’s readable, although splitting out sub-steps (e.g., building each UnselectedNode) into helper methods could further improve clarity.


394-420: Consider adding docs for with_metas_namespace.
This helper function is fairly self-explanatory, but a small doc comment describing the rationale would benefit new contributors.

tests/metagen/typegraphs/sample/rs/client.rs (2)

224-297: Union node metas for RootMixedUnionFn and RootCompositeUnionFn
The multi-variant approach (post/user, etc.) is well-implemented. For clarity, consider consistent naming across these function families (e.g., “RootMixedUnion...” vs. “RootCompositeUnion...”).


485-577: Remaining root calls referencing partial outputs.
composite_args, composite_union, mixed_union, nested_composite, identity, and identity_update consistently use partial types for outputs. This might be correct if these endpoints truly allow partial objects. Otherwise, consider switching if full objects are needed.

Would you like help converting certain endpoints to return non-partial types if you intend to enforce fully required fields?

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between bb5e3fe and f565e17.

📒 Files selected for processing (7)
  • src/metagen/src/client_rs/mod.rs (8 hunks)
  • src/metagen/src/client_ts/mod.rs (6 hunks)
  • src/metagen/src/fdk_rs/mod.rs (6 hunks)
  • src/metagen/src/fdk_rs/stubs.rs (2 hunks)
  • src/metagen/src/fdk_rs/types.rs (24 hunks)
  • tests/metagen/typegraphs/identities/rs/fdk.rs (21 hunks)
  • tests/metagen/typegraphs/sample/rs/client.rs (15 hunks)
🧰 Additional context used
🧬 Code Definitions (7)
src/metagen/src/fdk_rs/stubs.rs (2)
src/metagen/src/fdk_rs/utils.rs (1)
  • normalize_type_title (26-43)
src/typegraph/schema/src/types.rs (1)
  • fmt (118-131)
src/metagen/src/fdk_rs/mod.rs (2)
src/metagen/src/client_rs/mod.rs (2)
  • new (69-112)
  • new (121-125)
src/metagen/src/fdk_rs/stubs.rs (1)
  • gen_stub (14-54)
src/metagen/src/fdk_rs/types.rs (2)
src/metagen/src/shared/types.rs (1)
  • type_body_required (23-38)
src/metagen/src/fdk_rs/mod.rs (1)
  • new (84-88)
src/metagen/src/client_ts/mod.rs (5)
src/metagen/src/fdk_ts/types.rs (4)
  • new (246-263)
  • render (126-182)
  • ty (87-99)
  • ty (107-111)
src/metagen/src/shared/node_metas.rs (1)
  • new (22-30)
src/metagen/src/client_ts/selections.rs (4)
  • manifest_page (119-175)
  • render (25-51)
  • render (67-98)
  • render (104-109)
src/metagen/src/client_ts/node_metas.rs (4)
  • render (22-32)
  • render (52-79)
  • render (89-115)
  • render (127-172)
src/metagen/src/shared/manifest.rs (1)
  • render (14-18)
src/metagen/src/client_rs/mod.rs (4)
src/metagen/src/client_rs/selections.rs (2)
  • manifest_page (167-230)
  • render (36-47)
src/metagen/src/client_rs/node_metas.rs (4)
  • render (46-61)
  • render (75-109)
  • render (113-147)
  • render (151-202)
src/metagen/src/shared/manifest.rs (1)
  • render (14-18)
src/metagen/src/client_rs/static/client.rs (1)
  • hostcall (32-37)
tests/metagen/typegraphs/sample/rs/client.rs (1)
tests/metagen/typegraphs/sample/ts/client.ts (31)
  • Post (991-999)
  • Post (1064-1068)
  • RootIdentityFnInput (915-921)
  • RootIdentityFnInput (1072-1074)
  • User (982-990)
  • User (1075-1079)
  • scalar (903-905)
  • RootIdentityFn (922-929)
  • RootNestedCompositeFn (930-934)
  • RootNestedCompositeFnOutput (935-943)
  • RootNestedCompositeFnOutput (1093-1097)
  • RootNestedCompositeFnOutputCompositeStruct (951-958)
  • RootNestedCompositeFnOutputCompositeStruct (1098-1101)
  • RootNestedCompositeFnOutputListStruct (944-950)
  • RootNestedCompositeFnOutputListStruct (1106-1108)
  • RootNestedCompositeFnOutputCompositeStructNestedStruct (959-965)
  • RootNestedCompositeFnOutputCompositeStructNestedStruct (1102-1104)
  • RootMixedUnionFn (966-973)
  • RootMixedUnionFnOutput (974-981)
  • RootMixedUnionFnOutput (1088-1092)
  • RootCompositeUnionFn (1000-1007)
  • RootCompositeUnionFnOutput (1008-1015)
  • RootCompositeUnionFnOutput (1085-1087)
  • UserSelections (1109-1113)
  • PostSelections (1114-1118)
  • value (243-279)
  • inner (195-197)
  • inner (206-208)
  • RootCompositeUnionFnOutputSelections (1119-1122)
  • RootMixedUnionFnOutputSelections (1123-1126)
  • RootIdentityFnInputSelections (1142-1144)
tests/metagen/typegraphs/identities/rs/fdk.rs (1)
tests/metagen/typegraphs/identities/ts/fdk.ts (35)
  • PrimitivesArgs (1214-1216)
  • Primitives (993-1010)
  • Primitives (1217-1230)
  • PrimitivesStrString (1231-1231)
  • PrimitivesEnumStringEnum (1232-1236)
  • PrimitivesIntInteger (1244-1244)
  • PrimitivesFloatFloat (1245-1245)
  • PrimitivesBooleanBoolean (1246-1246)
  • Composites (1100-1109)
  • Composites (1250-1255)
  • CompositesOptPrimitivesStrStringOptional (1256-1256)
  • CompositesEitherEither (1110-1117)
  • CompositesEitherEither (1257-1259)
  • CompositesUnionUnion (1263-1267)
  • CompositesListPrimitivesStrStringList (1274-1274)
  • Cycles1Args (1275-1277)
  • Cycles1 (1051-1059)
  • Cycles1 (1278-1282)
  • Cycles1To2Cycles2Optional (1283-1283)
  • Cycles1List3Cycles1List3Cycles3ListOptional (1299-1299)
  • Cycles2 (1076-1083)
  • Cycles2 (1284-1286)
  • Cycles3 (1060-1067)
  • Cycles3 (1287-1289)
  • Cycles1List3Cycles3List (1300-1300)
  • SimpleCycles1Args (1301-1303)
  • SimpleCycles1 (1019-1026)
  • SimpleCycles1 (1304-1307)
  • SimpleCycles1To2SimpleCycles2Optional (1308-1308)
  • SimpleCycles2 (1027-1034)
  • SimpleCycles2 (1309-1312)
  • SimpleCycles3 (1035-1042)
  • SimpleCycles3 (1314-1317)
  • SimpleCycles3To1SimpleCycles1Optional (1318-1318)
  • scalar (981-983)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: lint-compat (macos-14, aarch64-apple-darwin, false)
  • GitHub Check: test-full
  • GitHub Check: bulid-docker (linux/amd64, custom-ubuntu-large)
  • GitHub Check: lint-compat (macos-13, x86_64-apple-darwin, false)
  • GitHub Check: pre-commit
🔇 Additional comments (35)
tests/metagen/typegraphs/identities/rs/fdk.rs (11)

501-510: Looks good for RsProxyPrimitives.

This helper function cleanly follows the established pattern of returning a NodeMeta. The use of ..Primitives() for default fields is consistent with other code sections. No immediate concerns.


534-543: RsSimpleCycles function is consistent.

This function mirrors the same node-meta pattern as elsewhere. The returned NodeMeta references SimpleCycles1. Everything lines up well with the existing approach. No changes requested.


550-580: Check for correct linking in SimpleCycles1/2/3.

The newly added sub-nodes (phantom1, to2, etc.) reference each other across these functions and may create recursive cycles. The references to SimpleCycles2 and SimpleCycles3 are presumably valid. Just ensure all intended cyclical paths are tested to confirm that no infinite recursion or unexpected serialization issues arise.

Do you have integration or unit tests that validate serialization/deserialization for these cyclical structures?


587-616: RsCycles and Cycles1/Cycles3 expansions appear correct.

The expansions for cyclical references in RsCycles are coherent with the nested hostcall approach. The sub-nodes (phantom1, to2, list3, etc.) are aligned with the partial data structures in the types module. No immediate issues.


620-657: Branch33B and Branch33A expansions are consistent.

Both node-meta functions correctly expose sub-nodes for phantom3b, to2, phantom3a, and to1. This matches the cyclical design in the types module. No concerns.


663-718: RsComposites, Composites, CompositesEitherEither, Branch2, and RsPrimitives expansions are well-integrated.

These definitions match the approach used for other expansions, passing the correct type names (e.g., "composites", "primitives") and hooking up sub-nodes. The slight duplication in code structure is presumably auto-generated. Everything is consistent.


757-818: New TS and Py node-meta functions appear consistent.

This block contains wrappers like TsComposites, TsPrimitives, PyProxyPrimitives, PySimpleCycles, etc., with the same approach: map "data" to the correct type key and build sub-nodes. The pattern is standard and no issues stand out.


857-869: Cycles3Selections & Cycles1Selections expansions.

The new union selection traits for branch33A and branch33B, along with the nested scalar node references, align with the cyclical design. No immediate concerns.


888-892: SimpleCycles1Selections additions.

These additions keep the same pattern (adding phantom1 and to2 as sub-selections). Looks consistent with the other expansions.


906-912: query_graph expansions are correct.

The new mappings for "primitives", "composites", "cycles1", and "simple_cycles_1" in .ty_to_gql_ty_map appear aligned with the rest of the code. No issues.


921-1093: Verified the new Rust/TS/Py node functions.

All newly introduced or modified _primitives, _composites, _cycles, _simple_cycles, _proxy_primitives entry points consistently accept and transform NodeArgs<T> to UnselectedNode<...>. This uniform approach matches the rest of the codebase’s pattern. No functional or logical issues detected.

src/metagen/src/fdk_rs/mod.rs (4)

180-185: Good addition of the Maps struct for type organization.

The new Maps struct nicely encapsulates various type mappings, improving code organization and making the relationships between different types more explicit.


188-188: Function signature update to use Arc<Typegraph> promotes efficiency.

Changing the function signature to use Arc<Typegraph> instead of &Typegraph allows for shared ownership of the typegraph without unnecessary cloning, which is a good optimization.


317-318:

✅ Verification successful

Subtle change in argument passing from dest to &mut dest.buf.

The change from dest to &mut dest.buf in the processed_write call might be an intentional fix or a potential bug. Verify that the function signature of processed_write expects a mutable string reference rather than the entire GenDestBuf struct.


🏁 Script executed:

#!/bin/bash
# Check the signature of processed_write function
rg -A 2 "fn processed_write" src/

Length of output: 178


Verification: Processed Write Signature Matches &mut dest.buf

After checking the signature of processed_write (which is defined as:

pub fn processed_write(
    dest: &mut impl Write,
    input: &str,
)

), it is confirmed that this function expects a mutable reference to a writer. Therefore, passing &mut dest.buf (assuming that dest.buf implements Write) is the correct and intended usage.

  • No further issues found.

251-257:

✅ Verification successful

Error handling in filter_stubbed_funcs needs validation.

The call to filter_stubbed_funcs now passes ownership of &tg rather than cloning it. Make sure this doesn't lead to lifetime issues in the function implementation.


🏁 Script executed:

#!/bin/bash
# Check the implementation of filter_stubbed_funcs to ensure it properly handles the Arc<Typegraph> reference
rg -A 5 "fn filter_stubbed_funcs" src/

Length of output: 443


Error handling and lifetime validation confirmed.

After reviewing the implementation of filter_stubbed_funcs in src/metagen/src/shared/mod.rs, it is clear that the function explicitly accepts a reference (&Typegraph). Passing &tg in the caller as shown is intentional, and there are no associated lifetime issues with this usage. The error handling via wrap_err_with remains valid.

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

4-6: Good update to imports to use the new typegraph crate.

The updated imports properly reflect the migration to the new typegraph crate structure.


14-19: Updated function signature properly reflects the new type structure.

The gen_stub function signature has been appropriately updated to use Arc<FunctionType> and the new Maps struct.

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

11-59: Good introduction of clear type definitions with enums and structs.

The new type definitions using enums and structs provide a more structured and type-safe approach compared to the previous implementation. This improves code readability and maintainability.

src/metagen/src/client_ts/mod.rs (3)

44-56: Good modularization with Maps and TsClientManifest structures.

The introduction of the Maps and TsClientManifest structures improves the organization of the code by centralizing the management of type mappings and rendering logic, following good object-oriented design principles.


59-83: Well-structured initialization in TsClientManifest::new.

The initialization process in TsClientManifest::new is well-structured, creating and caching references for each component in a consistent manner.


133-136: Improved error handling in the generate method.

The generate method now properly handles errors from TsClientManifest::new with the ? operator, which is a good practice.

src/metagen/src/client_rs/mod.rs (7)

9-12: Imports look appropriate for new functionality.
No immediate issues found with adding these imports. They appear necessary for the upcoming uses of RustTypesConfig, ManifestPage, etc.


162-179: Logic for generating client.rs looks solid.
The approach of constructing RsClientManifest, rendering it to a buffer, then inserting the result into the output map is straightforward and maintainable. No issues detected here.


209-223: Rendering entry point for RsClientManifest is concise and clear.
The generated header and subsequent client rendering steps are well structured.


225-241: Client rendering flow is well organized.
The invocation of render_static, render_full, node metas, and selections in a single function simplifies the generation pipeline.


243-275: Query graph rendering logic is properly encapsulated.
Generating a separate function to handle GraphQL type mappings is a good design choice, paving the way for potential expansions.


384-384: Static content injection is straightforward.
The approach of processing and writing static client.rs data is consistent with the rest of the pipeline.


68-112:

✅ Verification successful

Verify correct usage of partial and non-partial outputs.
When non_partial_output_types is false, partial outputs are generated. Please confirm that all call sites in the codebase and tests are updated accordingly to avoid mismatches between partial and complete types.


🏁 Script executed:

#!/bin/bash
# Search references to older typed partial usage
rg 'Partial' -A 3 -B 3

Length of output: 68708


Verified: Partial and non-partial outputs are used consistently across the codebase.
I reviewed the relevant call sites and tests. In src/metagen/src/client_rs/mod.rs, the code switches between OutputTypes::Both (when the non_partial_output_types flag is true) and OutputTypes::Partial (when false). The grep results show that all type names—such as UserPartial, PostPartial, etc.—and related call sites in tests and other modules now correctly reference the partial types. There are no mismatches between partial and complete types evident in the codebase.

tests/metagen/typegraphs/sample/rs/client.rs (7)

136-185: Root identity metadata composition looks consistent.
RootIdentityUpdateFn merges arguments from RootIdentityFnInput with an additional property. The layering with ..RootIdentityFnInput() helps reuse. No immediate issues.


187-223: Nested composite node metas appear structurally correct.
These functions provide a nested object scheme for RootNestedCompositeFn.... Properly referencing partial struct fields is done effectively here.


298-339: Scalar union and composite args usage.
RootScalarUnionFn and RootCompositeArgsFn show a clean approach to distinguishing input argument types vs. returned unions. Implementation is straightforward.


340-344: Get methods align with metas for user/posts.
RootGetPostsFn and RootGetUserFn follow the same structure as other root calls, returning partial typed nodes. No issues.


352-395: Selection structs coverage is robust.
The code defines selections for user, post, and nested composites. The usage of macros like impl_selection_traits! keeps the code DRY.


407-465:

✅ Verification successful

Query graph definition and initial root calls
Methods like get_user() and scalar_args() illustrate consistent usage of partial types in the return type while still offering typed input arguments. Verify that the scalar_args function indeed intends to accept Post as input.

Would you like to confirm that scalar_args(...) -> MutationNode<String> is meant to accept NodeArgs<Post>? If so, it suggests a specialized use case.


🏁 Script executed:

#!/bin/bash
rg 'fn scalar_args'

Length of output: 90


Scalar Args Type Verification Confirmed

The scalar_args function is indeed defined to accept an argument of type impl Into<NodeArgs<Post>> and returns a MutationNode<String>. This signature suggests it's intentionally specialized for handling Post inputs for mutations—consistent with the pattern observed in the other root calls. No further changes are required unless there’s a specific mismatch with domain expectations.


41-123:

❓ Verification inconclusive

Extensive definition of partial and non-partial structs.
The code outlines many types, such as UserPartial, PostPartial, and related enums. Ensure that any references to older partial definitions elsewhere in tests are updated to match these new names and structures.


🏁 Script executed:

#!/bin/bash
# Confirm no stale references to removed partial types across tests
rg 'Partial' tests

Length of output: 10395


Action: Verify Consistency of Partial Type References Across Tests

The updated definitions in tests/metagen/typegraphs/sample/rs/client.rs look good, but the search reveals that several other test files still reference types with the Partial suffix. Please review the following to ensure all partial type names and structures are consistent with the new definitions:

  • tests/runtimes/wasm_wire/rust/fdk.rs
    Check that types like ProfilePartial, ProfileCategoryStructPartial, and EntityPartial are either intentionally distinct or need to be aligned with the updated naming convention.

  • tests/metagen/typegraphs/identities/rs/fdk.rs
    Verify that types such as PrimitivesPartial, Branch2Partial, and others conform to the new structure or are updated as required.

  • Other references
    Confirm that any references in JSON (e.g., in tests/importers/introspection.json) and TypeScript (e.g., in tests/artifacts/artifacts_test.ts) are consistent with the new definitions.

Please update or document any intentional differences accordingly.

Comment on lines +80 to +241
// input: 1,
// output: 1,
// injections: Default::default(),
// outjections: Default::default(),
// runtime_config: Default::default(),
// rate_calls: false,
// rate_weight: None,
// materializer: 0,
// parameter_transform: None,
// },
// base: TypeNodeBase {
// title: "my_func".into(),
// ..default_type_node_base()
// },
// },
// ],
// })
// };
//
// let tg: Arc<Typegraph> = Arc::new(tg.try_into()?);
//
// let generator = Generator::new(FdkRustGenConfig {
// base: crate::config::FdkGeneratorConfigBase {
// path: "/".into(),
// typegraph_name: Some(tg_name.clone()),
// typegraph_path: None,
// template_dir: None,
// },
// stubbed_runtimes: Some(vec!["wasm".into()]),
// crate_name: None,
// skip_lib_rs: None,
// skip_cargo_toml: None,
// })?;
// let out = generator.generate(
// [
// (
// Generator::INPUT_TG.to_owned(),
// GeneratorInputResolved::TypegraphFromTypegate { raw: tg },
// ),
// (
// "template_dir".to_owned(),
// GeneratorInputResolved::FdkTemplate {
// template: FdkTemplate {
// entries: fdk_rs::DEFAULT_TEMPLATE
// .iter()
// .map(|(file, content)| (*file, (*content).into()))
// .collect(),
// },
// },
// ),
// ]
// .into_iter()
// .collect(),
// )?;
// let (_, buf) = out
// .0
// .iter()
// .find(|(path, _)| path.file_name().unwrap() == "fdk.rs")
// .unwrap();
// pretty_assertions::assert_eq!(
// r#"// gen-static-end
// use types::*;
// pub mod types {
// pub type MyInt = i64;
// }
// pub mod stubs {
// use super::*;
// pub trait MyFunc: Sized + 'static {
// fn erased(self) -> ErasedHandler {
// ErasedHandler {
// mat_id: "my_func".into(),
// mat_title: "my_func".into(),
// mat_trait: "MyFunc".into(),
// handler_fn: Box::new(move |req, cx| {
// let req = serde_json::from_str(req)
// .map_err(|err| HandleErr::InJsonErr(format!("{err}")))?;
// let res = self
// .handle(req, cx)
// .map_err(|err| HandleErr::HandlerErr(format!("{err}")))?;
// serde_json::to_string(&res)
// .map_err(|err| HandleErr::HandlerErr(format!("{err}")))
// }),
// }
// }
//
// fn handle(&self, input: MyInt, cx: Ctx) -> anyhow::Result<MyInt>;
// }
// pub fn op_to_trait_name(op_name: &str) -> &'static str {
// match op_name {
// "my_op" => "MyFunc",
// _ => panic!("unrecognized op_name: {op_name}"),
// }
// }
// }
// "#,
// &buf.contents[buf.contents.find("// gen-static-end").unwrap()..]
// );
// Ok(())
// }
// }
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

Tests have been commented out, potentially reducing test coverage.

The entire test module has been commented out, which is concerning. Tests are crucial for verifying functionality, especially during significant refactoring.

Either update the test to work with the new implementation or provide a clear explanation (as a TODO comment) for why it's temporarily commented out with a timeline for when it will be fixed. If these tests are being replaced by tests elsewhere, please document that.

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

🔭 Outside diff range comments (1)
src/metagen/src/client_py/selections.rs (1)

91-141: 🛠️ Refactor suggestion

Add error handling for unwrap calls in the Union renderer.

Similar to the Object renderer, the Union renderer also contains unwrap calls that could lead to runtime panics:

     match &variant.select_ty {
         Scalar | ScalarArgs { .. } => {
             // scalars always get selected if the union node
             // gets selected
             unreachable!()
         }
         Composite { select_ty } => {
-            let select_ty = page.get_ref(select_ty).unwrap();
+            let select_ty = page.get_ref(select_ty)
+                .ok_or_else(|| format!("Missing selection type reference for select_ty: {:?}", select_ty))?;
             ...
         }
         CompositeArgs { arg_ty, select_ty } => {
-            let arg_ty = page.extras.input_types.get(arg_ty).unwrap();
-            let select_ty = page.get_ref(select_ty).unwrap();
+            let arg_ty = page.extras.input_types.get(arg_ty)
+                .ok_or_else(|| format!("Missing input type for arg_ty: {:?}", arg_ty))?;
+            let select_ty = page.get_ref(select_ty)
+                .ok_or_else(|| format!("Missing selection type reference for select_ty: {:?}", select_ty))?;
             ...
         }

Additionally, consider replacing the unreachable!() call with a more descriptive error or assertion that documents the expected invariant.

🧹 Nitpick comments (4)
src/metagen/src/client_py/selections.rs (2)

10-10: Consider using specific imports instead of wildcard imports.

The use of wildcard imports (*) can make it harder to track dependencies and understand what's being used from each module. Consider replacing them with specific imports for better code clarity and maintainability.

-use crate::{interlude::*, shared::client::*};
+use crate::{
+    interlude::{Arc, IndexMap, TypeKey},
+    shared::client::{selection_for_field, SelectionTy}
+};

143-213: Consider adding documentation for assumptions and refactor the unreachable! call.

The implementation relies on assumptions about the input types that could be better documented. The unreachable!() call on line 158 should be replaced with a more descriptive error message or assertion:

     | Type::Integer(_)
     | Type::String(_)
     | Type::File(_) => {
-        unreachable!("scalars don't get to have selections")
+        // This should never happen because we filter for composite types earlier
+        debug_assert!(false, "Scalars don't get to have selections");
+        continue; // safer fallback in production
     }

Also, consider adding a comment to explain the purpose of cache_references() on line 210, as its necessity isn't immediately clear from the code.

src/typegraph/graph/src/path.rs (2)

303-355: Reduce code duplication in the contains method

The implementation for Input and Output cases is nearly identical. Consider refactoring to eliminate duplication.

pub fn contains(&self, nodes: &[tg_schema::TypeNode], xkey: &TypeKeyEx) -> bool {
    use RelativePath as RP;

    match self {
        RP::Function(_) => false,
        RP::NsObject(_) => false,
-        RP::Input(p) => {
-            let owner = p.owner.upgrade().expect("no strong pointer for type");
-            let input_type = match &nodes[owner.base.type_idx as usize] {
-                tg_schema::TypeNode::Function { data, .. } => data.input,
-                _ => unreachable!("expected a function node"),
-            };
-            let injection = owner.injection().cloned();
-            let mut cursor = TypeKeyEx(input_type, DuplicationKey { injection });
-            for seg in &p.path {
-                match seg.apply_on_schema_node_ex(nodes, cursor) {
-                    Ok(next) => {
-                        if &next == xkey {
-                            return true;
-                        }
-                        cursor = next;
-                    }
-                    Err(_) => return false,
-                }
-            }
-
-            false
-        }
-
-        RP::Output(p) => {
-            let owner = p.owner.upgrade().expect("no strong pointer for type");
-            let out_ty = match &nodes[owner.base.type_idx as usize] {
-                tg_schema::TypeNode::Function { data, .. } => data.output,
-                _ => unreachable!("expected a function node"),
-            };
-
-            let mut cursor = TypeKeyEx(out_ty, DuplicationKey { injection: None });
-            for seg in &p.path {
-                match seg.apply_on_schema_node_ex(nodes, cursor) {
-                    Ok(next) => {
-                        if &next == xkey {
-                            return true;
-                        }
-                        cursor = next;
-                    }
-                    Err(_) => return false,
-                }
-            }
-
-            false
-        }
+        RP::Input(p) | RP::Output(p) => {
+            let Some(owner) = p.owner.upgrade() else {
+                return false;
+            };
+            
+            let func_node = match &nodes[owner.base.type_idx as usize] {
+                tg_schema::TypeNode::Function { data, .. } => data,
+                _ => return false,
+            };
+            
+            let (type_idx, injection) = match self {
+                RP::Input(_) => (func_node.input, owner.injection().cloned()),
+                RP::Output(_) => (func_node.output, None),
+                _ => unreachable!(),
+            };
+            
+            let mut cursor = TypeKeyEx(type_idx, DuplicationKey { injection });
+            for seg in &p.path {
+                match seg.apply_on_schema_node_ex(nodes, cursor) {
+                    Ok(next) => {
+                        if &next == xkey {
+                            return true;
+                        }
+                        cursor = next;
+                    }
+                    Err(_) => return false,
+                }
+            }
+            
+            false
+        }
    }
}

357-390: Optimize resource usage in get_injection

The method creates and initializes an InjectionNode::Parent upfront, potentially wasting resources if the path is empty or processing fails early.

Consider initializing the injection node only when needed and avoiding the repeated creation of default objects.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f565e17 and deff3a4.

⛔ Files ignored due to path filters (5)
  • Cargo.lock is excluded by !**/*.lock
  • src/typegraph/graph/tests/snapshots/expanded__expanded_graph-2.snap is excluded by !**/*.snap
  • src/typegraph/graph/tests/snapshots/expanded__expanded_graph-3.snap is excluded by !**/*.snap
  • src/typegraph/graph/tests/snapshots/expanded__expanded_graph-4.snap is excluded by !**/*.snap
  • src/typegraph/graph/tests/snapshots/expanded__expanded_graph.snap is excluded by !**/*.snap
📒 Files selected for processing (5)
  • src/metagen/src/client_py/selections.rs (2 hunks)
  • src/typegraph/graph/Cargo.toml (1 hunks)
  • src/typegraph/graph/src/conv/map.rs (1 hunks)
  • src/typegraph/graph/src/path.rs (1 hunks)
  • src/typegraph/graph/tests/expanded.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/typegraph/graph/src/conv/map.rs
🧰 Additional context used
🧬 Code Definitions (3)
src/typegraph/graph/tests/expanded.rs (7)
src/typegraph/graph/src/conv/map.rs (1)
  • new (85-93)
src/typegraph/graph/src/types/function.rs (2)
  • output (38-40)
  • tag (59-61)
src/typegraph/graph/src/types/mod.rs (3)
  • name (114-114)
  • name (130-136)
  • tag (102-102)
src/typegraph/schema/src/lib.rs (1)
  • name (152-157)
src/typegraph/graph/src/types/object.rs (1)
  • tag (49-51)
src/typegraph/graph/src/types/optional.rs (1)
  • tag (28-30)
src/typegraph/graph/src/types/list.rs (1)
  • tag (27-29)
src/typegraph/graph/src/path.rs (6)
src/typegraph/graph/src/lib.rs (2)
  • try_from (48-55)
  • try_from (85-87)
src/typegraph/graph/src/types/object.rs (3)
  • tag (49-51)
  • base (45-47)
  • children (53-55)
src/typegraph/graph/src/types/function.rs (5)
  • tag (59-61)
  • base (55-57)
  • children (63-65)
  • input (26-28)
  • output (38-40)
src/typegraph/graph/src/types/optional.rs (3)
  • tag (28-30)
  • base (24-26)
  • children (32-34)
src/typegraph/graph/src/types/union.rs (3)
  • tag (29-35)
  • base (25-27)
  • children (37-39)
src/typegraph/graph/src/conv/key.rs (1)
  • fmt (12-14)
src/metagen/src/client_py/selections.rs (4)
src/metagen/src/client_py/mod.rs (3)
  • render (146-158)
  • new (49-53)
  • new (120-142)
src/metagen/src/shared/manifest.rs (2)
  • get_reference_expr (22-22)
  • with_extras (53-59)
src/metagen/src/shared/client.rs (1)
  • selection_for_field (43-83)
src/typegraph/graph/src/types/union.rs (1)
  • variants (17-21)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: test-full
  • GitHub Check: bulid-docker (linux/amd64, custom-ubuntu-large)
  • GitHub Check: lint-compat (macos-14, aarch64-apple-darwin, false)
  • GitHub Check: lint-compat (macos-13, x86_64-apple-darwin, false)
  • GitHub Check: pre-commit
🔇 Additional comments (12)
src/metagen/src/client_py/selections.rs (3)

12-16: LGTM: Clean, well-structured data model.

The Extras struct and PySelectionsPage type alias provide a clear foundation for the Python selection rendering system.


18-40: LGTM: Well-designed polymorphic approach with PySelection enum.

The enum with ManifestEntry implementation provides a clean abstraction for handling different selection types, making the code more maintainable and extensible.


143-213: LGTM: Well-structured construction of PySelectionsPage.

The new method for PySelectionsPage is well-designed, handling the different type cases appropriately and constructing a clean representation of selections for Python code generation.

src/typegraph/graph/Cargo.toml (1)

1-16: LGTM: Well-structured Cargo.toml for a new crate

The Cargo.toml file is properly configured with all necessary dependencies for the new typegraph crate. Using workspace-level configuration for versions and edition is a good practice to maintain consistency across the project.

src/typegraph/graph/tests/expanded.rs (1)

8-55: LGTM: Comprehensive snapshot testing implementation

The test successfully implements snapshot testing for various components of the expanded typegraph, addressing the previous reviewer's suggestion. The test properly exercises the conversion from schema to typegraph and captures the structure of namespace objects, functions, input types, and output types.

src/typegraph/graph/src/path.rs (7)

11-19: LGTM: Clean path segment structure

The Path type alias and PathSegment enum provide a clear representation of paths within the typegraph, with appropriate variants for different path segment types.


34-82: LGTM: Well-typed path segment application with good error handling

The apply method properly handles type checking for each path segment variant with descriptive error messages.


181-198: Add a fast-fail check for empty paths in to_indices

Consider adding a fast-fail check at the beginning of the method to handle empty paths more efficiently.

pub fn to_indices(&self, root_type: Type, schema: &tg_schema::Typegraph) -> Result<Vec<u32>> {
    let mut ty = root_type.idx();
    let mut acc = vec![ty];
+    if self.path.is_empty() {
+        return Ok(acc);
+    }
    for seg in &self.path {
        ty = seg.apply_on_schema_node(&schema.types, ty)?;
        acc.push(ty);
    }
    Ok(acc)
}

392-427: Improve error messages for path segment operations

The error messages when pushing unexpected segments could be more descriptive to aid in debugging.

pub(crate) fn push(&self, segment: PathSegment) -> Result<Self> {
    Ok(match self {
        Self::NsObject(path) => {
            let mut path = path.clone();
            match segment {
                PathSegment::ObjectProp(key) => {
                    path.push(key);
                    Self::NsObject(path)
                }
-                _ => bail!("unexpected segment pushed on namespace {:?}", segment),
+                _ => bail!("unexpected segment '{:?}' pushed on namespace path {:?}", segment, path),
            }
        }
        // ...similar changes for other match arms...
        Self::Function(_) => {
-            bail!("unexpected segment pushed on function {:?}", segment);
+            bail!("unexpected segment '{:?}' pushed on function reference - function paths cannot be extended", segment);
        }
    })
}

429-494: LGTM: Good implementation of path manipulation with edges

The push_edge method effectively handles different kinds of edges according to the source path type. Error messages are clear and the handling of edge kinds is thorough.


234-243: LGTM: Clear implementation of value type path conversion

The TryFrom<RelativePath> for ValueTypePath correctly handles input and output paths while rejecting other path types.


147-176: LGTM: Effective handling of injection data in path traversal

The apply_on_schema_node_ex and apply_on_injection methods provide good support for dealing with injections during path operations.

Comment on lines +42 to +89
#[derive(Debug)]
pub struct ObjectProp {
name: String,
select_ty: SelectionTy,
}

#[derive(Debug)]
pub struct Object {
pub name: String,
pub props: Vec<ObjectProp>,
}

impl Object {
pub fn render(&self, dest: &mut impl Write, page: &PySelectionsPage) -> std::fmt::Result {
let ty_name = &self.name;
writeln!(dest, r#"{ty_name} = typing.TypedDict("{ty_name}", {{"#)?;
writeln!(dest, r#" "_": SelectionFlags,"#)?;
for (name, select_ty) in props {
for prop in self.props.iter() {
let name = &prop.name;
use SelectionTy::*;
match select_ty {
match &prop.select_ty {
Scalar => writeln!(dest, r#" "{name}": ScalarSelectNoArgs,"#)?,
ScalarArgs { arg_ty } => {
let arg_ty = page.extras.input_types.get(arg_ty).unwrap();
writeln!(dest, r#" "{name}": ScalarSelectArgs["{arg_ty}"],"#)?
}
Composite { select_ty } => writeln!(
dest,
r#" "{name}": CompositeSelectNoArgs["{select_ty}"],"#
)?,
CompositeArgs { arg_ty, select_ty } => writeln!(
dest,
r#" "{name}": CompositeSelectArgs["{arg_ty}", "{select_ty}"],"#
)?,
Composite { select_ty } => {
let select_ty = page.get_ref(select_ty).unwrap();
writeln!(
dest,
r#" "{name}": CompositeSelectNoArgs["{select_ty}"],"#
)?
}
CompositeArgs { arg_ty, select_ty } => {
let arg_ty = page.extras.input_types.get(arg_ty).unwrap();
let select_ty = page.get_ref(select_ty).unwrap();
writeln!(
dest,
r#" "{name}": CompositeSelectArgs["{arg_ty}", "{select_ty}"],"#
)?
}
};
}
writeln!(dest, "}}, total=False)")?;
writeln!(dest)?;
Ok(())
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling for unwrap calls in the Object renderer.

The current implementation unwraps results without proper error handling in several places, which could lead to runtime panics if the expected types are not found.

     match &prop.select_ty {
         Scalar => writeln!(dest, r#"    "{name}": ScalarSelectNoArgs,"#)?,
         ScalarArgs { arg_ty } => {
-            let arg_ty = page.extras.input_types.get(arg_ty).unwrap();
+            let arg_ty = page.extras.input_types.get(arg_ty)
+                .ok_or_else(|| format!("Missing input type for arg_ty: {:?}", arg_ty))?;

             writeln!(dest, r#"    "{name}": ScalarSelectArgs["{arg_ty}"],"#)?
         }
         Composite { select_ty } => {
-            let select_ty = page.get_ref(select_ty).unwrap();
+            let select_ty = page.get_ref(select_ty)
+                .ok_or_else(|| format!("Missing selection type reference for select_ty: {:?}", select_ty))?;
              ...
         }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +245 to +264
impl std::fmt::Debug for RelativePath {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Function(idx) => write!(f, "Function({})", idx),
Self::NsObject(path) => write!(f, "NsObject(/{:?})", path.join("/")),
Self::Input(k) => write!(
f,
"Input(fn={}; {:?})",
k.owner.upgrade().expect("no strong pointer for type").idx(),
k.path
),
Self::Output(k) => write!(
f,
"Output(fn={}; {:?})",
k.owner.upgrade().expect("no strong pointer for type").idx(),
k.path
),
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Handle potential panics in Debug implementation

The current implementation of Debug for RelativePath uses expect when upgrading weak references, which could panic if the reference is dropped.

impl std::fmt::Debug for RelativePath {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Function(idx) => write!(f, "Function({})", idx),
            Self::NsObject(path) => write!(f, "NsObject(/{:?})", path.join("/")),
            Self::Input(k) => write!(
                f,
-                "Input(fn={}; {:?})",
-                k.owner.upgrade().expect("no strong pointer for type").idx(),
+                "Input(fn={}; {:?})",
+                k.owner.upgrade().map_or_else(|| "<dropped>".to_string(), |owner| owner.idx().to_string()),
                k.path
            ),
            Self::Output(k) => write!(
                f,
-                "Output(fn={}; {:?})",
-                k.owner.upgrade().expect("no strong pointer for type").idx(),
+                "Output(fn={}; {:?})",
+                k.owner.upgrade().map_or_else(|| "<dropped>".to_string(), |owner| owner.idx().to_string()),
                k.path
            ),
        }
    }
}
📝 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
impl std::fmt::Debug for RelativePath {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Function(idx) => write!(f, "Function({})", idx),
Self::NsObject(path) => write!(f, "NsObject(/{:?})", path.join("/")),
Self::Input(k) => write!(
f,
"Input(fn={}; {:?})",
k.owner.upgrade().expect("no strong pointer for type").idx(),
k.path
),
Self::Output(k) => write!(
f,
"Output(fn={}; {:?})",
k.owner.upgrade().expect("no strong pointer for type").idx(),
k.path
),
}
}
}
impl std::fmt::Debug for RelativePath {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Function(idx) => write!(f, "Function({})", idx),
Self::NsObject(path) => write!(f, "NsObject(/{:?})", path.join("/")),
Self::Input(k) => write!(
f,
"Input(fn={}; {:?})",
k.owner.upgrade().map_or_else(|| "<dropped>".to_string(), |owner| owner.idx().to_string()),
k.path
),
Self::Output(k) => write!(
f,
"Output(fn={}; {:?})",
k.owner.upgrade().map_or_else(|| "<dropped>".to_string(), |owner| owner.idx().to_string()),
k.path
),
}
}
}

Comment on lines +200 to +223
impl PartialEq for ValueTypePath {
fn eq(&self, other: &Self) -> bool {
let left = self.owner.upgrade().expect("no strong pointer for type");
let right = other.owner.upgrade().expect("no strong pointer for type");

self.branch == other.branch
&& left.base.type_idx == right.base.type_idx
&& self.path == other.path
}
}

impl Eq for ValueTypePath {}

impl Hash for ValueTypePath {
fn hash<H: Hasher>(&self, state: &mut H) {
self.owner
.upgrade()
.expect("no strong pointer for type")
.base
.type_idx
.hash(state);
self.path.hash(state);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider using a safer implementation for PartialEq and Hash

The current implementation panics with expect("no strong pointer for type") if the weak reference can't be upgraded. This might lead to runtime failures if the referenced object has been dropped.

impl PartialEq for ValueTypePath {
    fn eq(&self, other: &Self) -> bool {
-        let left = self.owner.upgrade().expect("no strong pointer for type");
-        let right = other.owner.upgrade().expect("no strong pointer for type");
+        let Some(left) = self.owner.upgrade() else {
+            return self.branch == other.branch && other.owner.upgrade().is_none() && self.path == other.path;
+        };
+        let Some(right) = other.owner.upgrade() else {
+            return false;
+        };

        self.branch == other.branch
            && left.base.type_idx == right.base.type_idx
            && self.path == other.path
    }
}

impl Hash for ValueTypePath {
    fn hash<H: Hasher>(&self, state: &mut H) {
-        self.owner
-            .upgrade()
-            .expect("no strong pointer for type")
-            .base
-            .type_idx
-            .hash(state);
+        if let Some(owner) = self.owner.upgrade() {
+            owner.base.type_idx.hash(state);
+        } else {
+            // Use a sentinel value for dropped owners
+            u32::MAX.hash(state);
+        }
        self.path.hash(state);
    }
}
📝 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
impl PartialEq for ValueTypePath {
fn eq(&self, other: &Self) -> bool {
let left = self.owner.upgrade().expect("no strong pointer for type");
let right = other.owner.upgrade().expect("no strong pointer for type");
self.branch == other.branch
&& left.base.type_idx == right.base.type_idx
&& self.path == other.path
}
}
impl Eq for ValueTypePath {}
impl Hash for ValueTypePath {
fn hash<H: Hasher>(&self, state: &mut H) {
self.owner
.upgrade()
.expect("no strong pointer for type")
.base
.type_idx
.hash(state);
self.path.hash(state);
}
}
impl PartialEq for ValueTypePath {
fn eq(&self, other: &Self) -> bool {
let Some(left) = self.owner.upgrade() else {
return self.branch == other.branch && other.owner.upgrade().is_none() && self.path == other.path;
};
let Some(right) = other.owner.upgrade() else {
return false;
};
self.branch == other.branch
&& left.base.type_idx == right.base.type_idx
&& self.path == other.path
}
}
impl Eq for ValueTypePath {}
impl Hash for ValueTypePath {
fn hash<H: Hasher>(&self, state: &mut H) {
if let Some(owner) = self.owner.upgrade() {
owner.base.type_idx.hash(state);
} else {
// Use a sentinel value for dropped owners
u32::MAX.hash(state);
}
self.path.hash(state);
}
}

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

♻️ Duplicate comments (3)
src/metagen/src/fdk_rs/types.rs (2)

274-282: ⚠️ Potential issue

Missing cyclic reference handling for optional types

The TODO comments indicate that cyclic reference handling is still needed. This is important for preventing infinite recursion in type definitions where a type refers to itself directly or indirectly.

Implement the cyclic reference detection logic based on the previous implementation mentioned in the PR comments. The is_path_unfortunately_cyclic logic from the previous implementation should be adapted for the new structure.


186-200: 🛠️ Refactor suggestion

Container definition needs cyclic reference handling

The container_def method is straightforward but doesn't handle cyclic type references, which could lead to infinite recursion in generated code.

Consider implementing detection logic similar to the previously mentioned is_path_unfortunately_cyclic function to break cycles with appropriate boxing. This is especially important for self-referential data structures.

src/typegraph/graph/src/policies.rs (1)

36-49: 🛠️ Refactor suggestion

Avoid potential panic with .expect("policy index out of bounds").

Use safe indexing to handle unexpected out-of-range values. This helps keep the application robust against malformed or changing schemas.

-    .map(|i| self.get(i as usize).expect("policy index out of bounds"))
+    .and_then(|i| self.get(i as usize))
🧹 Nitpick comments (21)
src/typegraph/graph/src/types/union.rs (4)

9-14: Missing documentation for the UnionType struct

The struct definition lacks documentation comments explaining its purpose and the meaning of its fields. Particularly, the semantic difference between either being true or false (resulting in different tags) is not explained, which could make maintenance more challenging for new contributors.

Consider adding documentation like this:

 #[derive(Debug)]
+/// Represents a union type in the typegraph.
+/// A union type can represent one of several possible variant types.
 pub struct UnionType {
+    /// Base type information
     pub base: TypeBase,
+    /// Lazily initialized vector of possible variant types
     pub(crate) variants: Once<Vec<Type>>,
+    /// When true, represents an "either" type; otherwise a "union" type.
+    /// Either types have different semantics than union types in that...
     pub either: bool,
 }

17-21: Consider more robust error handling for variants access

Using expect will panic if variants are uninitialized. While this makes sense during development, consider using a more graceful approach for error handling that provides context without panicking.

 pub fn variants(&self) -> &[Type] {
-    self.variants
-        .get()
-        .expect("variants uninitialized on union")
+    self.variants.get().unwrap_or_else(|| {
+        // Log the error first
+        log::error!("Attempted to access uninitialized variants on union type: {:?}", self.base);
+        // Still panic in this case, but with better diagnostic information
+        panic!("Critical error: variants uninitialized on union type: {:?}", self.base);
+    })
 }

29-35: Document the semantic difference between "either" and "union" tags

The code distinguishes between "either" and "union" tags based on the either field, but there are no comments explaining the semantic difference between these two types of unions.

 fn tag(&self) -> &'static str {
+    // "either" types represent exclusive unions where only one variant can be valid
+    // while "union" types represent inclusive unions where multiple variants can match
     if self.either {
         "either"
     } else {
         "union"
     }
 }

37-39: Potential optimization for children method

The current implementation clones the entire vector of variants. If this vector could be large, this might be inefficient.

Consider returning an iterator instead of cloning the vector:

-fn children(&self) -> Vec<Type> {
-    self.variants().to_vec()
+fn children(&self) -> Vec<Type> {
+    self.variants().iter().cloned().collect()
 }

Or if the trait allows it, consider changing the return type to avoid the clone altogether:

fn children(&self) -> &[Type] {
    self.variants()
}
src/metagen/src/fdk_rs/types.rs (3)

245-377: Consider breaking down the large new method

The new method is quite complex and handles many different type cases. This makes it harder to maintain and understand.

Consider refactoring this into smaller, focused methods for each major type category:

-    fn new(ty: &Type, partial: bool) -> RustType {
+    fn new(ty: &Type, partial: bool) -> RustType {
+        if type_body_required(ty) {
+            let name = normalize_type_title(&ty.name());
+            match ty {
+                Type::Boolean(_) | Type::Integer(_) | Type::Float(_) | Type::String(_) | Type::File(_) => 
+                    Self::new_primitive(ty, name),
+                Type::Optional(ty) => Self::new_optional(ty, name, partial),
+                Type::List(ty) => Self::new_list(ty, name, partial),
+                Type::Object(ty) => Self::new_object(ty, partial),
+                Type::Union(ty) => Self::new_union(ty, partial),
+                Type::Function(_) => unreachable!("unexpected function type"),
+            }
+        } else {
+            Self::new_inline_primitive(ty)
+        }
+    }
+
+    fn new_primitive(ty: &Type, name: String) -> RustType {
+        match ty {
+            Type::Boolean(_) => RustType::builtin("bool", Some(name)),
+            Type::Integer(_) => RustType::builtin("i64", Some(name)),
+            // ... other primitive types
+        }
+    }

This would make the code more maintainable and easier to understand.


1016-1021: Remove or update commented-out test code

There's commented-out code that appears to be a TODO related to transitioning from the old RustTypeRenderer to the new RustType enum.

Either remove this commented-out code if it's no longer needed, or update it to properly test the new implementation.


116-116: Consider more robust error handling than unwrap()

Using unwrap() can lead to runtime panics if an error occurs.

Consider propagating errors with the ? operator or handling them explicitly for better error management:

-    let mut ty_ref = page.get_ref(&prop.ty).unwrap();
+    let mut ty_ref = page.get_ref(&prop.ty).ok_or_else(|| 
+        format!("Failed to get reference for type key: {:?}", prop.ty))?;

Also applies to: 144-144

tests/runtimes/wasm_wire/rust/fdk.rs (2)

327-331: Validate redundant usage of ..Entity() in RootRandomFn.
Similar to HundredRandom, RootRandomFn relies on ..Entity(). Confirm that RootRandomFn truly requires the same sub-node structure as Entity, or consider creating a distinct shape if different fields are needed.


291-293: Consider explicit naming for sub-fields.
Using scalar for name and age ensures these fields map to a simple scalar type. However, if these sub-fields must be specialized or restricted in the future, you may want to adopt more specific field definitions.

src/metagen/src/shared/node_metas.rs (6)

12-14: Consider adding documentation for the MetaFactory trait

This trait seems to be central to building metadata for different types in various language clients. Adding clear documentation explaining its purpose and how it should be implemented would improve maintainability and make it easier for new contributors to understand the code.

+/// A trait for building metadata of type `M` from a `Type`.
+///
+/// Implementations of this trait are used to build metadata for different languages
+/// (Python, TypeScript, Rust) in the client code generation process.
 pub trait MetaFactory<M> {
+    /// Constructs metadata of type `M` from the given `Type`.
     fn build_meta(&self, ty: Type) -> M;
 }

16-19: Document the purpose of MetasPageBuilder

Adding documentation for the MetasPageBuilder struct would help clarify its role in the typegraph expansion process, which appears central to this PR's purpose.

+/// A builder for constructing a `ManifestPage` of metadata entries.
+///
+/// This builder maintains a stack of types to process and builds metadata entries
+/// for each type using the `MetaFactory` trait implementation.
 pub struct MetasPageBuilder {
     pub tg: Arc<Typegraph>,
     stack: RefCell<Vec<Type>>,
 }

36-65: Simplify the build method with a while-let loop

The current implementation uses a loop with explicit conditional checks. Using a while let approach would be more idiomatic in Rust and improve readability.

 pub fn build<M>(self) -> ManifestPage<M>
 where
     M: ManifestEntry<Extras = ()>,
     Self: MetaFactory<M>,
 {
     let mut map = IndexMap::new();

-    loop {
-        let next = {
-            let mut stack = self.stack.borrow_mut();
-            stack.pop()
-        };
-
-        if let Some(ty) = next {
-            if map.contains_key(&ty.key()) {
-                continue;
-            }
-            map.insert(ty.key(), self.build_meta(ty.clone()));
-        } else {
-            break;
-        }
-    }
+    while let Some(ty) = self.stack.borrow_mut().pop() {
+        if !map.contains_key(&ty.key()) {
+            map.insert(ty.key(), self.build_meta(ty.clone()));
+        }
+    }

     let res: ManifestPage<M> = map.into();
     res.cache_references();

     res
 }

62-62: Document the purpose of caching references

It's not immediately clear why the references need to be cached. Adding a comment explaining the purpose of cache_references() would improve code clarity.

 let res: ManifestPage<M> = map.into();
+// Cache references to ensure fast lookups when the manifest is used later
 res.cache_references();

22-30: Add error handling documentation

The method returns a Result, but there's no documentation about potential error scenarios. Adding this information would help users understand when this method might fail.

+/// Creates a new `MetasPageBuilder` from a typegraph.
+///
+/// # Errors
+///
+/// Returns an error if any root function in the typegraph cannot be retrieved.
 pub fn new(tg: Arc<Typegraph>) -> Result<Self> {
     let mut stack = vec![];
     for root_fn in tg.root_functions() {
         let (_, func_ty) = root_fn?;
         stack.push(func_ty.wrap());
     }
     let stack = RefCell::new(stack);
     Ok(Self { tg, stack })
 }

4-8: Consider using a more specific import for TypeNodeExt

The import statement uses a trailing underscore TypeNodeExt as _, which means the trait is imported but not directly used. It's likely being used for its extension methods, but this could be confusing. Consider either using a more direct import or adding a comment explaining why this trait is needed.

 use std::cell::RefCell;

-use typegraph::TypeNodeExt as _;
+// Import TypeNodeExt for its extension methods on Type
+use typegraph::TypeNodeExt;

 use crate::interlude::*;
src/typegraph/graph/src/conv/mod.rs (4)

42-45: Expand documentation for TypeConversionResult trait.

Provide a brief description of how it integrates with the rest of the conversion pipeline and clarify potential failure modes of finalize, especially if a child conversion fails.


47-63: Consider clarifying the name of FinalizedTypeConversion.

The name is accurate but still might confuse new contributors. A more expressive name (e.g., CachedOrLeafConversion) could better convey its purpose as a terminal or cached conversion result.


153-197: Beware of deep recursion in register_converted_type.

The logic to handle recursively registered value types can grow deep for large or cyclical schemas, potentially risking excessive recursion depth. An iterative approach, or detection of cycles earlier, might reduce the risk.


348-364: Document injection handling in base method.

It may not be obvious how rpath.get_injection(schema) works. Documenting the injection flow and usage would improve code readability.

src/typegraph/graph/src/policies.rs (2)

6-10: Add doc comments to PolicyNode.

Explaining how materializers and policy naming interact here will help newcomers.


14-20: Provide usage examples for ConditionalPolicy.

Brief examples of how each optional policy slot is combined at runtime would help clarify usage for new collaborators.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between deff3a4 and f487258.

📒 Files selected for processing (7)
  • src/metagen/src/client_py/static/client.py (1 hunks)
  • src/metagen/src/fdk_rs/types.rs (24 hunks)
  • src/metagen/src/shared/node_metas.rs (1 hunks)
  • src/typegraph/graph/src/conv/mod.rs (1 hunks)
  • src/typegraph/graph/src/policies.rs (1 hunks)
  • src/typegraph/graph/src/types/union.rs (1 hunks)
  • tests/runtimes/wasm_wire/rust/fdk.rs (13 hunks)
🧰 Additional context used
🧬 Code Definitions (4)
src/typegraph/graph/src/types/union.rs (7)
src/typegraph/graph/src/types/optional.rs (2)
  • base (24-26)
  • tag (28-30)
src/typegraph/graph/src/types/list.rs (2)
  • base (23-25)
  • tag (27-29)
src/typegraph/graph/src/types/file.rs (2)
  • base (17-19)
  • tag (21-23)
src/typegraph/graph/src/types/float.rs (2)
  • base (19-21)
  • tag (23-25)
src/typegraph/graph/src/types/integer.rs (2)
  • base (19-21)
  • tag (23-25)
src/typegraph/graph/src/types/string.rs (2)
  • base (19-21)
  • tag (23-25)
src/typegraph/graph/src/types/boolean.rs (2)
  • base (14-16)
  • tag (18-20)
src/metagen/src/shared/node_metas.rs (6)
src/metagen/src/client_ts/node_metas.rs (1)
  • build_meta (185-198)
src/metagen/src/client_rs/node_metas.rs (1)
  • build_meta (206-219)
src/metagen/src/client_py/node_metas.rs (1)
  • build_meta (189-202)
src/metagen/src/client_ts/mod.rs (2)
  • new (59-83)
  • new (92-96)
src/metagen/src/client_rs/mod.rs (2)
  • new (69-112)
  • new (121-125)
src/metagen/src/client_py/mod.rs (2)
  • new (49-53)
  • new (120-142)
src/typegraph/graph/src/conv/mod.rs (7)
src/typegraph/graph/src/policies.rs (1)
  • convert_policy (28-34)
src/typegraph/graph/src/runtimes.rs (1)
  • convert_materializer (19-27)
src/typegraph/graph/src/types/list.rs (2)
  • convert_list (44-66)
  • base (23-25)
src/typegraph/graph/src/types/object.rs (2)
  • convert_object (69-91)
  • base (45-47)
src/typegraph/graph/src/types/optional.rs (2)
  • convert_optional (45-65)
  • base (24-26)
src/typegraph/graph/src/types/union.rs (2)
  • convert_union (54-75)
  • base (25-27)
src/typegraph/graph/src/conv/map.rs (1)
  • new (85-93)
src/metagen/src/fdk_rs/types.rs (2)
src/metagen/src/utils.rs (1)
  • indent_lines_into (167-180)
src/metagen/src/shared/types.rs (1)
  • type_body_required (23-38)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: test-full
  • GitHub Check: bulid-docker (linux/amd64, custom-ubuntu-large)
  • GitHub Check: lint-compat (macos-14, aarch64-apple-darwin, false)
  • GitHub Check: lint-compat (macos-13, x86_64-apple-darwin, false)
  • GitHub Check: pre-commit
🔇 Additional comments (16)
src/metagen/src/client_py/static/client.py (1)

670-671: Improved error handling for content-type check.

This change enhances the robustness of the response handling by explicitly checking for a None content-type before checking if it starts with "application/json". This prevents potential AttributeError that could occur when the response headers don't include a content-type header.

src/typegraph/graph/src/types/union.rs (2)

54-75: LGTM: Well-structured conversion function

The convert_union function follows a consistent pattern with good error handling and proper memory management through Arc. It correctly initializes the UnionType with default variants and returns a conversion result that will be finalized later.


88-106: Well-implemented finalization with robust error handling

The finalization process for union types is thorough, converting each variant type and handling potential errors. The error message for attempting to set variants more than once is particularly informative, including the type key for easier debugging.

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

31-49: Well-structured RustType enum definition

The new RustType enum with its three variants (Alias, Struct, Enum) provides a clear and flexible structure for representing different Rust types. This approach improves type safety and makes the code more maintainable compared to the previous implementation.


392-396: Well-designed manifest structure

The RustTypesSubmanifest struct with separate fields for inputs, outputs, and partial outputs provides a clear structure for managing different types of generated code.

tests/runtimes/wasm_wire/rust/fdk.rs (3)

281-284: Double-check reuse of Entity structure in HundredRandom.
You are reusing ..Entity() in pub fn HundredRandom(). Ensure that this shape (inherited fields for name, age, profile) aligns with the intended semantics for a “hundred random” node.


382-389: Ensure float-to-integer conversions are safe.
AddArgsAFloat is defined as f64, while AddOutput is an i64. This may lead to potential precision loss or domain errors if the logic involves large float values. Please confirm that this numeric mismatch is intentional and sufficiently tested.


529-545: Confirm feasibility of returning partial outputs.
The record() method returns RecordCreationOutputPartial. Verify that downstream consumers can handle partial Entity objects (e.g., EntityPartial) without unexpected errors. In particular, check if partial data is intended or if you need a fully populated struct.

src/metagen/src/shared/node_metas.rs (1)

44-58:

❓ Verification inconclusive

Consider processing child types

Based on a previous review comment, there might have been logic for processing child types that was commented out. If handling of child types is necessary for the expanded typegraph, consider reintroducing this logic.


🏁 Script executed:

#!/bin/bash
# Check if there were previous implementations that processed child types
rg "children\(\)" --type rust -A 5 -B 5 src/metagen/

Length of output: 54


Re: Verify Processing of Child Types
I ran a search for children() across the src/metagen/ directory and found no evidence—either active or commented-out—of logic handling child types. This suggests that any previous approach for iterating over or processing child types has been removed.

Please verify if the expanded typegraph now requires support for child types. If such processing is needed, you should implement the necessary logic; otherwise, the current implementation is acceptable.

src/typegraph/graph/src/conv/mod.rs (6)

30-40: Add field-level documentation for Conversion struct.

These fields form the core of the type conversion process, but readers unfamiliar with the codebase might struggle to understand each field’s purpose. Adding a short explanation for each field will improve maintainability and clarity for new contributors.


65-91: Initialization logic looks good.

The function gracefully converts runtimes, materializers, and policies from the schema. No obvious bugs or vulnerabilities stand out.


199-202: Consider renaming register_type_2 for clarity.

A more descriptive name (e.g., register_type_with_duplicate_handling) could clarify how it differs from register_type.


214-221: Add more context to the function name.

Renaming register_type to better reflect its uniqueness or purpose would align with the existing patterns in the codebase.


223-346: Handle the unreachable!() scenario safely.

Even if Any is currently unused in schemas, leaving unreachable!() might cause panic if the code changes in the future. Consider returning an error or logging instead.

Would you like a verification script to find all references to N::Any across the codebase to ensure it is never created at runtime?


366-372: Policy conversion logic is consistent.

This cohesive approach to handling policies integrates well with convert_policy_spec.

src/typegraph/graph/src/policies.rs (1)

28-34: Validate policy.materializer index safety.

Although indexing is presumably consistent with the schema, consider verifying or gracefully handling an out-of-bounds materializer index to prevent panics.

@@ -116,7 +116,7 @@ impl Router {
}

pub fn init(&self, args: InitArgs) -> Result<InitResponse, InitError> {
static MT_VERSION: &str = "0.5.1-rc.0";
static MT_VERSION: &str = "0.5.1-rc.1";
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Confirm version alignment.
The fixed version string has been updated to "0.5.1-rc.1". If version-based checks or downstream builds rely on this constant, please ensure all references are consistently updated across the codebase.

Run the following script to search for other version references that may still use the old value:


🏁 Script executed:

#!/bin/bash
rg "0\.5\.1-rc\.0"

Length of output: 210


Action Required: Align All Version References

The update to "0.5.1-rc.1" in tests/runtimes/wasm_wire/rust/fdk.rs is incomplete. The following files still reference the old version "0.5.1-rc.0":

  • tests/runtimes/wasm_reflected/rust/Cargo.lock
  • poetry.lock
  • examples/typegraphs/metagen/rs/fdk.rs

Please update these entries to "0.5.1-rc.1" to ensure consistency across the codebase, as version-based checks or downstream builds might be affected.

Comment on lines +93 to +151
pub fn convert<NE>(
schema: Arc<tg_schema::Typegraph>,
naming_engine: NE,
) -> Result<crate::Typegraph>
where
NE: NamingEngine,
{
let mut conv = Conversion::new(schema.clone());
let mut res = conv.convert_type(
WeakType::Object(Default::default()),
0,
RelativePath::root(),
)?;
let root = res.get_type();
res.finalize(&mut conv)?;

let mut ne = naming_engine;

for idx in 0..schema.types.len() {
match conv
.conversion_map
.direct
.get(idx)
.unwrap_or(&MapItem::Unset)
{
MapItem::Unset => {
bail!("no type for type idx: {}", idx);
}
MapItem::Function(ty) => {
ne.name_function(ty)?;
}
MapItem::Namespace(ty, _) => {
ne.name_ns_object(ty)?;
}
MapItem::Value(types) => {
ne.name_value_types(types)?;
}
}
}

let reg = std::mem::take(ne.registry());
Ok(crate::Typegraph {
schema,
root: root.assert_object()?.clone(),
input_types: conv.input_types,
output_types: conv.output_types,
functions: conv.functions,
namespace_objects: conv.namespace_objects,
named: reg.map,
conversion_map: conv
.conversion_map
.direct
.into_iter()
.map(TryFrom::try_from)
.collect::<Result<Vec<_>>>()?,
runtimes: conv.runtimes,
materializers: conv.materializers,
})
}
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Confirm error handling coverage.

Calling bail! for unset types is appropriate, but consider adding unit tests to verify that any unexpected schema entry triggers this error properly.

Request coverage tests to ensure the error path is reached when type indices are missing.


🏁 Script executed:

#!/bin/bash
# Searching for tests that cover the scenario where no type is found for a given index
rg -A 8 "bail!\(\"no type for type idx:"

Length of output: 699


Unit Test Required for "No Type for Type idx" Error Handling

It appears that no coverage tests exist for the branch that triggers the bail!("no type for type idx: {}", idx); error in src/typegraph/graph/src/conv/mod.rs. Please add unit tests that simulate a missing type entry in the schema to ensure that this error can be properly reached and logged.

  • Location of concern: src/typegraph/graph/src/conv/mod.rs (lines 93-151)
  • Suggested action: Create a test case that intentionally omits a type mapping for a given index to trigger the error condition.

Comment on lines +50 to +61
pub fn convert_policy_spec(policies: &[Policy], spec: &tg_schema::PolicyIndices) -> PolicySpec {
use tg_schema::PolicyIndices as PI;
match spec {
PI::Policy(i) => PolicySpec::Simple(policies[*i as usize].clone()),
PI::EffectPolicies(pp) => PolicySpec::Conditional(ConditionalPolicy {
read: policies.opt_get(pp.read),
create: policies.opt_get(pp.create),
update: policies.opt_get(pp.update),
delete: policies.opt_get(pp.delete),
}),
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Ensure safe array indexing in convert_policy_spec.

Using policies[*i as usize] can similarly provoke a panic if i is invalid. Handle this case more gracefully or confirm the schema always provides valid indices.

Copy link

codecov bot commented Mar 27, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 81.13%. Comparing base (4d1e860) to head (f487258).
Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #978      +/-   ##
==========================================
- Coverage   81.14%   81.13%   -0.01%     
==========================================
  Files         142      143       +1     
  Lines       17970    18048      +78     
  Branches     1961     1965       +4     
==========================================
+ Hits        14581    14643      +62     
- Misses       3371     3387      +16     
  Partials       18       18              

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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