Skip to content

Conversation

@Aenimus
Copy link
Member

@Aenimus Aenimus commented Nov 17, 2025

Summary by CodeRabbit

  • Refactor

    • Renamed directive map fields to a consistent name across composition and federation surfaces; aligned related type names for consistency (no behavioral changes).
  • New Features

    • Subgraph metadata now includes a URL field and stronger typed identifiers.
  • Tests

    • Added extensive normalization and federation tests with new fixtures covering schema generation and boilerplate-field handling.
  • Chores

    • Adjusted public exports: added parsing helpers and removed/renamed a few legacy exports.

Checklist

  • I have discussed my proposed changes in an issue and have received approval to proceed.
  • I have followed the coding standards of the project.
  • Tests or benchmarks have been added or updated.
  • Documentation has been updated on https://github.com/wundergraph/cosmo-docs.
  • I have read the Contributors Guide.

@coderabbitai
Copy link

coderabbitai bot commented Nov 17, 2025

Walkthrough

Renames directive-tracking maps and parameters from directivesByDirectiveName to directivesByName across composition, updates related types to use typed name aliases (e.g., TypeName, SubgraphName, FieldName), adjusts normalization to permit SchemaExtensionNode returns, and updates imports/tests/exports accordingly.

Changes

Cohort / File(s) Change Summary
Core directive map rename & types
composition/src/federation/types.ts, composition/src/schema-building/types.ts, composition/src/subgraph/types.ts, composition/src/v1/normalization/params.ts
Replaced directivesByDirectiveName with directivesByName and updated map value types to Array<ConstDirectiveNode>; refined key/value types to typed aliases (TypeName, SubgraphName, FieldName, DirectiveName, etc.). Added url to InternalSubgraph.
Schema-building utils & helpers
composition/src/schema-building/utils.ts
Updated initializers, helper functions, and signatures to accept/use directivesByName: Map<DirectiveName, Array<ConstDirectiveNode>>; migrated all internal iterations/sets/checks to directivesByName.
Normalization core & walkers
composition/src/v1/normalization/normalization-factory.ts, composition/src/v1/normalization/walkers.ts, composition/src/v1/normalization/params.ts
Replaced all usages/signatures naming directivesByDirectiveNamedirectivesByName; updated functions like extractDirectives, getValidFlattenedDirectiveArray, getNodeExtensionType; getSchemaNodeByData may return `SchemaDefinitionNode
Federation v1 factory
composition/src/v1/federation/federation-factory.ts
Replaced read/write/merge of persisted-directive maps to directivesByName across copy/upsert/propagation/extraction paths and updated related method signatures.
Imports adjustments
composition/src/subgraph/types.ts, composition/src/v1/federation/params.ts, composition/tests/v1/utils/utils.ts
Consolidated/changed GraphQL imports (moved SchemaDefinitionNode/SchemaExtensionNode into top-level graphql import; combined/import order tweaks).
Tests & public exports
composition/tests/v1/federation-factory.test.ts, composition/tests/v1/normalization.test.ts, composition/tests/v1/types/objects.test.ts, composition/tests/v1/utils/utils.ts
Updated tests/fixtures to reflect rename and normalization changes; removed stringToNameNode export usage; added/changed exports parse and stringToNamedTypeNode in public surface; adjusted expectations and fixtures.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

  • Mechanical, pervasive renames lower per-file cognitive load, but changes span interacting subsystems (normalization, federation, schema-building, tests).
  • Verify consistent renames across all call sites and exported signatures.
  • Confirm no runtime behavior regressions where typed aliases replaced plain strings.

Areas needing extra attention:

  • composition/src/v1/normalization/normalization-factory.ts — complex directive handling and getSchemaNodeByData return-shape changes.
  • composition/src/schema-building/utils.ts — many helper signatures and edge-case directive flows.
  • Tests / public exports — ensure added/removed exports (e.g., stringToNameNode, stringToNamedTypeNode, parse) align with package entry points.

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'chore: change how schema node is propagated' is vague and generic. It uses non-specific language ('change how') that doesn't convey meaningful information about what was actually changed. Provide a more specific title that clearly describes the main changes, such as 'refactor: rename directivesByDirectiveName to directivesByName across federation and normalization' or similar.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 13b2438 and b686a43.

📒 Files selected for processing (7)
  • composition/src/federation/types.ts (1 hunks)
  • composition/src/schema-building/utils.ts (11 hunks)
  • composition/src/subgraph/types.ts (2 hunks)
  • composition/src/v1/federation/params.ts (1 hunks)
  • composition/src/v1/normalization/params.ts (1 hunks)
  • composition/tests/v1/types/objects.test.ts (2 hunks)
  • composition/tests/v1/utils/utils.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • composition/src/v1/normalization/params.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-08T20:57:07.946Z
Learnt from: JivusAyrus
Repo: wundergraph/cosmo PR: 2156
File: controlplane/src/core/repositories/SubgraphRepository.ts:1746-1763
Timestamp: 2025-09-08T20:57:07.946Z
Learning: The checkSubgraphSchema.ts file already correctly implements linked subgraph functionality, using byName(linkedSubgraph.name, linkedSubgraph.namespace) to fetch target subgraphs and properly handles parse(newSchemaSDL) for schema building. The implementation doesn't need fixes for byId usage or schema parsing as it's already correct.

Applied to files:

  • composition/tests/v1/types/objects.test.ts
  • composition/src/subgraph/types.ts
🧬 Code graph analysis (3)
composition/src/federation/types.ts (2)
composition/src/types/types.ts (3)
  • SubgraphName (9-9)
  • DirectiveName (3-3)
  • TypeName (11-11)
composition/src/schema-building/types.ts (1)
  • ConfigureDescriptionData (36-39)
composition/src/subgraph/types.ts (1)
composition/src/schema-building/types.ts (1)
  • ParentDefinitionData (242-248)
composition/src/schema-building/utils.ts (3)
composition/src/types/types.ts (1)
  • DirectiveName (3-3)
composition/src/utils/string-constants.ts (5)
  • EXTERNAL (48-48)
  • SHAREABLE (137-137)
  • AUTHENTICATED (8-8)
  • REQUIRES_SCOPES (124-124)
  • INACCESSIBLE (67-67)
composition/src/utils/utils.ts (1)
  • generateSimpleDirective (171-176)
⏰ 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). (15)
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: build_test
  • GitHub Check: image_scan
  • GitHub Check: build_push_image (nonroot)
  • GitHub Check: integration_test (./telemetry)
  • GitHub Check: image_scan (nonroot)
  • GitHub Check: build_push_image
  • GitHub Check: integration_test (./events)
  • GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
  • GitHub Check: build_push_image
  • GitHub Check: build_test
  • GitHub Check: build_push_image
  • GitHub Check: build_test
  • GitHub Check: build_test
🔇 Additional comments (17)
composition/tests/v1/types/objects.test.ts (2)

242-245: Good documentation of edge case behavior.

The comment clearly explains why empty Query root types are valid in Federation, providing helpful context for this potentially surprising test case.


258-261: Good documentation of edge case behavior.

The comment clearly explains why renamed empty Query root types are valid, maintaining consistency with the previous test's documentation.

composition/tests/v1/utils/utils.ts (1)

2-2: LGTM! Standard import consolidation.

The import path change from 'graphql/index' to 'graphql' aligns with standard GraphQL package usage and improves consistency across the codebase.

composition/src/federation/types.ts (1)

63-66: LGTM! Improved type safety with aliased types.

The rename from directivesByDirectiveName to directivesByName is clearer and more concise. Using typed aliases (SubgraphName, TypeName, DirectiveName) instead of raw strings provides better type documentation and consistency across the codebase.

composition/src/subgraph/types.ts (3)

1-8: LGTM! Standard import consolidation.

Consolidating GraphQL imports from 'graphql/index' to 'graphql' follows the standard package usage pattern and improves consistency.


40-44: LGTM! Type aliases improve code clarity.

Using FieldName, SubgraphName, and TypeName type aliases instead of raw strings provides better type documentation and makes the code more self-documenting.


18-22: No actionable changes needed - url field requirement is enforced by TypeScript.

The url field is declared as a required (non-optional) property in the Subgraph type definition at composition/src/subgraph/types.ts. TypeScript's type system automatically enforces that all Subgraph object instantiations must include this field at compile time. Any code attempting to create a Subgraph without a url field would fail compilation. All visible instantiations throughout the codebase (in tests and source) correctly provide the url field. No unsafe patterns like unchecked type assertions or bypasses were detected.

composition/src/v1/federation/params.ts (2)

3-3: LGTM! Import consolidation aligned with project standards.

Consolidating the GraphQL imports follows the standard package usage pattern.


11-14: LGTM! Consistent field rename with improved clarity.

The rename from directivesByDirectiveName to directivesByName is more concise and aligns with the broader refactoring across the codebase. The use of Array<ConstDirectiveNode> instead of ConstDirectiveNode[] provides consistency.

composition/src/schema-building/utils.ts (8)

86-93: LGTM! Clear field rename in factory function.

The rename from directivesByDirectiveName to directivesByName in the newPersistedDirectivesData factory function is more concise and aligns with the broader refactoring pattern.


100-123: LGTM! Parameter rename improves function clarity.

The parameter rename from directivesByDirectiveName to directivesByName in isNodeExternalOrShareable is cleaner and more concise. The function logic remains unchanged.


224-273: LGTM! Consistent directive map access pattern.

The updates to use directivesByName in propagateFieldDataArguments and childMapToValueArray maintain the existing logic while following the new naming convention.


339-369: LGTM! Authorization directive propagation updated consistently.

Both propagateAuthDirectives and propagateFieldAuthDirectives now correctly write to directivesByName instead of the old field name, maintaining the same behavior.


388-411: LGTM! Helper function signature updated consistently.

The getValidFlattenedPersistedDirectiveNodeArray function parameters are renamed to directivesByName and persistedDirectiveDefinitionByName for consistency. The function logic remains correct.


413-431: LGTM! Router directive handling updated correctly.

getRouterPersistedDirectiveNodes now accesses directivesByName consistently with the refactoring. The logic for gathering persisted directives is unchanged.


433-455: LGTM! Client directive filtering maintains behavior.

The getClientPersistedDirectiveNodes function now iterates over directivesByName and correctly filters for client-facing directives (@deprecated, @oneOf, @semanticNonNull).


655-657: LGTM! Inaccessible check updated for both directive sources.

The isNodeDataInaccessible function correctly checks both data.persistedDirectivesData.directivesByName and data.directivesByName for the inaccessible directive.


Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Nov 17, 2025

Router-nonroot image scan passed

✅ No security vulnerabilities found in image:

ghcr.io/wundergraph/cosmo/router:sha-2454665ef35bfa21d1b88f965e8595d39b1b957f-nonroot

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
composition/src/subgraph/types.ts (1)

1-8: Imports and schemaNode typing look correct.

Top-level graphql imports are preferred and the union SchemaDefinitionNode | SchemaExtensionNode is appropriate. Minor consistency nit: InternalSubgraph.name is a string while Subgraph.name is SubgraphName. Consider aligning for type clarity.

 export type InternalSubgraph = {
@@
-  name: string;
+  name: SubgraphName;

Also, double-check there are no lingering from 'graphql/index' imports elsewhere.

Also applies to: 30-31, 47-47

composition/tests/v1/types/objects.test.ts (1)

242-246: Stylistic: place test on a new line after the block comment.

*/ test('...') on the same line is valid but harms readability. Move test( to the next line.

Also applies to: 258-262

composition/src/federation/types.ts (1)

64-69: Use domain-specific key types in maps.

Prefer DirectiveName and SubgraphName over raw string for stronger intent and consistency with other types.

 export type MutualParentDefinitionData = {
-  configureDescriptionDataBySubgraphName: Map<string, ConfigureDescriptionData>;
-  directivesByName: Map<string, ConstDirectiveNode[]>;
+  configureDescriptionDataBySubgraphName: Map<SubgraphName, ConfigureDescriptionData>;
+  directivesByName: Map<DirectiveName, ConstDirectiveNode[]>;
   extensionType: ExtensionType;
   name: string;
   persistedDirectivesData: PersistedDirectivesData;
   description?: StringValueNode;
 };
composition/src/v1/normalization/walkers.ts (1)

206-207: Rename looks good; consider typing directive maps by DirectiveName.

The migration to directivesByName is consistent. Optional: initialize with new Map<DirectiveName, ConstDirectiveNode[]>() (and import DirectiveName) to encode intent and catch key-type mistakes early.

Also applies to: 211-212, 271-272, 333-347, 351-354

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 94519ce and 80da660.

📒 Files selected for processing (11)
  • composition/src/federation/types.ts (1 hunks)
  • composition/src/schema-building/types.ts (10 hunks)
  • composition/src/schema-building/utils.ts (11 hunks)
  • composition/src/subgraph/types.ts (1 hunks)
  • composition/src/v1/federation/federation-factory.ts (23 hunks)
  • composition/src/v1/normalization/normalization-factory.ts (38 hunks)
  • composition/src/v1/normalization/params.ts (1 hunks)
  • composition/src/v1/normalization/walkers.ts (3 hunks)
  • composition/tests/v1/federation-factory.test.ts (0 hunks)
  • composition/tests/v1/normalization.test.ts (4 hunks)
  • composition/tests/v1/types/objects.test.ts (2 hunks)
💤 Files with no reviewable changes (1)
  • composition/tests/v1/federation-factory.test.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-08T20:57:07.946Z
Learnt from: JivusAyrus
Repo: wundergraph/cosmo PR: 2156
File: controlplane/src/core/repositories/SubgraphRepository.ts:1746-1763
Timestamp: 2025-09-08T20:57:07.946Z
Learning: The checkSubgraphSchema.ts file already correctly implements linked subgraph functionality, using byName(linkedSubgraph.name, linkedSubgraph.namespace) to fetch target subgraphs and properly handles parse(newSchemaSDL) for schema building. The implementation doesn't need fixes for byId usage or schema parsing as it's already correct.

Applied to files:

  • composition/src/subgraph/types.ts
  • composition/tests/v1/types/objects.test.ts
  • composition/tests/v1/normalization.test.ts
  • composition/src/v1/normalization/normalization-factory.ts
🧬 Code graph analysis (7)
composition/src/v1/normalization/params.ts (1)
composition/src/types/types.ts (1)
  • DirectiveName (3-3)
composition/src/v1/normalization/walkers.ts (2)
composition/src/schema-building/types.ts (1)
  • InputValueData (134-155)
composition/src/utils/string-constants.ts (2)
  • PROVIDES (115-115)
  • REQUIRES (123-123)
composition/src/schema-building/types.ts (1)
composition/src/types/types.ts (2)
  • DirectiveName (3-3)
  • SubgraphName (9-9)
composition/src/v1/federation/federation-factory.ts (3)
composition/src/utils/string-constants.ts (3)
  • SUBSCRIPTION_FILTER (147-147)
  • ONE_OF (104-104)
  • INACCESSIBLE (67-67)
composition/src/utils/utils.ts (3)
  • copyArrayValueMap (247-253)
  • getValueOrDefault (153-161)
  • generateSimpleDirective (171-176)
composition/src/schema-building/utils.ts (1)
  • newPersistedDirectivesData (86-93)
composition/tests/v1/normalization.test.ts (6)
composition/tests/utils/utils.ts (3)
  • normalizeSubgraphSuccess (36-46)
  • schemaToSortedNormalizedString (23-25)
  • 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 (1)
  • KEY_DIRECTIVE (67-69)
composition/src/ast/utils.ts (2)
  • stringToNamedTypeNode (100-105)
  • parse (272-274)
composition/src/utils/string-constants.ts (1)
  • QUERY (117-117)
composition/src/subgraph/types.ts (1)
  • Subgraph (18-22)
composition/src/v1/normalization/normalization-factory.ts (5)
composition/src/utils/string-constants.ts (10)
  • INACCESSIBLE (67-67)
  • REQUIRE_FETCH_REASONS (122-122)
  • EXTERNAL (48-48)
  • SHAREABLE (137-137)
  • EXTENDS (49-49)
  • CONFIGURE_DESCRIPTION (16-16)
  • KEY (80-80)
  • INTERFACE_OBJECT (79-79)
  • ONE_OF (104-104)
  • SCHEMA (128-128)
composition/src/v1/normalization/params.ts (1)
  • HandleFieldInheritableDirectivesParams (10-15)
composition/src/schema-building/types.ts (7)
  • FieldData (97-118)
  • ObjectDefinitionData (174-191)
  • EnumValueData (73-85)
  • InputValueData (134-155)
  • EnumDefinitionData (58-71)
  • SchemaData (221-227)
  • UnionDefinitionData (229-240)
composition/src/schema-building/utils.ts (1)
  • isNodeExternalOrShareable (100-123)
composition/src/ast/utils.ts (1)
  • stringToNamedTypeNode (100-105)
composition/src/schema-building/utils.ts (3)
composition/src/types/types.ts (1)
  • DirectiveName (3-3)
composition/src/utils/string-constants.ts (5)
  • EXTERNAL (48-48)
  • SHAREABLE (137-137)
  • AUTHENTICATED (8-8)
  • REQUIRES_SCOPES (124-124)
  • INACCESSIBLE (67-67)
composition/src/utils/utils.ts (1)
  • generateSimpleDirective (171-176)
⏰ 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). (15)
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: build_push_image
  • GitHub Check: build_test
  • GitHub Check: image_scan (nonroot)
  • GitHub Check: image_scan
  • GitHub Check: build_push_image
  • GitHub Check: build_push_image (nonroot)
  • GitHub Check: integration_test (./telemetry)
  • GitHub Check: integration_test (./events)
  • GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
  • GitHub Check: build_test
  • GitHub Check: build_push_image
  • GitHub Check: build_test
  • GitHub Check: build_test
🔇 Additional comments (4)
composition/src/v1/normalization/params.ts (1)

11-11: Rename applied; verify call sites.

directivesByName matches the project-wide change. Please ensure all invocations of handleFieldInheritableDirectives now pass directivesByName.

composition/src/v1/federation/federation-factory.ts (1)

339-343: Directive propagation refactor LGTM.

Map-based persisted-directive extraction/flattening is consistent with the rename and preserves behavior (non-repeatable handling, tag/deprecated, semanticNonNull). No blocking issues spotted.

To be safe, scan the repo for any remaining directivesByDirectiveName or OperationTypeNode. usages and old graphql/index imports.

Also applies to: 651-652, 685-686, 980-989, 999-1011, 1059-1067, 1076-1101, 1818-1821

composition/src/schema-building/types.ts (1)

61-61: Type surface updated consistently.

All definition data now expose directivesByName: Map<DirectiveName, Array<ConstDirectiveNode>>. This aligns types across normalization/federation. Looks good.

Also applies to: 76-76, 100-100, 122-122, 136-136, 159-160, 176-176, 204-205, 211-212, 222-223, 231-232

composition/tests/v1/normalization.test.ts (1)

63-63: Ignore this review comment—OperationTypeNode is a valid runtime value in graphql v16.9.0.

The composition package uses "graphql": "^16.9.0", and starting in graphql-js v16 (16.0.0), OperationTypeNode was exported as a runtime value (an enum-like object with members QUERY, MUTATION, SUBSCRIPTION). The current code using OperationTypeNode.QUERY is correct and does not yield undefined at runtime. No changes are required.

Likely an incorrect or invalid review comment.

@Aenimus Aenimus enabled auto-merge (squash) November 17, 2025 21:07
@Aenimus Aenimus merged commit 6c49302 into main Nov 17, 2025
33 checks passed
@Aenimus Aenimus deleted the david/eng-8464-fix-schema-node branch November 17, 2025 21:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants