Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions composition-js/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

This CHANGELOG pertains only to Apollo Federation packages in the 2.x range. The Federation v0.x equivalent for this package can be found [here](https://github.com/apollographql/federation/blob/version-0.x/federation-js/CHANGELOG.md) on the `version-0.x` branch of this repo.

## vNext

- Fix composition of repeatable custom directives [PR #2136](https://github.com/apollographql/federation/pull/2136)

## 2.1.0

- Don't apply @shareable when upgrading fed1 supergraphs if it's already @shareable [PR #2043](https://github.com/apollographql/federation/pull/2043)
Expand Down
36 changes: 35 additions & 1 deletion composition-js/src/__tests__/compose.composeDirective.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -925,5 +925,39 @@ describe('composing custom core directives', () => {
expect(feature?.imports).toEqual([]);
expect(feature?.nameInSchema).toEqual('mytag');
expect(printSchema(schema)).toMatchSnapshot();
});
});

it('repeatable custom directives', () => {
const subgraphA = {
typeDefs: gql`
extend schema @composeDirective(name: "@auth")
@link(url: "https://specs.apollo.dev/federation/v2.1", import: ["@key", "@composeDirective", "@shareable"])
@link(url: "https://custom.dev/auth/v1.0", import: ["@auth"])
directive @auth(scope: String!) on FIELD_DEFINITION

type Query {
shared: String @shareable @auth(scope: "VIEWER")
}
`,
name: 'subgraphA',
};

const subgraphB = {
typeDefs: gql`
extend schema @composeDirective(name: "@auth")
@link(url: "https://specs.apollo.dev/federation/v2.1", import: ["@key", "@composeDirective", "@shareable"])
@link(url: "https://custom.dev/auth/v1.0", import: ["@auth"])
directive @auth(scope: String!) on FIELD_DEFINITION

type Query {
shared: String @shareable @auth(scope: "ADMIN")
}`,
name: 'subgraphB',
};

const result = composeServices([subgraphA, subgraphB]);
const schema = expectNoErrors(result);
const appliedDirectives = schema.elementByCoordinate('Query.shared')?.appliedDirectives;
expect(appliedDirectives?.map(d => [d.name, d.arguments()])).toMatchObject([['auth', { scope: 'VIEWER'}], ['auth', { scope: 'ADMIN'}]]);
});
});
16 changes: 8 additions & 8 deletions composition-js/src/merging/merge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,14 +393,6 @@ class Merger {
// calling root type a "value type" when hinting).
this.mergeSchemaDefinition(this.subgraphsSchema.map(s => s.schemaDefinition), this.merged.schemaDefinition);

for (const type of typesToMerge) {
// We've already merged unions above and we've going to merge enums last
if (type.kind === 'UnionType' || type.kind === 'EnumType') {
continue;
}
this.mergeType(this.subgraphsTypes(type), type);
}

for (const definition of this.merged.directives()) {
// we should skip the supergraph specific directives, that is the @core and @join directives.
if (linkSpec.isSpecDirective(definition) || joinSpec.isSpecDirective(definition)) {
Expand All @@ -409,6 +401,14 @@ class Merger {
this.mergeDirectiveDefinition(this.subgraphsSchema.map(s => s.directive(definition.name)), definition);
}

for (const type of typesToMerge) {
// We've already merged unions above and we've going to merge enums last
if (type.kind === 'UnionType' || type.kind === 'EnumType') {
continue;
}
this.mergeType(this.subgraphsTypes(type), type);
}

// We merge enum dead last because enums can be used as both input and output types and the merging behavior
// depends on their usage and it's easier to check said usage if everything else has been merge (at least
// anything that may use an enum type, so all fields and arguments).
Expand Down
2 changes: 1 addition & 1 deletion docs/source/hints.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The following hints might be generated during composition:
| `INCONSISTENT_DESCRIPTION` | Indicates that an element has a description in more than one subgraph, and the descriptions are not equal. | `WARN` |
| `INCONSISTENT_ARGUMENT_PRESENCE` | Indicates that an optional argument (of a field or directive definition) is not present in all subgraphs and will not be part of the supergraph. | `WARN` |
| `FROM_SUBGRAPH_DOES_NOT_EXIST` | Source subgraph specified by @override directive does not exist | `WARN` |
| `INCONSISTEN_NON_REPEATABLE_DIRECTIVE_ARGUMENTS` | A non-repeatable directive is applied to a schema element in different subgraphs but with arguments that are different. | `WARN` |
| `INCONSISTENT_NON_REPEATABLE_DIRECTIVE_ARGUMENTS` | A non-repeatable directive is applied to a schema element in different subgraphs but with arguments that are different. | `WARN` |
| `DIRECTIVE_COMPOSITION_WARN` | Indicates that an issue was detected when composing custom directives. | `WARN` |

</div>
Expand Down