-
Notifications
You must be signed in to change notification settings - Fork 13
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
base: main
Are you sure you want to change the base?
Conversation
📝 WalkthroughWalkthroughThe 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
Sequence Diagram(s)Client Code Generation FlowsequenceDiagram
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
Type Conversion FlowsequenceDiagram
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
Suggested reviewers
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
# Conflicts: # src/metagen/src/fdk_rs/stubs.rs # src/metagen/src/fdk_rs/types.rs # src/metagen/src/tests/fixtures.rs
7a52445
to
af7aa21
Compare
c512910
to
f237e2d
Compare
There was a problem hiding this 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? |
There was a problem hiding this comment.
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?
@Yohe-Am Thanks for your review.
Yes, you can look at the typegraph definition in the tests for the GraphQL namespaces.
There is something missing in the implementation. Will fix that...
I will need to make a full review myself... |
There was a problem hiding this 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 likeimpl_selection_traits!
is a clean approach to avoid boilerplate. Consider fallback logic or an error ifpage.extras.input_types.get(...)
yieldsNone
.- 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 suggestionLook 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 callsunwrap()
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 viaself.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., inclient_rs
,client_py
, andfdk_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 ifnodeSelection
is an instance ofAlias
and, if so, uses itsaliases()
method; otherwise, it wraps the selection in an object keyed bynodeName
. This logic appears sound.Suggestion: If there's any possibility for
nodeSelection
to benull
orundefined
, consider an explicit check or comment to document the assumption.
680-686
: Query Node Inner Value Extraction:
In thebuildGql
call for queries, a conditional is used to distinguish between a singleQueryNode
(usingquery.inner()
) and an object mapping of query nodes (viaObject.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 beQueryNode
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 inMyOutput
.When mapping
(idx, ty)
to(ty.base().title.clone(), idx as u32 + 4)
, duplicatetitle
fields could inadvertently overwrite properties in theproperties
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 FlowThe 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 ofTrue if ... else False
Replace with `bool(...)
(SIM210)
530-530
: Variable Shadowing in LoopsIn 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 ErrorsThe 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-raisingLines 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 originalURLError
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 withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
tests/metagen/typegraphs/identities/ts/fdk.ts (2)
53-58
: Enumerated string type forenum
.
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 inSelectNodeOut
.
Static analysis indicates a redeclaration ofO
. 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 functionThe
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 thedata
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 checkingThe
is_plain()
method uses thematches!
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 implementationThe
format_only()
method correctly implements the logic to return the format only if no other constraints are present. However, similar to the issue inis_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.
Thenew
constructor callsty.injection().cloned()
. Ensure large clones of deeply nestedInjectionNode
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 viarpath.get_injection(schema)
. Provide doc comments specifying when and whyDuplicationKey
is built from paths, especially as it may differ from the direct injection onType
.
42-48
: Document variant meaning.
TheDeduplication
enum differentiates reusing an existing type vs. registering a new one. Consider doc comments or short remarks clarifying situations that lead toReuse
versusRegister
.src/metagen/src/shared/node_metas.rs (3)
8-8
: Potential circular references caution.
Re-exportingcrate::interlude::*
can help unify imports but watch out for cyclical references ifinterlude
in turn references modules that might rely on these items.
10-14
: Clarify the relationship betweenMetaFactory
andManifestEntry
.
MetaFactory
is simply a trait withbuild_meta
. Ensure that implementers fully handle allType
variants. Consider referencing or linkingManifestEntry
uses for a cohesive developer experience.
16-19
: Guard mutable usage ofstack
.
ARefCell<Vec<Type>>
is appropriate if there's no multi-thread concurrency. If concurrency is possible, considerMutex
or removing interior mutability.src/metagen/src/lib.rs (1)
6-6
: Wildcard import usage check.
Usingtypegraph::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 aspub
Confirm whether there is a strong reason to keep the field inInjectionTree
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
Usingor_insert(InjectionNode::Parent { children: BTreeMap::new() })
forces the creation of a newBTreeMap
each time. You can useor_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 onInjectionTree
This function merges twoInjectionTreeMap
s. For discoverability and maintainability, consider implementing it as an associated method onInjectionTree
.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 generatedfdk.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 ofUnion
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
andindent_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 commentsMinor 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 aliasessrc/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 andimpl_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 temporarilytake(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
MarkingScalar
orScalarArgs
asunreachable!()
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
Usingunreachable!()
for theeyre::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 handlesComposite
andCompositeArgs
. 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 forAlias
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 inDerive
.
debug
andserde
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
: RevisitRustType
variant organization for future-proofing.The
enum RustType
is well-structured, but expanding beyondAlias
,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 withinStruct
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 appendPartial
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 nestedBox
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 cyclicalObjectType
logic.If
ObjB
referencesObjC
, 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
: LeverageFrom
or specialized trait forMapItem
conversions.
TryFrom<conv::MapItem>
usesbail!
for invalid states (line 50). You might unify with other conversion patterns (likeFrom<conv::MapItem>
) for simpler code if you’re certain about your domain constraints.
83-103
: Confirm closure oftry_from
schema conversions.Line 86 calls
conv::Conversion::convert(schema, DefaultNamingEngine::default())
. Check thatDefaultNamingEngine
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)
returningRootFnsIter
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 inapply_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 forValueTypePath
.
ValueTypePath
(lines 182–186) couples a reference to theFunctionType
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 inRelativePath
.We have
Function
,NsObject
,Input
,Output
. If we add future top-level concepts (likePolicy
,Runtime
references), ensure we keepRelativePath
general enough or subdivide it for clarity.
264-267
: Clarify usage ofroot
forRelativePath
.
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 aResult
onpop
.
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. AResult
-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.
Thedefault_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 toBTreeMap
inInjectionNode
.
UsingBTreeMap
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 forget_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 callget_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
Storinginput_types
is straightforward. Add doc comments if needed.src/metagen/src/client_py/node_metas.rs (1)
142-142
: Address theTODO
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 ofoutjection: Option<()>
.
UsingOption<()>
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 implementingTypeConversionResult
.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 behaviorCurrently, 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 typesSuffixing
_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 namesWhen calling
.named(name)
, ensurename
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 fieldsThis 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 useNotRequired
. 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 typesWhen constructing an alias for
Optional[...]
, there's a note (TODO) about cyclical references (line 303). If a type references itself through anOptional
, 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
WithinObject::render
, the call topage.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
: Avoidunwrap()
for union variant references
Similar to the object rendering logic, callingpage.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
⛔ 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
toRootUploadFnInput
and direct assignment of the file property (without wrapping inOption
) 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
toRootUploadManyFnInput
and direct assignment of the files vector (without wrapping inOption
) 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 castingvariant_select
to aSelection
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 usingObject.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 thePreparedRequest
constructor, the use ofinstanceof
for detecting ifdryRunNode
is aQueryNode
orMutationNode
is consistent with earlier patterns. The subsequent conditional transformation usingObject.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 foruploadMany
.Providing
inputFiles
ensures GraphQL can handle file arrays properly.
913-922
: Proper argument definition forupload
.The single file input is well-specified, matching the
argumentTypes
field.
928-929
: Type aliases appear consistent.Alias for
FileBf9b7
asFile
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 totypes::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
: FullPost
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 ArgumentsThis block consistently replaces the previous partial types with their complete counterparts (
types::Post
andtypes::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 UnifyingPostPartial
UsageLine 53 still references
types::PostPartial
, while functions above use the fulltypes::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 ConsistencyUsing
types::Post
andtypes::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 InputsThese lines replace partial input types with
RootCompositeArgsFnInput
, ensuring calls toapi1.scalar_union
,composite_union
, andmixed_union
are consistent with full-type requirements. This is a solid improvement in type safety.Also applies to: 124-126, 131-133
172-174
: Usingtypes::Post
in Scalar ArgsSwitching to
types::Post
for thescalar_args
match is consistent with the rest of the codebase’s shift away from partial types. No issues found.
180-181
: Identity Function InputThe 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
: Newtypes
Module IntroductionThese 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 ConfigurationThis addition configures the argument types (
files
andprefix
) with the correct references to their graph type names, and properly listsfiles
as input files. This ensures the GraphQL layer processes file uploads as intended. Looks good.
81-98
:RootUploadFn
Node Meta ConfigurationSimilarly, 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 forfile_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 forupload()
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 forupload_many()
Using
RootUploadManyFnInput
ensures that the function receives the necessaryfiles
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 HandlingEncapsulating 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 OperationsThroughout, the approach of passing typed dicts (
PlaceholderArgs
,PrimitivesArgs
, etc.) with a matching selection structure fosters type safety. Ensure that references likeTransports.hostcall()
are defined in the codebase or imported.
1695-1733
: Handlers for Rust/Python/TypeScript CompositesThese wrapper functions unify user-defined logic with the GraphQL context. The references to
Transports
in lines 1698, 1708, 1718, 1730 appear external. Verify thatTransports
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 toCycles1Args
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 forCycles2
andCycles3
.
This approach for unioning cycle types is consistent. Just confirm usage in your runtime logic.
116-116
: Optional reference withinBranch33ATo1Cycles1Optional
.
Straightforward optional pointer toCycles1
. 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 ofuse 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
andRootIdentityFnInput
.
Both new structs are minimal but clear. Good addition for strongly typed arguments.
49-62
:UserPartial
andPostPartial
.
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 yourroot_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 ofRootIdentityFnInput
plus argument types is aligned. Keep your doc or comments updated if parameters evolve.
152-156
:RootNestedCompositeFn
meta delegating toRootNestedCompositeFnOutput
.
No immediate issues. Ensures consistent nested structures.
157-168
:RootNestedCompositeFnOutput
meta configuration.
Sub-nodes forscalar
,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 fieldinner
. Straightforward.
208-215
:RootMixedUnionFn
meta.
Argument typeid
withstring_e1a43
. No issues flagged.
231-239
:User
node meta expansions.
Mappingid
,posts
to scalar or composite sub-nodes is consistent with your data model.
245-255
:Post
node meta expansions.
Sub-nodes align withPostPartial
. 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 forpost
oruser
are clearly defined. No changes needed.
282-289
:RootScalarUnionFn
meta withid
argument.
No obvious pitfalls. Ties in well with your scalar usage.
292-299
:RootCompositeArgsFn
meta usage.
Tiesid
tostring_e1a43
and reusesPost()
. Straightforward design.
302-306
:RootCompositeNoArgsFn
meta.
Just calls..Post()
. No issues.
307-316
:RootScalarArgsFn
meta.
Arguments forid
,slug
, andtitle
. Reusesscalar()
. All consistent.
319-323
:RootScalarNoArgsFn
meta.
No concerns. Delegates toscalar()
.
325-329
:RootGetPostsFn
node meta.
Simple reuse ofPost()
.
330-333
:RootGetUserFn
node meta.
Simple reuse ofUser()
.
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 theinner
field. Straightforward usage.tests/metagen/typegraphs/sample/ts/client.ts (7)
26-28
: RefinednodeInstances
logic.
Switching based onAlias
helps handle multiple aliases. Clear approach.
30-34
: Expandedfor
block on node instances.
Good readability. Each instance is processed distinctly.
141-144
: Union variant selection logic.
Cleanly extracts variant selections referencingvariant_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.
Usinginstanceof
checks forQueryNode
orMutationNode
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
: AddedArc
import for reference-counted smart pointers.The addition of
Arc
from thestd::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 oneArc
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 2Length 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
: NewBooleanType
implementation follows the type system pattern.The implementation of
BooleanType
follows the consistent pattern seen in other type implementations, with aTypeBase
field and theTypeNode
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
, andFloatType
, which all follow the same pattern of implementing thebase()
andtag()
methods from theTypeNode
trait.src/typegraph/core/src/utils/artifacts.rs (1)
7-7
: Updated error handling imports.The import change to include
ErrorContext
trait andResult
type prepares for the improved error handling implemented below.src/metagen-client-rs/src/nodes.rs (2)
24-29
: New SubNodes enum looks goodThe addition of the
SubNodes
enum with its three variants (None
,Atomic
, andUnion
) 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-designedThe
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 goodThe
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 appropriateThe
TypeNode
trait implementation forArc<FloatType>
follows the expected pattern, providing access to the base type and a static tag identifier.
28-40
: Clean implementation of is_plain methodThe
is_plain
method efficiently uses pattern matching to check if all constraints areNone
, 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 goodThe
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 appropriateThe
TypeNode
trait implementation forArc<FileType>
correctly provides access to the base type and defines the type tag as "file".
27-32
: Efficient is_plain method implementationThe
is_plain
method correctly usesas_ref()
when pattern matching onmime_types
since it's anOption<Vec<String>>
. This approach properly handles the reference without moving the value.tests/metagen/typegraphs/sample/metatype.yml (2)
13-15
: Python client generator disabledThe
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 disabledSimilar 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 itsFrom<&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 BTreeMapThe import statement has been modified to use
BTreeMap
from the standard library instead of the previously importedIndexMap
. 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 aBTreeMap
instead of anIndexMap
. This is a significant change in behavior:
BTreeMap
keeps keys sorted, whileIndexMap
preserves insertion orderBTreeMap
has O(log n) lookup time vs O(1) average-case forIndexMap
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 theres
variable fromIndexMap
toBTreeMap
. 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
orIndexMap
in files referencingInjectionTree
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 syntaxThe import statement has been updated to use the more modern TypeScript syntax for importing types, changing from
import { type Logger }
toimport type { Logger }
. This is a minor syntax improvement that better separates type imports from value imports.
278-281
: Enhanced logging for cached policy resultsThe 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 referencesThe type aliases for
Materializer
andRuntime
asArc<T>
types are appropriate for these shared resources. UsingArc
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 thedata
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 3Length 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 flexibleIndexMap<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 implementationThe
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 implementationThe
TypeNode
trait implementation forArc<StringType>
follows the consistent pattern seen in other type implementations shown in the relevant code snippets. Thebase()
andtag()
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 compilationThe 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 forHostcallBinding
.
16-29
: Clean implementation of the Ctx class with conditional parametersThe
Ctx
class implementation is clean and follows the same structure seen in the test typegraphs. The conditional compilation withmetagen-genif
directives ensures that the appropriate fields are included based on whetherHOSTCALL
is enabled.
31-32
: Simple and effective GQL method implementationThe
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 constraintsThe
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 implementationThe
TypeNode
implementation forArc<IntegerType>
provides straightforward access to the base type and a static type tag. UsingArc
here is appropriate for shared ownership semantics, which aligns with the expanded typegraph approach mentioned in the PR objectives.
28-41
: Efficient is_plain implementationThe
is_plain
method efficiently checks if all constraint fields areNone
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 ArcWrapping the
raw
typegraph in anArc
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 pathsThis 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 classificationThe
is_composite
method provides a thorough classification of types, appropriately handling all variants including recursive types likeOptional
,List
,Union
, andEither
. The method correctly identifies primitive types and handles composite types recursively.There is a placeholder for
Any
types marked withunimplemented!()
, which is appropriate if support for this type is planned for future work.
248-250
: Efficient is_function implementationThe
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 theTypegraph
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 atry
block to provide clearer feedback to maintainers.
438-438
: Typographical fix recognized.Renaming
name: "primtives"
toname: "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 justprintln!
) may catch regressions. This addresses a past suggestion to snapshot test.src/metagen/src/fdk_rs/mod.rs (10)
17-18
: Introduction ofRustTypesConfig
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
: NewMaps
struct introduced.Separating input and output references into
Maps
clarifies code organization. This structure is beneficial for caching.
177-177
: Refactored function signature to acceptArc<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
: InitializingMaps
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 derivingHash
aligns withInjectionNode
usage.
DuplicationKey
is marked#[derive(Hash)]
, which depends onInjectionNode
being hashable in a consistent manner. Verify thatInjectionNode
’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 withInjectionNode::is_empty
.
is_empty
relies oninjection.is_empty()
ortrue
ifNone
. Verify that returningtrue
wheninjection
isNone
is desired in all contexts, or consider returningfalse
forNone
if that better reflects semantics.
36-40
: Leverage directfrom
usage for uniformity.
TheFrom<&Type>
trait is a neat convenience. Make sure all places requiring aDuplicationKey
from a reference toType
consistently use this trait to keep code uniform.
58-96
: Check concurrency assumptions.
deduplicate
reads fromself.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 onConversionMap
, or add synchronization.src/metagen/src/shared/node_metas.rs (3)
6-6
: No immediate concerns.
ImportingTypeNodeExt
is standard. Nothing appears problematic at a glance.
22-30
: Check for potential errors inroot_functions
iteration.
root_functions
returns aResult
, which is unwrapped viaroot_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.
RenamingClienPyGenConfig
toClientPyGenConfig
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 fromIndexMap
toBTreeMap
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 fromIndexMap
toBTreeMap
is consistent with your broader changes.
65-65
:✅ Verification successful
Ensure no ordering assumption in recursive calls
When changing fromIndexMap
toBTreeMap
, 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
orchildren
did not reveal any hidden reliance on insertion order. In the recursive logic (e.g., collecting keys from children insrc/typegraph/core/src/types/type_ref/injection.rs
), the use ofBTreeMap
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 ofFunctionType
andTypeNodeExt
. Confirm usage in place of the olderStubbedFunction
references is fully integrated.
15-17
: Signature updated to use Arc and super::Maps
ReplacingStubbedFunction
withFunctionType
may improve consistency across the codebase.
26-26
: Potential panic from unwrap
Using.unwrap()
onmaps.output.get(...)
can panic if the key is missing. Consider error handling or a descriptive fallback.
27-27
: Title normalization
Usingnormalize_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
Importingmanifest_page
fromtypes
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 callsmanifest_page(&tg)?
and thenmanif.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 withwrap_err_with
Good use ofwrap_err_with
to provide context on failures when filtering stubbed functions.
104-106
: Dynamic type name creation
Usingutils::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
TheAlias
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 ofManifestEntry
forTsType
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 inget_typespec
Appropriately handles each type variant, including enumerations and specialized string formats. The usage oftype_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
: UpdatedSelectionTy
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 inselection_for_field
.The heavy use of recursion for
Optional
,List
, and nestedFunction
outputs might risk deep recursion or edge cases returning another function. Ensure that a function returning another function never occurs in practice (as indicated byunreachable!
). 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
, andpolicies
from the schema is logical. Validate that materializer or policy indices are never out of range for large or unusual schemas.
95-153
: Primaryconvert<NE>
flow may assume type0
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 thatroot.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 ofinterlude
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 toBTreeMap
is intentionalReplacing
IndexMap
withBTreeMap
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 inParent
injection node
InjectionNode::Parent { children }
now uses aBTreeMap
, meaning the iteration overchildren
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 forvalidate_union
Within
validate_union
, thechildren
parameter now leveragesBTreeMap
, 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 consistentThe 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 ofupgrade()
calls in equality & hashing.Within the
Edge
struct, bothPartialEq
andHash
rely onupgrade()
calls. If the underlyingArc
is dropped,upgrade()
will fail. Currently, you invokeexpect("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 handlingNone
.
73-82
: Validate optional injection behavior.
TypeBase
includes aninjection: Option<InjectionNode>
. Ensure that any required validations or post-processing (like special handling of hidden types) are consistently enforced.
84-110
: Structure forType
andTypeNode
is logical.The
Type
enum comprehensively covers the supported types (e.g., Boolean, Float, File, etc.). The defaultchildren()
andedges()
returning empty is a practical fallback for leaf-like types. This design cleanly integrates with the visitor pattern.
170-257
: Use ofWeakType
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 itspath
is beneficial for debugging, logging, or advanced transformations.
54-102
:traverse_types_with_path
ensures consistent visitor flow.The code properly handles the
Stop
orSiblings
signals. The approach is clear and maintainable.
104-161
: Cyclic path detection appears robust.
PathExt::is_cyclic
uses aHashSet
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
, andeither
are succinctly declared. The use ofLazy<Vec<Type>>
is good for deferred initialization.
16-22
: Ensurevariants
are initialized early.
variants()
panics if they’re not set. Confirm that all union types properly finalize their variants before usage.
24-52
: Implementation ofTypeNode
is cohesive.Using
tag()
to differentiate “either” from “union” is concise. Theedges()
method enumerates each variant with an indexed edge, aligning well withEdgeKind::UnionVariant
.
54-75
: Union conversion function is clear.
convert_union
delegates toUnionTypeConversionResult
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 forObject
andUnion
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
TheUnion
struct parallelsObject
closely, keeping design consistent for selection types. No issues spotted.
101-117
: ManifestEntry implementation
ReturningSome(name.clone())
inget_reference_expr
is consistent and straightforward. Good job employing the trait to unify rendering logic.
119-175
: Manifest page creation
Logic for iteratingtg.output_types
and constructing either anObject
orUnion
selection is clear and covers relevant composite types. The earlycontinue
for non-composite or scalar types avoids clutter. Looks solid.src/metagen/src/shared/files.rs (5)
5-5
: Visitor imports
ImportingVisitNext
is correct for traversals. No issues identified.
9-9
: Use ofArc<str>
Moving toArc<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-basedTryFrom
, adding flexibility forVec<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 fromtypegraph
and local modules align well with the expandedRustSelection
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 modelsStruct
vs.Union
. This is a robust design to handle branching logic in rendering.
33-54
: ManifestEntry usage
Implements the trait straightforwardly, returning references viaget_reference_expr
. The approach is cohesive with the rest of the codebase.
160-162
:Extras
struct
Storinginput_types
inIndexMap
is flexible for referencing argument types. No immediate concerns here.
164-227
: Manifest page function
BuildsStruct
orUnion
from composite types. Inclusion ofinput_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 theEnum
variant.The
#[serde(untagged)]
attribute usage is correct, but ensure future expansions (likeadjacently tagged
or explicit discriminants) are handled systematically if more complex tagging is required.
389-477
: Re-examine partial type usage withinoutput_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 forMyEither
.
#[serde(untagged)]
on theMyEither
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 acrossMyEither
andMyUnion
.
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
, andutils
. 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.rsLength 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
, andindent_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 withLazy<T>
.In line 15,
pub type Lazy<T> = std::sync::OnceLock<T>;
is straightforward. Watch for confusion with the standardLazyLock
in Rust if other parts of the code consider alternative lazy initialization approaches.
58-80
: Guard multi-variant usage infind_type
.
match self.conversion_map.get(idx as usize)?
can produceNamespace
,Function
, orValue
. 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 withEdgeKind
definitions.Lines 4–10 reference
EdgeKind, FunctionType, Type
. Ensure that eachEdgeKind
variant you map to or fromPathSegment
is consistently updated when new variants appear, preventing out-of-sync definitions.
161-176
: Gracefully handle non-parent injection nodes.
apply_on_injection
expects aParent
injection node forObjectProp
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 includesxkey
. 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 foritem()
.
UsingLazy<Type>
withOnceLock
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 ofTypeNode
looks solid.
Thechildren
andedges
methods correctly link the optional type to its underlying item. This is consistent with the other type implementations.
45-66
: Check references toconvert_optional
usage.
Everything seems correct for conversion. Confirm that any code callingconvert_optional
provides valid JSON fordefault_value
and that the final result is tested (particularly ifdefault_value
oritem
are absent).
67-96
: Lifecycle management for the optional item is well-handled.
Thefinalize
method properly sets the item once and fails otherwise, which is a good safeguard.src/typegraph/schema/src/types.rs (4)
20-20
: DerivingPartialEq
andEq
forSingleValue
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 additionalPartialEq
andEq
make sense for consistent comparisons of injection data.
224-229
: Use ofBTreeMap
forinjections
andoutjections
inFunctionTypeData
.
The shift fromIndexMap
toBTreeMap
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 theitem()
accessor for concurrency.
Similar to the optional type, verify if multi-threaded usage might require additional synchronization.
22-42
:TypeNode
trait implementation looks consistent.
Thechildren()
andedges()
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 likeunique_items
.
68-96
:ListTypeConversionResult
finalization is robust.
The use ofOnceLock
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.
TheManifestEntry
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 anRwLock<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.
TheFrom<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.
Thewith_extras
function allows specifying additional context, improving the reusability ofManifestPage
. No issues spotted.
65-69
: Proactive reference caching.
Callingget_ref(key)
withincache_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.
Therender_all
function loops through each entry and delegates toManifestEntry::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.
Addingpub mod manifest
andpub mod node_metas
cleanly separates the codebase. Good move for modular design.
13-13
:HashSet
import can reduce duplication.
Using aHashSet
forstubbed_runtimes
streamlines membership checks. This is a neat optimization.
16-16
:FunctionType
import.
BringingFunctionType
into scope is valid for typed function usage; no concerns.
26-28
: Refactored return type.
filter_stubbed_funcs
returningVec<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 instubbed_runtimes
. This logic is clear.
36-36
: ReturningOk(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 importingRustTypesConfig, RustTypesSubmanifest
,RsNodeMeta
, andRustSelectionManifestPage
clarifies dependencies.
43-45
: Manifest instantiation & render.
CreatingRsClientManifest
and rendering it immediately to a buffer is a natural flow. Ensure that all error handling fromrender
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 newQueryGraph
. 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 undermod 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 importingTypeNodeExt
.
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 theheck
usage.
10-10
: Import expansions
References tointerlude
andshared::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 eitherObject
orUnion
. Implementation is solid.src/metagen/src/fdk_py/mod.rs (17)
4-5
: Import statements
No issues with newly introduced imports forfmt::Write
andCow
.
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 exposestypes
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 thefdk.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
Createsfdk.py
with the rendered contents. Good approach.
217-278
: End‐to‐end test
Checks the generated file withruff
. 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.
Callingv.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 5Length of output: 10430
Union variant filtering has been verified as intentional.
The search results indicate that similar filtering logic—usingis_composite()
to exclude non-composite variants—is consistently used across different parts of the codebase (for example, insrc/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.
Thematch
block ends withunreachable!()
, which assumes either atypegraph_name
or atypegraph_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
orClientPyGenConfig.base.typegraph_path
.
239-245
: Consider fallback logic fornode_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 frominjections.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 ofOnceLock
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 removingruntime_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
orBranch4again
asString
andVec<...>
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 inprops
.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 titlesYou rely on
item.ty.title()
to create a unique name. Iftitle()
is empty or uninitialized, the newly registered name might be unclear and lead to potential naming collisions. Consider validating or providing a fallback name whentitle()
is empty.src/typegraph/graph/src/conv/map.rs (3)
84-88
: Check initialization correctness fordirect
direct.resize_with(type_count, || MapItem::Unset);
initializes all slots asUnset
. 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 typesThis 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 inappend
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 fieldsIn lines 277-278, the code sets
(true, true)
for optional typed properties, referencingquote_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, therender
method produces no output forSelf::Scalar
andSelf::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 theSelf::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 ofunwrap()
in function code generation
In theFunction::render
method, the usage ofpage.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
Inbuild_union
, only composite types are inserted into thevariants
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 ofprop.ty.name()
for argument fields
Usingprop.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 usingprop.ty.key()
for unique identification.
@@ -33,7 +31,7 @@ pub mod shared; | |||
|
|||
mod fdk_py; | |||
mod fdk_rs; | |||
mod fdk_substantial; | |||
// mod fdk_substantial; |
There was a problem hiding this comment.
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.
// ( | ||
// "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)) | ||
// }, | ||
// }, | ||
// ), |
There was a problem hiding this comment.
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"); |
There was a problem hiding this comment.
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.
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(()) |
There was a problem hiding this comment.
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.
There was a problem hiding this 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 detailsThe
Typegraph
struct has all fields marked aspub
, 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 codeThe 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, ifitem
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 whenitem
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
returnsNone
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 aTODO
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 relationshipThe
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 processThe
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 structConsider 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 forAliasTarget
.
AliasTarget
might benefit from derivations likeClone
,PartialEq
, orEq
for easier manipulation and testing.#[derive(Debug)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum AliasTarget {
93-105
: Leverage privacy modifiers forObjectProperty
.If
ObjectProperty
is only used internally, consider making itpub(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 eachType
.
- Great handling of
Boolean
,Float
,Integer
, etc.unreachable!()
forType::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
📒 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 standardLazyLock
instead of aliasingOnceLock
You're using
pub type Once<T> = std::sync::OnceLock<T>;
when Rust hasLazyLock
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 typesInclude 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 cleanGood 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-structuredThe
MapItem
enum and itsTryFrom
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 effectiveThe
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 functionalityThe
root_functions
method provides a clean interface for traversing the typegraph, and thename
method is a simple and useful accessor.
105-145
: Root function iterator implementation is thoroughThe 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 insrc/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
andtypegraph.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 theOnce<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 therpath
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
, therpath
is cloned for use in thebase
conversion and then forwarded intact into theUnionTypeConversionResult
.- References in
src/typegraph/graph/src/conv/mod.rs
confirm thatconvert_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
: Validatedefault_value
or clarify its usage.
Whiledefault_value
is being propagated into theOptionalType
, there's no validation or usage context shown here. Consider verifying thatdefault_value
is compatible with the underlyingitem
type or is otherwise handled appropriately.
87-92
: Confirm one-time initialization logic under concurrent conversions.
TheOnceLock
usage ensuresitem
can be set exactly once, but if multiple threads attempt to callfinalize
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
: Validatemin_items
andmax_items
.
When both fields are set, ensuremin_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 viaOnceLock
. This sequence is typically correct, but if any errors can arise during item finalization, ensure theListType
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 theParent
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 commentThe 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 objectsNice 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 retrievalThe
effect()
method cleanly handles the default case when no effect is specified by returningEffectType::Read
. This helps maintain consistent behavior for callers.
67-80
: LGTM: Comprehensive edge definitionThe
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 handlingThe
finalize
method inFunctionTypeConversionResult
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
, andIndexMap
appear necessary given the usage in subsequent code.
21-27
: Builder-like approach forAlias
is clear.Storing
AliasTarget
,container
, andquote
as separate fields is an intuitive design for flexible type definitions. No immediate concerns here.
29-38
: Defaulting fields inFrom<AliasTarget>
is convenient.The fallback values (
name: None
,container: None
,quote: false
) streamline creation ofAlias
objects and reduce boilerplate.
40-61
: Fluent builder methods are well-structured.These
named
,container
, andquote
methods follow a good pattern for incremental construction. All methods returnSelf
, 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
andUnion
design is consistent.Both structures neatly implement
render
with similar patterns. This consistency enhances maintainability.
188-226
: Implementation ofManifestEntry
forPyType
is clean.
- The
match
arms are well organized and easy to follow.- Returning
Option<String>
inget_reference_expr
is a practical approach for references.
335-349
: Add validations or logs when generatingPyTypesPage
.This block processes
tg.input_types
andtg.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.rsLength 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
, andtype_body_required
—is referenced in the file. No unused imports were detected.
There was a problem hiding this 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 refactoringselection_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 forPreparedRequest
.
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
📒 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
, andindent_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
, andTypeNodeExt
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 inClientPyManifest::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 ofprocessed_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
andstd::borrow::Cow
signals direct intention and reduces confusion around which modules are in scope.
9-16
: Publicly declared modules keep structure organized.Making
types
andutils
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 forFdkPythonGenConfig
.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 incollect_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 inclient_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
andmetagen-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 infetch
.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 ofrequest.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
utilityProviding both a
graphql_sync
andhostcall
method ensures a consistent API for different runtime contexts.tests/metagen/typegraphs/identities/py/fdk.py (3)
355-367
: Implementation forextract_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 inconvert_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
andHostcallTransport
.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 usefrom __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
andHostcallTransport
In the constructor of the
Ctx
class (lines 17–22 intests/metagen/typegraphs/identities/py/fdk.py
), the type hints forHostcallBinding
andHostcallTransport
are written as forward references. This may lead to runtime issues if these classes are not defined before theCtx
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
at the top of the file to postpone type evaluation.from __future__ import annotations- 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.
path: &mut Vec<Edge>, | ||
accumulator: &mut A, | ||
visit_fn: V, |
There was a problem hiding this comment.
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?
} | ||
N::Any { .. } => unreachable!(), // FIXME is this still used? |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
huge PR🧠
There was a problem hiding this 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 suggestionPotential 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 GenClientRsOptsThe 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 generationThe
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 methodsThe 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 fieldThe 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 interactionsThe 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 featuresThere'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 constraintsThe 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:
- Generate different type definitions based on the Python version
- Use try/except blocks to handle imports for newer typing features
- 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 withAtomic
andUnion
variants.
The usage ofwrite!
ensures structured output. Watch for panic fromexpect(...)
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
Populatesty_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
: Newtransports
module is neatly introduced.
Thegraphql
andgraphql_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
⛔ 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 componentsThe 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 dataThe 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 structureThe
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 componentsThe
new
method properly initializes all components of the manifest, including caching references for better performance. The function follows a clear stepwise approach:
- Build the types manifest with appropriate configuration
- Cache references for input and output types
- Build and cache node metadata
- Build and cache selections
- Combine all components into the final manifest
This structured approach enhances maintainability and readability.
130-152
: Simplified Generator::generate implementationThe 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 pipelineThe
render
andrender_client
methods provide a clear entry point for generating client code. The code follows a logical sequence:
- Add file header comments
- Render static content with appropriate options
- Render types
- Render node metadata
- Render selections
- Render query graph
This organization makes the code generation process more maintainable and easier to understand.
356-362
: Improved render_static with parameterized hostcallThe
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 handlingThe
with_metas_namespace
function provides a clean way to encapsulate node metadata within a dedicated namespace. The function now returns astd::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,urlLength 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 structThe UnionProp struct is well-defined with descriptive field names that indicate its purpose in handling union type variants.
21-31
: LGTM! Well-designed RustSelection enumThe 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 dependenciesThe 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 dependenciesThe 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:
- Uses a manifest-based approach for type generation (RustTypesConfig or RsClientManifest)
- Conditionally includes client code based on the new
exclude_client
option- 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:
- Add a hostcall parameter to control client inclusion
- Properly handle debug vs. release dependency paths
- 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
toArc<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 usesArc<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 theHOSTCALL
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:
- Make
args
public for direct access- Add
common
for shared functionality- Conditionally compile
files
andgraphql
based on features- Add
hostcall
to support the new injection capabilitiesThis 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
tourl::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:
- Improves separation of concerns
- Makes the code more flexible
- Supports both GraphQL and hostcall transports
- 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 theaddr
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 UsageThe
QueryGraph
struct insrc/metagen/src/client_rs/static/client.rs
(lines 46–48) has been updated to only contain thety_to_gql_ty_map
field, successfully removing the coupling to transport-specific code. No references to a removedaddr
field (via lookups likeQueryGraph.*\.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.rsLength of output: 268
Confirmed Removal of Deprecated Field
The
QueryGraph
struct insrc/metagen/src/client_rs/static/client.rs
now only contains thety_to_gql_ty_map
field, and theaddr
field has been completely removed. Searches for references toQueryGraph.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 theQueryGraph
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 oftypes::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, whileStructProp
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
andoutput_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 aspub(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 aspub(crate)
, andbuild_gql_req
has been renamed tobuild_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 parameterT
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 andAlias
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
andAsync
, 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 theAsyncRead
in areqwest::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 thatasync
readers are unsupported here. Ensure that consumers of theFile
type in asynchronous contexts rely oninto_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 forTypePathSegment
clarifies the path logic. Check if the enumeration covers all needed variants for future expansions.
16-17
:TypePath
clarity.
Wrapping a slice ofTypePathSegment
ensures the path is strongly typed. Good approach for predictable pattern matching later.
27-29
:PathToInputFiles
struct correctness.
Holds multipleTypePath
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 parallelsTypePath
. Useful for mapping user input to typed structures. Validate index handling in arrays.
39-40
:TyToGqlTyMap
name implies GraphQL usage.
Arc-wrappedHashMap
is a good way to share references. Confirm concurrency patterns if mutated in the future.
42-49
:FoundPlaceholders
andGqlRequest
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 onprop_key
are handled properly (e.g., keys not found).
90-100
:select_node_to_gql
(args block): initial argument parsing.
Writes arguments intodoc
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 invariable_types
have correspondingty_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
andGraphQLRequestError
Solid approach for HTTP and GraphQL error handling. Checking for200..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
: ForwardingBuildReqError
intoPrepareRequestError
Direct mapping is straightforward. Safe and consistent approach.tests/metagen/typegraphs/identities/rs/fdk.rs (7)
88-92
:Default
implementation forMatBuilder
.
ReturningSelf::new()
is sensible. This keeps initialization consistent with other code paths.
137-141
: Creation ofquery_graph
andCtx
.
Instantiating the query graph before buildingCtx
is clear. Confirm concurrency handling inhost
.
153-156
: NewCtx
struct fields.
EmbeddingQueryGraph
andHostcallTransport
in the context can simplify shared logic. Good design.
248-253
:hostcall(qg: &QueryGraph)
Returns aHostcallTransport
using the provided type map. This pattern is consistent with the file I/O frommetagen_client
.
260-263
:QueryGraph
struct
Holds anArc
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 forRootUploadFnInput
,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 toRootUploadFnInput
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 toupload(
in the repository (e.g., in TypeScript, Python, and other Rust tests). Please verify that all external invocations—especially in files liketests/metagen/typegraphs/sample/rs_upload/main.rs
and similar test files—are updated to provide completeRootUploadFnInput
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_uploadLength 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 passRootUploadManyFnInput
.
🏁 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 conversionThe search confirmed that every Rust usage of
upload_many
appears consistent with the update—most notably, the explicit call intests/metagen/typegraphs/sample/rs_upload/main.rs
clearly passes aRootUploadManyFnInput
. 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 groupingty_to_gql_ty_map
and the binding.
22-28
:new
constructor is straightforward.
No concerns here. Implementation is succinct.
66-85
:query
andquery_with_opts
methods are consistent.
They correctly leveragefetch
for reading data. Possibly unify code paths if you expect more “opts” usage in the future.
87-106
: Asynchronousmutation
usage is forward-compatible.
This layout is good for future expansions like concurrency or advanced networking features.
108-127
: Prepared queries straightforwardly delegate toprepare_query_with_opts
.
Implementation is conventional for a “preparation + usage” pattern.
129-148
:prepare_mutation
parallelsprepare_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 forPreparedRequestHostcall
This is well-structured. The usage ofmap_err
to unify errors is neat.
241-256
: Manual clone impl
This approach is correct given thatDoc
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
forHostcallError
Output ensures errors are summarized well, with partial detail on each error scenario.
311-324
: GraphQL errors consolidated intoHostcallError
.
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 inrs_upload/client.rs
– consistent, easy to maintain.
40-57
: Newtypes
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.
PyType::Alias( | ||
Alias::from(AliasTarget::Type(ty.item().key())) | ||
.container("Optional") | ||
.quote(), // TODO handle cyclic case where entire cycle is aliases | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
if prop.optional { | ||
// writeln!(dest, r#" "{name}": typing.NotRequired[{ty_name}],"#)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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>> |
There was a problem hiding this comment.
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
andRootIdentityFnInputPartial
(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
There was a problem hiding this 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 issueRemove the duplicate
for
loop declarationThere'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 issueResolve 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 issueFix the duplicated
transports
moduleThe
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 suggestionParameter type updated but return type still uses partial
Similar to the
identity
method, theidentity_update
method has been updated to useRootIdentityFnInput
for parameters but still usesRootIdentityFnInputPartial
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 suggestionInconsistent use of partial and complete types
Line 515 uses
PostPartial
as a return type, but line 514 usesRootCompositeArgsFnInput
(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 parameterIn the
convertQueryNodeGql
function, the destructured parameter namesubNodes
in the mapping function shadows the outersubNodes
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 whenexclude_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 ofHOSTCALL
flag keyed byexclude_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 typegraphThe 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:
- Use only complete types instead of a mix of partial and complete types
- Ensure all type definitions are consistently structured
- 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
⛔ 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 TypeScriptRegarding 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 composesRootIdentityFnInput
and sets theargumentTypes
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 fromRootIdentityUpdateFn
.
Both functions share a similar pattern, and the approach to expandRootIdentityFnInput
plus arguments appears consistent.
926-930
: Chained composition of node metas is correct.
The function forwards the NodeMeta fromRootNestedCompositeFnOutput
.
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 forRootNestedCompositeFnOutputListStruct
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
,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
mergesnodeMetas.scalar()
and sets an argument “id.”
1020-1027
: Composite function reusing “Post.”
No issues with referencingPost
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 mergesnodeMetas.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.
DefiningStringUuid4
asstring
and using it forid
inPost
is valid.
1075-1076
: Definingid
andUser
as typed fields.
No concerns:StringUuid4
andStringEmail5
are suitably typed.
1092-1095
: Adding explicit fields forRootNestedCompositeFnOutput
.
This structure, includingscalar
,composite
, andlist
, aligns with the subNodes definitions.
1102-1104
: Nested struct type clarifies theinner
field.
All definitions appear well-formed.
1109-1111
: UserSelections type updated with optional fields.
The fieldsid?
andemail?
match the scalar usage pattern.
1148-1150
: Type-to-GraphQL type mapping is aligned.
user_id_string_uuid
→ID!
,string_e1a43
→String!
, andinteger_64be4
→Int!
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 likeexclude_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 callinggen_mod_rs
.
Ensure that passingtg.clone()
is indeed necessary and doesn’t add unnecessary overhead.
152-152
: Retrieving the typegraph name looks straightforward.
No concerns with storing it intg_name
.
159-162
: Usage of!exclude_client.unwrap_or_default()
is logical.
Passing the inverse ofexclude_client
to indicate the need for a hostcall is consistent with the intended behavior.
184-187
: NewMaps
struct is a clear way to bundle references.
Encapsulating input/output references promotes clarity and reusability.
190-190
: Switching toArc<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, andgen_stub
usage is straightforward. Double-check thatmap(|val| val.as_str())
does not silently skip any needed functions if the key is missing.
263-267
:gen_static
now acceptingconfig
seems prudent.
This provides flexibility if you need to branch logic based on config.
305-306
: Reapplying the same flags to the nextprocessed_write
call.
Keeps code generation unified under one conditional approach.
330-351
: Conditional logic formetagen-client
ingen_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 forTypeNodeExt
andmanifest_page
.
They appear to enable extended typegraph functionalities and manifest-based rendering.
77-77
: Switching toArc<Typegraph>
inrender_fdk_ts
.
This follows the same pattern for shared ownership seen in other modules.
92-95
: Leveragingmanifest_page
andrender_all
centralizes type rendering.
This is a more maintainable approach than manual type assembly.
102-102
: Excellent use ofwrap_err_with
for contextual errors.
No concerns—this makes debugging easier.
106-108
: Usingnormalize_type_title
for input/output/function type names.
Ensures consistent naming conventions for generated stubs.
174-174
: Refactoringfdk.ts
generation viarender_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.
Replacingfile
with afiles
array clarifies multi-upload usage. Verify correct processing logic forinputFiles: [[".files","[]"]]
.
913-920
:RootUploadFn
updated for single-file handling.
Transitioning from multi-file to single upload is consistent with the method name. Ensurepath
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_pyThe 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 eitherPyTypesPage
orClientPyManifest
accordingly.
128-139
: Enhanced error handling for stubbed functionsThe 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_pyThe 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 systemThe 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 implementationThe
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 structThe 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 implementationThe
RsClientManifest
struct and its implementation provide a clean way to initialize and manage the client generation process. Thenew
method properly sets up all required components and constructs the maps needed for type and metadata lookups.
143-152
: Simplified client generation implementationThe changes to the
generate
method simplify the code by leveraging the newRsClientManifest
structure. This makes the code more readable and maintainable.
253-352
: Comprehensive implementation of root function generationThe
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 implementationThe
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 reviewAs 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 subtypesThe updated type definitions for
uuid
,ean
,json
,uri
,date
, anddatetime
use more specific type aliases (StringUuid6
,StringEmail7
, etc.) rather than juststring
. This enhances type safety and makes the code more self-documenting.
69-77
: Well-structured composite type definitionsThe
CompositesArgs
andComposites
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 typesThe
Cycles1Args
andCycles1
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 typesThe
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 typesThe
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
toPost
) 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 aPost
struct is used as input arguments to a function that seems to expect field values likeid
,slug
, andtitle
.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 rustLength of output: 167
Attention: Verify Data Structure Consistency in Method Signature
The
scalar_args
method currently accepts an argument of typeimpl Into<NodeArgs<Post>>
, which implies that a completePost
type (including fields such asid
,slug
, andtitle
) 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 ofNodeArgs<Post>
elsewhere to indicate a different intent, so please confirm that using the completePost
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
src/metagen/src/fdk_py/mod.rs
Outdated
use core::fmt::Write; | ||
use std::borrow::Cow; | ||
use core::fmt::Write; | ||
use std::borrow::Cow; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
use core::fmt::Write; | |
use std::borrow::Cow; | |
use core::fmt::Write; | |
use std::borrow::Cow; | |
use core::fmt::Write; | |
use std::borrow::Cow; |
args: impl Into<NodeArgs<RootIdentityFnInput>>, | ||
) -> UnselectedNode< | ||
RootIdentityFnInputSelections, | ||
RootIdentityFnInputSelections<HasAlias>, | ||
QueryMarker, | ||
RootIdentityFnInputPartial, | ||
> { |
There was a problem hiding this comment.
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.
args: impl Into<NodeArgs<RootIdentityFnInput>>, | |
) -> UnselectedNode< | |
RootIdentityFnInputSelections, | |
RootIdentityFnInputSelections<HasAlias>, | |
QueryMarker, | |
RootIdentityFnInputPartial, | |
> { | |
args: impl Into<NodeArgs<RootIdentityFnInput>>, | |
) -> UnselectedNode< | |
RootIdentityFnInputSelections, | |
RootIdentityFnInputSelections<HasAlias>, | |
QueryMarker, | |
RootIdentityFnInput, | |
> { |
There was a problem hiding this 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 issueMissing 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 issueMissing 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 issueMissing 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
andRootUploadFnInputPathString25e51Optional
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 logicThe refactored code now conditionally uses either
TsTypesPage
orTsClientManifest
based on theexclude_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 anArc
, the.clone()
call is redundant asArc
is designed for cheap cloning and would be cloned implicitly when needed.
237-240
: Consider using debug logs instead of printlnThese 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 detectionThe 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 renderingThe 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 typeThe 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 skipThe 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 onexclude_client
. Consider extracting this logic into a dedicated helper to avoid complexity. Also, replace or remove theeprintln!("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 importsThese 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 fallbackWhen
exclude_client
is false, the code initializes aClientPyManifest
and renders client stubs. Double-check that the subsequent references tomanif.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 returningNodeMeta
. Confirm naming consistency with related “uploadMany” logic in the codebase.
97-97
: File argument type resolution
("file".into(), "file_bf9b7".into())
is consistent withFileBf9b7 = super::FileId
. Double-check the actualFileId
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 StringDouble-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 importsThese 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 sequenceCreating a
TsClientManifest
and immediately callingrender
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 debuggingThe 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 multipleIndexMap<TypeKey, String>
structures is convenient. However, confirm that the sameTypeKey
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
: ConstructorRsClientManifest::new
is comprehensive but consider error-handling clarity.
The function builds submanifests, node metas, and selections, then stores references inMaps
. 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 aQueryGraph
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 thehostcall
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 oftypes::*
.
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 partialPost
.
Check that no-arg usage is consistent with the typegraph’s required fields.
572-573
:composite_union
similarly reusesRootCompositeArgsFnInput
.
Again, consistent yet unusual naming. If the input structure differs from typical “composite” usage, a rename might help.
584-585
:mixed_union
also builds onRootCompositeArgsFnInput
.
Same pattern ascomposite_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
: CreateBranch33B
and updateBranch33A
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_a
→branch33A
or consistently using snake_case for all fields.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ 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
forRustType
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 theRustTypesSubmanifest
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
andrender_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
anduploadMany
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 renderingThe imports now utilize
TsClientManifest
andTsTypesPage
from the client_ts module instead of custom type rendering logic. The import ofTypeNodeExt
trait also enables direct access to type information.
80-80
: Function signature changed to use ArcThe 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 usesTsClientManifest
which requires anArc<Typegraph>
.
110-116
: Improved type name access with TypeNodeExt traitThe code now uses the
TypeNodeExt
trait's methods likeinput().name()
andoutput().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 processingThe return type change from
core::fmt::Result
toanyhow::Result<()>
allows for more detailed error reporting. Additionally, the implementation now usesprocessed_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 aliasThe new
TsTypesPage
type alias simplifies the codebase by providing a descriptive type forManifestPage<TsType>
, making the code more maintainable and easier to understand. Good use of type aliasing.
13-39
: Well-structured type representation with enumsThe enums
Alias
andTsType
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 typesThe 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 handlingThe
build_union
method correctly maps union types to TypeScript's enum representation, collecting all variant keys for later rendering.
116-121
: Well-defined ObjectProp structThe
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 implementationThe
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 generationThe
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 implementationThe
From<&Type>
implementation forTsType
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 creationThe
new
method efficiently creates aTsTypesPage
from aTypegraph
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 (usingrg RpcCall::Utils
) did not yield any outputs, which is inconclusive. Please manually verify that the ordering of variants in the enum declared insrc/meta-cli/src/typegraph/rpc/mod.rs
(includingUtils(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 retrievingtg_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 forFunctionType
andTypeNodeExt
.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 requirementsSwitching to
Arc<Typegraph>
suggests shared ownership, possibly enabling concurrent usage. Confirm this is intentional and all references totg
support thread-safe operations or are never used across threads if not needed.
91-94
: Validate PyTypesPage usageRetrieving 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 carefullyFiltering 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 referencesThese 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 successThe 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 newfdk.py
file.tests/metagen/typegraphs/sample/rs_upload/client.rs (8)
40-58
: New type definitions for upload inputsThe new
RootUploadFnInput
andRootUploadManyFnInput
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 referencesPassing
"files".into()
and"prefix".into()
is valid, but verify these match the actual fields inRootUploadManyFnInput
. 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 toOption<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 mappingMapping
"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 structEncapsulating 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 initializationThe
new
method caches references from each page fortypes
,node_metas
, andselections
. Validate that all type keys are recognized and that no references are missed.
139-139
: Direct buffer injectionStoring
buf
ascontents
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 inrender_client
.
152-163
: High-level render method
render
prints a warning header and delegates torender_client
. This is a good encapsulation. Ensure that future expansions (such as inlined docs) are appended in a consistent manner.
165-193
: render_client changesThis method writes static code, rendered types, node metas, selections, and the query graph. Verify that placeholders (like
HOSTCALL
) are replaced correctly, especially ifhostcall
is set totrue
.
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_functionsThis 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 ofRustTypesConfig
,RustTypesSubmanifest
,RsNodeMeta
, andRustSelectionManifestPage
. No conflicts or unused imports are detected.
55-61
: StructRsClientManifest
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 ofRsClientManifest::new
in the generation pipeline.
These lines create theRsClientManifest
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 thattg_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
andrender_client
methods unify generation steps.
Centralizing rendering steps insideRsClientManifest
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 callingconvertQueryNodeGql
.
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
reusesRootIdentityFnInput
plusargumentTypes
.
Extending base NodeMeta with extra arguments is good. Confirm that theinput
argument is consistently recognized in all related queries.
922-929
:RootIdentityFn
reusesRootIdentityFnInput
and setsargumentTypes
.
Similar toRootIdentityUpdateFn
, keep consistent usage patterns across code references. No immediate concerns.
930-933
:RootNestedCompositeFn
aliasingRootNestedCompositeFnOutput
.
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 includesid
,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 fromscalar()
with an “id.”
No immediate problem. Maintaining a uniform approach to argument naming is recommended.
1024-1031
:RootCompositeArgsFn
: argument “id” plus thePost
sub-node.
Combining arguments with sub-nodes is coherent. Looks fine.
1032-1036
:RootCompositeNoArgsFn
referencesPost
.
Straightforward function. No concerns.
1037-1046
:RootScalarArgsFn
mergesscalar()
with new argument types.
Uses “user_id_string_uuid,” “slug,” and “title.” Implementation is consistent.
1047-1051
:RootScalarNoArgsFn
extendsscalar()
.
No arguments needed. Everything is minimal and correct.
1052-1056
:RootGetPostsFn
referencesPost
with no arguments.
In sync with the rest of the structure. No issues.
1057-1061
:RootGetUserFn
referencesUser
with no arguments.
Similar approach asRootGetPostsFn
, looks good.
1063-1065
: New aliasStringUuid4
integrated withPost
.
DeclaringStringUuid4
as a simple string is acceptable. Confirm that future expansions for ID validations or specialized types remain consistent.
1076-1081
: User fields updated toStringUuid4
andStringEmail5
.
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 aninner: 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
returnsUnselectedNode<..., 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
returnsUnselectedNode<..., PostPartial>
Similarly references partial data for “posts.” Confirm that consumers expect partial data.
507-508
:scalar_args
usesimpl Into<NodeArgs<Post>>
.
This signature ensures flexible argument passing forPost
. The usage looks fine.
539-540
:composite_args
referencesRootCompositeArgsFnInput
.
Solid approach to pass structured arguments. No concerns.
551-552
:scalar_union
referencesRootCompositeArgsFnInput
for arguments.
ReusingRootCompositeArgsFnInput
is interesting—please confirm that union behavior with these arguments is always expected.
596-597
:nested_composite
referencesRootNestedCompositeFnOutputPartial
.
Straightforward partial usage, no issues.
607-608
:identity
usesRootIdentityFnInput
with partial return.
Ensures partial output. Confirm that partial usage is intentional.
619-620
:identity_update
parallelsidentity
, passingRootIdentityFnInput
.
Matches the pattern, returning partial data.tests/metagen/typegraphs/identities/py/fdk.py (7)
1030-1040
: Add methodRsProxyPrimitives
for specialized NodeMeta creation.This new static method is consistent with the existing pattern of returning a NodeMeta object referencing
NodeDescs.Primitives()
. Thearg_types
configuration for{"data": "primitives"}
is appropriate and aligns with other methods.
1062-1090
: IntroduceRsSimpleCycles
and defineSimpleCycles1
,SimpleCycles2
, andSimpleCycles3
.These methods follow the established NodeMeta pattern and set
arg_types
to handle"data": "simple_cycles_1"
. The sub_nodes referencingphantom1
,phantom2
,phantom3
, and the chained calls (to2
,to3
) appear correct for cyclical references.
1099-1115
: AddRsCycles
and updateCycles1
sub_nodes.The new approach of setting
arg_types
to"data": "cycles1"
and referencing sub_nodes likephantom1
,to2
, andlist3
for cyclical structures is consistent with other cycle definitions. Looks logically sound.
1156-1192
: AddRsComposites
,Composites
,CompositesEitherEither
, andBranch2
.This block extends the composites structure with optional sub_nodes or variants. The usage of
{"data": "composites"}
inRsComposites
is consistent. The either/union pattern referencingPrimitives
andBranch2
is coherent.
1193-1314
: Expand or introduceRsPrimitives
,TsProxyPrimitives
,TsSimpleCycles
,TsCycles
,TsComposites
,TsPrimitives
,PyProxyPrimitives
,PySimpleCycles
,PyCycles
,PyComposites
, andPyPrimitives
.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 forPrimitivesArgs
,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 forCompositesArgs
,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
: ImplementRsProxyPrimitives
innodeMetas
.Merges a base
Primitives()
NodeMeta withargumentTypes: { data: "primitives" }
. Matches the cross-language pattern. No issues spotted.
1011-1042
: IntroduceRsSimpleCycles
andSimpleCycles1/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
: AddRsCycles
, define/extendCycles1
,Branch33B
,Cycles2
,Branch33A
, andRsComposites
, 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 forPrimitives
,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 expandedtypes
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
: DefineRsProxyPrimitives
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 toSimpleCycles1()
. 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
Storingvariants: None
and linking"phantom2"
,"to3"
toSimpleCycles3
is consistent. All good.Also applies to: 561-562
573-574
:SimpleCycles3
sub-nodes
Defines"phantom3"
mapping to scalar,"to1"
linking back toSimpleCycles1
, 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 toComposites()
. 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 referencingPrimitives
andBranch2
. 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 toPrimitives()
. This leverages the same pattern used in other typed entry points.
716-726
: Repeated patterns forts_
,py_
NodeMeta registrations
These lines replicate the same pattern of"data" => <type>
followed by a delegating spread (..Xxx()
). All are consistent with the approach inRsPrimitives
.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 genericNodeArgs<PrimitivesArgs>
to buildpy_primitives
. This straightforward approach is repeated in subsequentpy_
,ts_
, andrs_
functions.Also applies to: 921-922
933-934
: Repeated query function definitions
These lines mirror the same pattern ofargs: impl Into<NodeArgs<...>>
followed by returning a typedUnselectedNode
. They align consistently with thepy_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
src/metagen/src/fdk_rs/stubs.rs
Outdated
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); |
There was a problem hiding this comment.
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 inmaps
.
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 inmaps.default
. - Since
gen_stub
is used in multiple locations (seesrc/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 |
There was a problem hiding this comment.
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.
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 |
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>, | ||
} |
There was a problem hiding this comment.
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.
- 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. - Sizable enumerations like
RootMixedUnionFnOutputPartial
might benefit from comments describing each variant’s usage to reduce confusion. - Consider adding dedicated tests for partial vs. non-partial states, ensuring the serialization logic matches expected usage.
There was a problem hiding this 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 issueHandle missing types more gracefully.
Defaulting the input type to
()
could mask missing or erroneous inputs, and usingunwrap()
for the output type can cause runtime panics if it's missing inmaps
.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 issueMissing 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 issueImplement 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.
- Consider adding doc comments for these exported types to clarify usage.
- 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 onconfig.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 expandingGenClientTsOpts
for future extensibility.Currently,
GenClientTsOpts
only contains ahostcall
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 ofMaps
.
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 acrossRsClientManifest
andRsClientManifestOpts
.
pub(super)
fields are mixed with a publicmaps
field. Verify it is intentional to expose onlymaps
but hide other fields. Adding doc comments for these public items would also improve clarity.
205-207
: Add doc comments forGenClientRsOpts
.
Providing a short summary, especially around thehostcall
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 eachUnselectedNode
) into helper methods could further improve clarity.
394-420
: Consider adding docs forwith_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 forRootMixedUnionFn
andRootCompositeUnionFn
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
, andidentity_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
📒 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 forRsProxyPrimitives
.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
referencesSimpleCycles1
. Everything lines up well with the existing approach. No changes requested.
550-580
: Check for correct linking inSimpleCycles1/2/3
.The newly added sub-nodes (
phantom1
,to2
, etc.) reference each other across these functions and may create recursive cycles. The references toSimpleCycles2
andSimpleCycles3
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
andCycles1/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 thetypes
module. No immediate issues.
620-657
:Branch33B
andBranch33A
expansions are consistent.Both node-meta functions correctly expose sub-nodes for
phantom3b
,to2
,phantom3a
, andto1
. This matches the cyclical design in the types module. No concerns.
663-718
:RsComposites
,Composites
,CompositesEitherEither
,Branch2
, andRsPrimitives
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
andbranch33B
, along with the nestedscalar
node references, align with the cyclical design. No immediate concerns.
888-892
:SimpleCycles1Selections
additions.These additions keep the same pattern (adding
phantom1
andto2
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 transformNodeArgs<T>
toUnselectedNode<...>
. 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 theMaps
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 useArc<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 ofprocessed_write
expects a mutable string reference rather than the entireGenDestBuf
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 thatdest.buf
implementsWrite
) 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
insrc/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 viawrap_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 useArc<FunctionType>
and the newMaps
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
andTsClientManifest
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 inTsClientManifest::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 thegenerate
method.The
generate
method now properly handles errors fromTsClientManifest::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 ofRustTypesConfig
,ManifestPage
, etc.
162-179
: Logic for generatingclient.rs
looks solid.
The approach of constructingRsClientManifest
, 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 forRsClientManifest
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 ofrender_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 staticclient.rs
data is consistent with the rest of the pipeline.
68-112
:✅ Verification successful
Verify correct usage of partial and non-partial outputs.
Whennon_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 3Length of output: 68708
Verified: Partial and non-partial outputs are used consistently across the codebase.
I reviewed the relevant call sites and tests. Insrc/metagen/src/client_rs/mod.rs
, the code switches betweenOutputTypes::Both
(when thenon_partial_output_types
flag is true) andOutputTypes::Partial
(when false). The grep results show that all type names—such asUserPartial
,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 fromRootIdentityFnInput
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 forRootNestedCompositeFn...
. Properly referencing partial struct fields is done effectively here.
298-339
: Scalar union and composite args usage.
RootScalarUnionFn
andRootCompositeArgsFn
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
andRootGetUserFn
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 likeimpl_selection_traits!
keeps the code DRY.
407-465
:✅ Verification successful
Query graph definition and initial root calls
Methods likeget_user()
andscalar_args()
illustrate consistent usage of partial types in the return type while still offering typed input arguments. Verify that thescalar_args
function indeed intends to acceptPost
as input.Would you like to confirm that
scalar_args(...) -> MutationNode<String>
is meant to acceptNodeArgs<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 typeimpl Into<NodeArgs<Post>>
and returns aMutationNode<String>
. This signature suggests it's intentionally specialized for handlingPost
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 asUserPartial
,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' testsLength 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 thePartial
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 likeProfilePartial
,ProfileCategoryStructPartial
, andEntityPartial
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 asPrimitivesPartial
,Branch2Partial
, and others conform to the new structure or are updated as required.Other references
Confirm that any references in JSON (e.g., intests/importers/introspection.json
) and TypeScript (e.g., intests/artifacts/artifacts_test.ts
) are consistent with the new definitions.Please update or document any intentional differences accordingly.
// 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(()) | ||
// } | ||
// } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this 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 suggestionAdd 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 thecontains
methodThe implementation for
Input
andOutput
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 inget_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
⛔ 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 andPySelectionsPage
type alias provide a clear foundation for the Python selection rendering system.
18-40
: LGTM: Well-designed polymorphic approach withPySelection
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 forPySelectionsPage
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 crateThe 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 implementationThe 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 structureThe
Path
type alias andPathSegment
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 handlingThe
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 into_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 operationsThe 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 edgesThe
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 conversionThe
TryFrom<RelativePath>
forValueTypePath
correctly handles input and output paths while rejecting other path types.
147-176
: LGTM: Effective handling of injection data in path traversalThe
apply_on_schema_node_ex
andapply_on_injection
methods provide good support for dealing with injections during path operations.
#[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(()) | ||
} | ||
} |
There was a problem hiding this comment.
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.
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 | ||
), | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
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.
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 | |
), | |
} | |
} | |
} |
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); | ||
} | ||
} |
There was a problem hiding this comment.
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.
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); | |
} | |
} |
There was a problem hiding this 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 issueMissing 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 suggestionContainer 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 suggestionAvoid 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 structThe 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 accessUsing
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" tagsThe 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 methodThe 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 largenew
methodThe
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 codeThere's commented-out code that appears to be a TODO related to transitioning from the old
RustTypeRenderer
to the newRustType
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 thanunwrap()
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()
inRootRandomFn
.
Similar toHundredRandom
,RootRandomFn
relies on..Entity()
. Confirm thatRootRandomFn
truly requires the same sub-node structure asEntity
, or consider creating a distinct shape if different fields are needed.
291-293
: Consider explicit naming for sub-fields.
Usingscalar
forname
andage
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 theMetaFactory
traitThis 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 ofMetasPageBuilder
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 loopThe 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 referencesIt'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 documentationThe 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 TypeNodeExtThe 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 forTypeConversionResult
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 ofFinalizedTypeConversion
.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 inregister_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 inbase
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 toPolicyNode
.Explaining how materializers and policy naming interact here will help newcomers.
14-20
: Provide usage examples forConditionalPolicy
.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
📒 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 potentialAttributeError
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 functionThe
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 handlingThe 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 definitionThe 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 structureThe
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 ofEntity
structure inHundredRandom
.
You are reusing..Entity()
inpub fn HundredRandom()
. Ensure that this shape (inherited fields forname
,age
,profile
) aligns with the intended semantics for a “hundred random” node.
382-389
: Ensure float-to-integer conversions are safe.
AddArgsAFloat
is defined asf64
, whileAddOutput
is ani64
. 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.
Therecord()
method returnsRecordCreationOutputPartial
. Verify that downstream consumers can handle partialEntity
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 forchildren()
across thesrc/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 forConversion
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 renamingregister_type_2
for clarity.A more descriptive name (e.g.,
register_type_with_duplicate_handling
) could clarify how it differs fromregister_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 theunreachable!()
scenario safely.Even if
Any
is currently unused in schemas, leavingunreachable!()
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
: Validatepolicy.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"; |
There was a problem hiding this comment.
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.
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, | ||
}) | ||
} |
There was a problem hiding this comment.
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.
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), | ||
}), | ||
} | ||
} |
There was a problem hiding this comment.
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.
Codecov ReportAll modified and coverable lines are covered by tests ✅
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. 🚀 New features to boost your workflow:
|
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
Summary by CodeRabbit
New Features
Primitives
,Composites
, and cycle-related entities.Refactor