fix: failing composition for contract schemas (#6685)

This commit is contained in:
Laurin Quast 2025-04-01 15:19:22 +02:00 committed by GitHub
parent 0e05049d91
commit a107ad363b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 53 additions and 16 deletions

View file

@ -0,0 +1,5 @@
---
'hive': patch
---
Fix failing schema contract composition.

View file

@ -348,3 +348,47 @@ test('failed contract composition has errors and no sdl and supergraph', async (
expect(result.contracts?.[0].supergraph).toEqual(null);
expect(result.contracts?.[0].errors).toBeDefined();
});
test('type is marked as inaccessible if all fields are inaccessible and the type is not used', async () => {
const result = await client.composeAndValidate.mutate({
type: 'federation',
native: true,
schemas: [
{
raw: /* GraphQL */ `
extend schema
@link(url: "https://specs.apollo.dev/link/v1.0")
@link(url: "https://specs.apollo.dev/federation/v2.8", import: ["@tag"])
type Query {
hello: String @tag(name: "public")
}
type Brr {
a: String
b: String
c: String
}
`,
source: 'foo.graphql',
url: null,
},
],
external: null,
contracts: [
{
id: 'foo',
filter: {
removeUnreachableTypesFromPublicApiSchema: true,
exclude: null,
include: ['public'],
},
},
],
});
expect(result.contracts?.[0].errors).toEqual([]);
expect(result.contracts?.[0].supergraph).toContain(
'type Brr @join__type(graph: FOO_GRAPHQL) @inaccessible {',
);
});

View file

@ -31,10 +31,9 @@ import {
} from './lib/compose';
import { CompositionErrorSource, errorWithSource, toValidationError } from './lib/errors';
import {
applyTagFilterToInaccessibleTransformOnSubgraphSchema,
applyTagFilterOnSubgraphs,
createTagDirectiveNameExtractionStrategy,
extractTagsFromDocument,
Federation2SubgraphDocumentNodeByTagsFilter,
} from './lib/federation-tag-extraction';
import { extractMetadata, mergeMetadata } from './lib/metadata-extraction';
import { SetMap } from './lib/setmap';
@ -348,20 +347,9 @@ const createFederation: (
const contractResults = await Promise.all(
contracts.map(async contract => {
// apply contracts to replace tags with inaccessible directives
const filteredSubgraphs = subgraphs.map(subgraph => {
const filter: Federation2SubgraphDocumentNodeByTagsFilter = {
include: new Set(contract.filter.include),
exclude: new Set(contract.filter.exclude),
};
const filteredSubgraph = applyTagFilterToInaccessibleTransformOnSubgraphSchema(
subgraph.typeDefs,
filter,
);
return {
// @note Although it can differ from the supergraph's, ignore metadata on contracts.
...subgraph,
typeDefs: filteredSubgraph.typeDefs,
};
const filteredSubgraphs = applyTagFilterOnSubgraphs(subgraphs, {
include: new Set(contract.filter.include),
exclude: new Set(contract.filter.exclude),
});
// attempt to compose the contract filtered subgraph