-
Notifications
You must be signed in to change notification settings - Fork 193
feat: implement openfed__requireFetchReasons #2170
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
Conversation
WalkthroughAdds a repeatable directive openfed__requireFetchReasons, threads its definition and propagation through normalization and schema-building, records per-object fields that require fetch reasons, tightens string types to FieldName/TypeName across composition and config, updates protobuf/TS models, and adds tests. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (16)
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
Router-nonroot image scan passed✅ No security vulnerabilities found in image: |
ysmolski
left a comment
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.
It looks good. I have integrated engine and router to use this change. Thank you!
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: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
proto/wg/cosmo/node/v1/node.proto (1)
140-145: Documentprotected_field_namesin the proto and regenerate all clients/serversPlease add a concise comment in
proto/wg/cosmo/node/v1/node.protodescribing the semantics ofprotected_field_names, then run your protobuf generation pipeline to update all affected artifacts (Go, JS/TS, Connect code). The field is already in use across tests and generated code, so we need to ensure the new comment makes its way into every client.• File to update:
proto/wg/cosmo/node/v1/node.proto(line 144, before field 4)• Steps:
- Add the following comment above
protected_field_namesin the proto.- Re-run
protoc(and any codegen scripts) to regenerate:
- Go:
router/gen/proto/wg/cosmo/node/v1/node.pb.go- TS:
connect/src/wg/cosmo/node/v1/node_pb.ts- Any other generated clients/servers.
- Commit the updated generated files.
Diff to apply in
proto/wg/cosmo/node/v1/node.proto:message TypeField { string type_name = 1; repeated string field_names = 2; repeated string external_field_names = 3; + // Fields on this type marked with @openfed__protected. + // List is empty if no fields are protected. repeated string protected_field_names = 4; }composition/src/v1/normalization/normalization-factory.ts (2)
3417-3450: protectedFieldNames never populated; configuration remains empty.You copy parentData.protectedFieldNames into configuration, but nothing adds field names to that Set. Populate it while iterating fields.
for (const [fieldName, fieldData] of parentData.fieldDataByName) { if (!isObject && fieldData.externalFieldDataBySubgraphName.get(this.subgraphName)?.isDefinedExternal) { externalInterfaceFieldNames.push(fieldName); } + // Track protected fields on object types + if (isObject && fieldData.directivesByDirectiveName.has(PROTECTED)) { + (parentData as ObjectDefinitionData).protectedFieldNames.add(fieldName as FieldName); + } // Arguments can only be fully validated once all parents types are known this.validateArguments(fieldData, parentData.kind);
587-596: Sticky inheritance flags cause cross-type leakage. Reset for each parent object.isParentObjectProtected (and peers) are never reset; a protected object will incorrectly mark subsequent objects’ fields as protected. Reset at object entry in extractDirectives.
) { - if (!node.directives) { + if (!node.directives) { return directivesByDirectiveName; } + // Reset inheritable flags per parent object + if (isNodeKindObject(node.kind)) { + this.isParentObjectExternal = false; + this.isParentObjectProtected = false; + this.isParentObjectShareable = false; + } for (const directiveNode of node.directives) {
🧹 Nitpick comments (6)
composition/src/router-configuration/types.ts (1)
84-95: Consider deduping protectedFieldNames to avoid drift.
ConfigurationData mixes Set (fieldNames, externalFieldNames) with Array (protectedFieldNames). Keep Array if preferred, but ensure consumers dedupe to avoid duplicates in emitted configs. I’ve proposed a small downstream change where it’s consumed.Proposed consumer change (see shared/src/router-config/graphql-configuration.ts lines 132-134).
shared/src/router-config/graphql-configuration.ts (1)
132-134: Deduplicate and stabilize ordering of protectedFieldNames.
Helps produce deterministic configs and avoids accidental duplicates from upstream.Apply this diff:
- if (data.protectedFieldNames && data.protectedFieldNames.length > 0) { - typeField.protectedFieldNames = [...data.protectedFieldNames]; - } + if (data.protectedFieldNames && data.protectedFieldNames.length > 0) { + const protectedFieldNames = Array.from(new Set(data.protectedFieldNames)).sort(); + typeField.protectedFieldNames = protectedFieldNames; + }composition/src/v1/normalization/walkers.ts (1)
366-374: Add protected-field tracking and update the comment to reflect PROTECTED.Logic is correct: apply when parent is object and either parent is protected or field is protected. Update the comment to avoid future confusion.
Suggested in-range comment tweak:
-// Add parent-level shareable and external to the field extraction and repeatable validation +// Add parent-level shareable, external, and protected to the field extraction and repeatable validationcomposition/tests/v1/directives/protected.test.ts (2)
254-338: Add a regression guard to ensure PROTECTED definition is emitted exactly once.To prevent accidental duplicate directive-definition emission, add an assertion that counts a single occurrence of "directive @openfed__protected" in each subgraph SDL.
I can add a small helper to assert “occursExactlyOnce(schemaSDL, 'directive @openfed__protected')”.
341-349: Use the project parse wrapper for consistency and noLocation defaults.Prefer importing parse from composition/src/ast/utils to align with other tests and avoid location noise.
-import { parse } from 'graphql'; +import { parse } from '../../../src';composition/src/v1/normalization/normalization-factory.ts (1)
3479-3482: Optional: ensure deterministic ordering of protectedFieldNames.Sorting yields stable output across environments and avoids order flakiness if Set insertion varies.
- if (isObject && parentData.protectedFieldNames.size > 0) { - configurationData.protectedFieldNames = [...parentData.protectedFieldNames]; - } + if (isObject && parentData.protectedFieldNames.size > 0) { + configurationData.protectedFieldNames = [...parentData.protectedFieldNames].sort(); + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (2)
connect-go/gen/proto/wg/cosmo/node/v1/node.pb.gois excluded by!**/*.pb.go,!**/gen/**router/gen/proto/wg/cosmo/node/v1/node.pb.gois excluded by!**/*.pb.go,!**/gen/**
📒 Files selected for processing (19)
composition/src/router-configuration/types.ts(2 hunks)composition/src/router-configuration/utils.ts(2 hunks)composition/src/schema-building/types.ts(1 hunks)composition/src/schema-building/utils.ts(1 hunks)composition/src/subgraph/types.ts(2 hunks)composition/src/utils/string-constants.ts(2 hunks)composition/src/v1/federation/federation-factory.ts(2 hunks)composition/src/v1/normalization/directive-definition-data.ts(3 hunks)composition/src/v1/normalization/normalization-factory.ts(11 hunks)composition/src/v1/normalization/utils.ts(3 hunks)composition/src/v1/normalization/walkers.ts(5 hunks)composition/src/v1/utils/constants.ts(3 hunks)composition/src/v1/utils/utils.ts(0 hunks)composition/tests/v1/directives/protected.test.ts(1 hunks)composition/tests/v1/directives/shareable.test.ts(0 hunks)composition/tests/v1/utils/utils.ts(1 hunks)connect/src/wg/cosmo/node/v1/node_pb.ts(2 hunks)proto/wg/cosmo/node/v1/node.proto(1 hunks)shared/src/router-config/graphql-configuration.ts(1 hunks)
💤 Files with no reviewable changes (2)
- composition/src/v1/utils/utils.ts
- composition/tests/v1/directives/shareable.test.ts
🧰 Additional context used
🧬 Code graph analysis (13)
composition/src/schema-building/utils.ts (1)
composition/src/schema-building/types.ts (2)
ParentDefinitionData(240-246)InterfaceDefinitionData(156-170)
composition/src/subgraph/types.ts (3)
composition/src/types/types.ts (1)
TypeName(9-9)composition/src/router-configuration/types.ts (1)
ConfigurationData(83-95)composition/src/schema-building/types.ts (1)
ParentDefinitionData(240-246)
composition/src/schema-building/types.ts (1)
composition/src/types/types.ts (1)
FieldName(3-3)
composition/tests/v1/directives/protected.test.ts (8)
composition/tests/utils/utils.ts (3)
federateSubgraphsSuccess(59-72)schemaToSortedNormalizedString(27-29)normalizeString(19-21)composition/src/router-compatibility-version/router-compatibility-version.ts (1)
ROUTER_COMPATIBILITY_VERSION_ONE(3-3)composition/tests/v1/utils/utils.ts (3)
versionOneRouterDefinitions(106-106)schemaQueryDefinition(84-87)baseDirectiveDefinitionsWithProtected(37-45)composition/src/types/types.ts (2)
TypeName(9-9)FieldName(3-3)composition/src/router-configuration/types.ts (1)
ConfigurationData(83-95)composition/src/utils/string-constants.ts (1)
QUERY(110-110)composition/src/subgraph/types.ts (1)
Subgraph(11-15)composition/src/ast/utils.ts (1)
parse(272-274)
shared/src/router-config/graphql-configuration.ts (1)
connect/src/wg/cosmo/node/v1/node_pb.ts (1)
TypeField(1085-1135)
composition/src/router-configuration/utils.ts (1)
composition/src/types/types.ts (1)
FieldName(3-3)
composition/src/v1/federation/federation-factory.ts (1)
composition/src/types/types.ts (1)
FieldName(3-3)
composition/src/v1/normalization/walkers.ts (2)
composition/src/schema-building/utils.ts (1)
isInterfaceDefinitionData(261-263)composition/src/utils/string-constants.ts (2)
EXTERNAL(42-42)PROTECTED(106-106)
composition/src/v1/normalization/directive-definition-data.ts (3)
composition/src/schema-building/types.ts (2)
DirectiveDefinitionData(41-50)ArgumentData(30-34)composition/src/utils/string-constants.ts (3)
FIELD_DEFINITION_UPPER(50-50)OBJECT_UPPER(99-99)PROTECTED(106-106)composition/src/v1/utils/constants.ts (1)
PROTECTED_DEFINITION(663-668)
composition/src/router-configuration/types.ts (1)
composition/src/types/types.ts (2)
FieldName(3-3)TypeName(9-9)
composition/src/v1/normalization/utils.ts (2)
composition/src/utils/string-constants.ts (1)
PROTECTED(106-106)composition/src/v1/normalization/directive-definition-data.ts (1)
PROTECTED_DEFINITION_DATA(444-452)
composition/src/v1/normalization/normalization-factory.ts (4)
composition/src/utils/string-constants.ts (2)
PROTECTED(106-106)SHAREABLE(128-128)composition/src/utils/utils.ts (1)
generateSimpleDirective(159-164)composition/src/types/types.ts (1)
FieldName(3-3)composition/src/v1/utils/constants.ts (1)
PROTECTED_DEFINITION(663-668)
composition/src/v1/utils/constants.ts (2)
composition/src/utils/string-constants.ts (3)
PROTECTED(106-106)FIELD_DEFINITION_UPPER(50-50)OBJECT_UPPER(99-99)composition/src/ast/utils.ts (2)
stringArrayToNameNodeArray(84-90)stringToNameNode(77-82)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: integration_test (./events)
- GitHub Check: build_test
🔇 Additional comments (28)
composition/src/schema-building/types.ts (1)
185-185: No changes needed for protectedFieldNames initialization and mergingI ran the suggested checks and confirmed that:
- Both the federation and normalization factories initialize
protectedFieldNamesas a newSet<FieldName>(normalization-factory.ts:1302; federation-factory.ts:1135).- Merge operations correctly union the sets via
.add(...)in walkers (walkers.ts:372) and by spreading into a new array (configurationData.protectedFieldNames = [...parentData.protectedFieldNames]) in the normalization factory (normalization-factory.ts:3480).All constructors and mergers properly handle
protectedFieldNames, so there’s no accidental data loss to address here.composition/src/router-configuration/utils.ts (2)
2-2: Type alignment LGTMImporting FieldName tightens typing without runtime impact.
16-16: Set typing LGTMfieldNames: new Set() aligns with updated ConfigurationData.
composition/src/utils/string-constants.ts (2)
106-106: New directive constant PROTECTED LGTMName aligns with directive usage elsewhere.
169-169: PROTECTED fully integrated — LGTMAll references to PROTECTED are present and correctly wired through the inheritance mechanism:
- The INHERITABLE_DIRECTIVE_NAMES set in composition/src/utils/string-constants.ts now includes PROTECTED, and this is the same set consumed by the v1 normalization factory to filter out inherited directives.
- PROTECTED is declared in the v1 constants (composition/src/v1/utils/constants.ts) and has its corresponding PROTECTED_DEFINITION and PROTECTED_DEFINITION_DATA in directive-definition-data.ts, ensuring it’s recognized as a first-class directive.
- The normalization pipeline (walkers.ts and normalization-factory.ts) both reference PROTECTED when tracking parent protection state, auto-injecting the directive where needed, and adding its definition in generated output.
No further changes required. Approved.
composition/src/schema-building/utils.ts (1)
261-263: Verification complete: Type guard relocation and imports are correct
- No occurrences of the old predicate
isParentDataInterfaceTyperemain in composition/src.- In composition/src/v1/normalization/walkers.ts,
isInterfaceDefinitionDatais imported from../../schema-building/utils(lines 24–28).composition/src/subgraph/types.ts (2)
9-9: Importing TypeName is appropriate.
Aligns this module with the new keyed-by-TypeName maps.
18-21: Switch to Map<TypeName, …> looks good.
TypeName aliases string, so this is type-safe and non-breaking.composition/src/router-configuration/types.ts (2)
1-1: Stronger typing via FieldName/TypeName import is correct.
Improves clarity without runtime impact.
77-81: RequiredFieldConfiguration.fieldName → FieldName is fine.
Alias to string; call sites should already type-check.shared/src/router-config/graphql-configuration.ts (1)
128-128: Constructor arg order change is harmless.
Object-literal init ignores order; usage is correct.connect/src/wg/cosmo/node/v1/node_pb.ts (2)
1117-1118: FieldList updated with tag 4 — backward compatible.
No wire conflicts; older readers ignore unknown field.
1101-1105: Verified generated field:protectedFieldNames
Theprotected_field_names = 4;declaration innode.protoand the generation marker innode_pb.tsconfirm this is an auto-generated field. No manual edits are needed.•
node.proto(line 144):repeated string protected_field_names = 4;
•connect/src/wg/cosmo/node/v1/node_pb.ts(line 1):// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"composition/src/v1/federation/federation-factory.ts (1)
234-234: Importing FieldName is fine.
Prepares for protectedFieldNames typing.composition/src/v1/utils/constants.ts (1)
101-102: Import of PROTECTED constant looks correct.Matches downstream usages and directive definition.
composition/src/v1/normalization/directive-definition-data.ts (1)
444-452: Directive definition data for PROTECTED is consistent.No args, repeatable, FIELD_DEFINITION | OBJECT, and wired to PROTECTED_DEFINITION.
composition/tests/v1/utils/utils.ts (1)
37-45: Test fixture for base definitions with PROTECTED is accurate.Locations and repeatable match the implementation.
composition/src/v1/normalization/walkers.ts (3)
528-530: Resetting isParentObjectProtected on leave is correct.Prevents bleed-over between object scopes.
Also applies to: 554-556
26-27: Switch to isInterfaceDefinitionData is appropriate.Keeps interface parents excluded from object-only inheritance paths.
42-43: Import of PROTECTED constant aligns with new usage.All good.
composition/src/v1/normalization/utils.ts (1)
50-51: Wiring PROTECTED into directive-definition catalog is correct.Ensures validation and extraction treat it as first-class.
Also applies to: 74-75, 409-410
composition/tests/v1/directives/protected.test.ts (3)
18-49: Solid coverage for field-level propagation.Assertions for router SDL and per-subgraph ConfigurationData look correct.
271-291: Great: explicit check of subgraph SDL with baseDirectiveDefinitionsWithProtected.This precisely validates inclusion of the PROTECTED directive definition when referenced.
292-337: Map/Set expectations are clear and deterministic.Using Set for fieldNames and Array for protectedFieldNames matches router-configuration types.
composition/src/v1/normalization/normalization-factory.ts (4)
3344-3346: Keep single-source emission here.Centralizing PROTECTED_DEFINITION emission in normalize() is correct.
1261-1264: Good: safer nullish coalescing when extracting parent directives.Prevents accidental fallback when an empty Map is valid.
566-573: Inheritance of PROTECTED to fields is correct.Adding the directive when the parent object is protected aligns with the intended semantics.
361-362: Type import used appropriately.Using FieldName for the per-object Set is consistent with downstream types.
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
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
composition/src/v1/normalization/normalization-factory.ts(10 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
composition/src/v1/normalization/normalization-factory.ts (4)
composition/src/utils/string-constants.ts (1)
PROTECTED(106-106)composition/src/utils/utils.ts (1)
generateSimpleDirective(159-164)composition/src/types/types.ts (1)
FieldName(3-3)composition/src/v1/utils/constants.ts (1)
PROTECTED_DEFINITION(663-668)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (16)
- GitHub Check: build-router
- GitHub Check: build_test
- GitHub Check: integration_test (./events)
- GitHub Check: build_push_image (nonroot)
- GitHub Check: build_push_image
- GitHub Check: build_push_image
- GitHub Check: build_test
- GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
- GitHub Check: image_scan (nonroot)
- GitHub Check: image_scan
- GitHub Check: integration_test (./telemetry)
- GitHub Check: build_test
- GitHub Check: build_push_image
- GitHub Check: build_test
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (go)
🔇 Additional comments (7)
composition/src/v1/normalization/normalization-factory.ts (7)
3329-3333: Gated LINK directive emission: LGTM.Reintroducing LINK_DEFINITION/IMPORT/PURPOSE only when LINK is referenced is consistent with prior patterns.
1263-1264: Nullish coalescing for parent directives: LGTM.Safer than || for existing empty maps.
67-68: Imports wired correctly.PROTECTED_DEFINITION, PROTECTED, and FieldName imports align with their usages.
Also applies to: 307-308, 361-362
3340-3343: ✅ Single PROTECTED_DEFINITION emission verifiedRipgrep search for
definitions.push(PROTECTED_DEFINITION)returns exactly one match:
- composition/src/v1/normalization/normalization-factory.ts:3341
No other occurrences found, so there are no duplicate directive definitions.
566-573: Resolved:INHERITABLE_DIRECTIVE_NAMESalready includesPROTECTED.The grep output confirms that in
composition/src/utils/string-constants.tsline 169,INHERITABLE_DIRECTIVE_NAMESis defined as:export const INHERITABLE_DIRECTIVE_NAMES = new Set<string>([EXTERNAL, PROTECTED, SHAREABLE]);Since
PROTECTEDis already present, no changes are needed.
3475-3477: Config propagation verified – TheprotectedFieldNamesarray is correctly consumed downstream in the router configuration:• In
shared/src/router-config/graphql-configuration.ts(lines 132–134), the code checks fordata.protectedFieldNames.length > 0and spreads it intotypeField.protectedFieldNames: string[].
• The generated protobuf definitions (.pb.tsand Go code) exposeprotectedFieldNamesasstring[].No further action needed.
1302-1303: Protected fields are populated end-to-end
- In the normalization walker (composition/src/v1/normalization/walkers.ts:372), protected fields are added to the parent’s set when
@protectedis present:
parentData.protectedFieldNames.add(fieldName);- The factory then spreads these into the configuration object (normalization-factory.ts), ensuring the set is carried forward.
- Finally, in the GraphQL router config (shared/src/router-config/graphql-configuration.ts:133), the protection set is applied to each field:
typeField.protectedFieldNames = [...data.protectedFieldNames];All population steps—from directive detection to final configuration—are in place.
|
@Aenimus should we review this PR as it is or some additional work needs to be done here? |
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: 4
🧹 Nitpick comments (3)
proto/wg/cosmo/node/v1/node.proto (1)
140-145: Additive proto change looks good; add brief comment for clarity.Adding require_fetch_reasons_field_names = 4 is backward-compatible and aligns with generated TS. Consider documenting intended semantics on this field for future readers.
composition/tests/v1/directives/require-fetch-reasons.test.ts (1)
18-339: Solid positive-path coverage; add a couple of negative tests.Consider adding:
- misuse on unsupported locations (e.g., INTERFACE/INPUT_OBJECT) → expect composition to fail with invalid location.
- repeatable application on the same field (twice) → expect no duplication in config (still one field entry).
Low effort, increases guardrail coverage.
I can draft these tests if you want.
composition/src/v1/normalization/normalization-factory.ts (1)
3475-3477: Deterministic ordering for requireFetchReasonsFieldNames.For stable configs across runs, sort before assigning.
Apply:
- if (isObject && parentData.requireFetchReasonsFieldNames.size > 0) { - configurationData.requireFetchReasonsFieldNames = [...parentData.requireFetchReasonsFieldNames]; + if (isObject && parentData.requireFetchReasonsFieldNames.size > 0) { + configurationData.requireFetchReasonsFieldNames = [...parentData.requireFetchReasonsFieldNames].sort(); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (2)
connect-go/gen/proto/wg/cosmo/node/v1/node.pb.gois excluded by!**/*.pb.go,!**/gen/**router/gen/proto/wg/cosmo/node/v1/node.pb.gois excluded by!**/*.pb.go,!**/gen/**
📒 Files selected for processing (14)
composition/src/router-configuration/types.ts(2 hunks)composition/src/schema-building/types.ts(1 hunks)composition/src/utils/string-constants.ts(2 hunks)composition/src/v1/federation/federation-factory.ts(2 hunks)composition/src/v1/normalization/directive-definition-data.ts(5 hunks)composition/src/v1/normalization/normalization-factory.ts(10 hunks)composition/src/v1/normalization/utils.ts(3 hunks)composition/src/v1/normalization/walkers.ts(5 hunks)composition/src/v1/utils/constants.ts(5 hunks)composition/tests/v1/directives/require-fetch-reasons.test.ts(1 hunks)composition/tests/v1/utils/utils.ts(1 hunks)connect/src/wg/cosmo/node/v1/node_pb.ts(4 hunks)proto/wg/cosmo/node/v1/node.proto(1 hunks)shared/src/router-config/graphql-configuration.ts(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
- composition/src/utils/string-constants.ts
- composition/src/v1/federation/federation-factory.ts
- composition/src/router-configuration/types.ts
- composition/tests/v1/utils/utils.ts
- composition/src/schema-building/types.ts
🧰 Additional context used
🧬 Code graph analysis (7)
composition/src/v1/utils/constants.ts (2)
composition/src/utils/string-constants.ts (3)
REQUIRE_FETCH_REASONS(106-106)FIELD_DEFINITION_UPPER(50-50)OBJECT_UPPER(99-99)composition/src/ast/utils.ts (2)
stringArrayToNameNodeArray(84-90)stringToNameNode(77-82)
composition/src/v1/normalization/utils.ts (2)
composition/src/utils/string-constants.ts (1)
REQUIRE_FETCH_REASONS(106-106)composition/src/v1/normalization/directive-definition-data.ts (1)
REQUIRE_FETCH_REASONS_DEFINITION_DATA(444-452)
shared/src/router-config/graphql-configuration.ts (1)
connect/src/wg/cosmo/node/v1/node_pb.ts (1)
TypeField(1092-1142)
composition/src/v1/normalization/normalization-factory.ts (4)
composition/src/utils/string-constants.ts (5)
REQUIRE_FETCH_REASONS(106-106)SHAREABLE(128-128)LINK(76-76)CONFIGURE_DESCRIPTION(13-13)CONFIGURE_CHILD_DESCRIPTIONS(14-14)composition/src/utils/utils.ts (1)
generateSimpleDirective(159-164)composition/src/types/types.ts (1)
FieldName(3-3)composition/src/v1/utils/constants.ts (6)
LINK_DEFINITION(609-642)LINK_IMPORT_DEFINITION(586-589)LINK_PURPOSE_DEFINITION(591-606)CONFIGURE_DESCRIPTION_DEFINITION(918-956)CONFIGURE_CHILD_DESCRIPTIONS_DEFINITION(963-983)REQUIRE_FETCH_REASONS_DEFINITION(663-668)
composition/src/v1/normalization/directive-definition-data.ts (3)
composition/src/schema-building/types.ts (2)
DirectiveDefinitionData(41-50)ArgumentData(30-34)composition/src/utils/string-constants.ts (3)
FIELD_DEFINITION_UPPER(50-50)OBJECT_UPPER(99-99)REQUIRE_FETCH_REASONS(106-106)composition/src/v1/utils/constants.ts (1)
REQUIRE_FETCH_REASONS_DEFINITION(663-668)
composition/src/v1/normalization/walkers.ts (2)
composition/src/schema-building/utils.ts (1)
isInterfaceDefinitionData(261-263)composition/src/utils/string-constants.ts (2)
EXTERNAL(42-42)REQUIRE_FETCH_REASONS(106-106)
composition/tests/v1/directives/require-fetch-reasons.test.ts (7)
composition/tests/utils/utils.ts (3)
federateSubgraphsSuccess(59-72)schemaToSortedNormalizedString(27-29)normalizeString(19-21)composition/src/router-compatibility-version/router-compatibility-version.ts (1)
ROUTER_COMPATIBILITY_VERSION_ONE(3-3)composition/tests/v1/utils/utils.ts (3)
versionOneRouterDefinitions(106-106)schemaQueryDefinition(84-87)baseDirectiveDefinitionsWithRequireFetchReasons(37-45)composition/src/types/types.ts (2)
TypeName(9-9)FieldName(3-3)composition/src/router-configuration/types.ts (1)
ConfigurationData(83-95)composition/src/utils/string-constants.ts (1)
QUERY(110-110)composition/src/ast/utils.ts (1)
parse(272-274)
🪛 GitHub Actions: wgc CI
connect/src/wg/cosmo/node/v1/node_pb.ts
[error] 3-18: Git diff check failed. Differences detected in connect/src/wg/cosmo/node/v1/node_pb.ts (exit code 1). Command: 'git diff --no-ext-diff --exit-code'.
🪛 GitHub Actions: Composition CI
connect/src/wg/cosmo/node/v1/node_pb.ts
[error] 3-9: Command 'git diff --no-ext-diff --exit-code' failed (exit code 1) due to unstaged changes in connect/src/wg/cosmo/node/v1/node_pb.ts (top import block).
[error] 2783-2789: Command 'git diff --no-ext-diff --exit-code' failed (exit code 1) due to unstaged changes in connect/src/wg/cosmo/node/v1/node_pb.ts (GraphQLSubscriptionConfiguration docblock).
🪛 GitHub Actions: Shared CI
connect/src/wg/cosmo/node/v1/node_pb.ts
[error] 3-11: git diff --no-ext-diff --exit-code failed: exit code 1 due to differences in the working tree (connect/src/wg/cosmo/node/v1/node_pb.ts).
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
- GitHub Check: build-router
- GitHub Check: Analyze (go)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
- GitHub Check: integration_test (./events)
- GitHub Check: image_scan
- GitHub Check: build_push_image
- GitHub Check: integration_test (./telemetry)
- GitHub Check: build_push_image
- GitHub Check: build_push_image (nonroot)
- GitHub Check: image_scan (nonroot)
- GitHub Check: build_test
- GitHub Check: build_push_image
🔇 Additional comments (20)
shared/src/router-config/graphql-configuration.ts (2)
30-30: Import change is fine.Including PROVIDER_TYPE_REDIS here is consistent with usage below.
126-135: Remove unnecessary Set guard
requireFetchReasonsFieldNamesis defined asFieldName[]inrouter-configuration/types.ts(line 93), so it can never be aSetand the existing.lengthcheck and spread are safe.Likely an incorrect or invalid review comment.
connect/src/wg/cosmo/node/v1/node_pb.ts (1)
1108-1112: TypeField: generated property and field descriptor match proto.requireFetchReasonsFieldNames and tag no. 4 align with the proto. No issues.
Also applies to: 1121-1125
composition/src/v1/utils/constants.ts (3)
23-25: New string constants imported: OK.
40-42: EDFS Redis imports: OK.
76-77: Import of REQUIRE_FETCH_REASONS: OK.composition/src/v1/normalization/walkers.ts (4)
25-26: Updated type guard import: OK.
43-44: Import directive name constant: OK.
366-374: Correctly track fields requiring fetch reasons.Adding the field name when the parent object or field is annotated is the right spot; limited to non-interface parents. Looks good.
If not already, ensure ObjectDefinitionData initializes requireFetchReasonsFieldNames = new Set() in upsertObjectDataByNode.
528-529: State reset on object leaves: OK.Clearing doesParentObjectRequireFetchReasons avoids leakage across objects.
Also applies to: 554-555
composition/src/v1/normalization/directive-definition-data.ts (2)
23-23: Wiring in REQUIRE_FETCH_REASONS definition — looks good.Import added correctly and consistent with usage below.
444-452: Directive data for @openfed__requireFetchReasons — correct shape and locations.
- repeatable: true
- locations: FIELD_DEFINITION, OBJECT
- no args
All aligned with the constant definition.
composition/src/v1/normalization/utils.ts (1)
409-410: Include REQUIRE_FETCH_REASONS in the initialization map.Good addition; ensures normalization recognizes and validates the directive.
composition/tests/v1/directives/require-fetch-reasons.test.ts (1)
341-485: Subgraph fixtures are clear and target the propagation matrix well.Nice spread of object-level, extension-level, and mixed cases across multiple subgraphs.
composition/src/v1/normalization/normalization-factory.ts (6)
566-574: Correct inheritance: object-level @openfed__requireFetchReasons applied to fields.This mirrors existing EXTERNAL/SHAREABLE inheritance logic.
1299-1306: Track field names on the parent object — good.requireFetchReasonsFieldNames: Set() is the right container for later emission.
3330-3333: Emitting LINK only when referenced — good optimization.*This avoids unnecessary SDL noise.
3341-3342: Conditionally emit REQUIRE_FETCH_REASONS_DEFINITION — correct.Keeps SDL minimal while enabling the directive when used.
1299-1306: Resolved: walkers.ts includesparentData.requireFetchReasonsFieldNames.add(fieldName)(L371–372), ensuring annotated or inherited fields are recorded.
3341-3342: No action needed:INHERITABLE_DIRECTIVE_NAMESalready includesREQUIRE_FETCH_REASONS(composition/src/utils/string-constants.ts:169).
Updates ENG-7769
Summary by CodeRabbit
New Features
Refactor
Tests
Checklist