@@ -4026,6 +4026,63 @@ testImplementations((api) => {
40264026 ` ) ;
40274027 } ) ;
40284028
4029+ test ( "@external + @tag" , ( ) => {
4030+ const subgraphs = [
4031+ {
4032+ name : "a" ,
4033+ typeDefs : parse ( /* GraphQL */ `
4034+ extend schema @link(url: "https://specs.apollo.dev/federation/${ version } ", import: ["@key", "@tag"])
4035+
4036+ type Product @key(fields: "id") {
4037+ id: ID! @tag(name: "public")
4038+ name: String! @tag(name: "public")
4039+ inStock: Int! @tag(name: "public")
4040+ }
4041+
4042+ type Query {
4043+ products: [Product] @tag(name: "public")
4044+ }
4045+ ` ) ,
4046+ } ,
4047+ {
4048+ name : "b" ,
4049+ typeDefs : parse ( /* GraphQL */ `
4050+ extend schema
4051+ @link(
4052+ url: "https://specs.apollo.dev/federation/${ version } "
4053+ import: ["@key", "@external", "@requires", "@tag"]
4054+ )
4055+
4056+ type Product @key(fields: "id") {
4057+ id: ID! @tag(name: "public")
4058+ inStock: Int! @external
4059+ isAvailable: String! @requires(fields: "inStock") @tag(name: "public")
4060+ }
4061+ ` ) ,
4062+ } ,
4063+ ] ;
4064+
4065+ const result = composeServices ( subgraphs ) ;
4066+ expect ( result . errors ) . toEqual ( undefined ) ;
4067+ assertCompositionSuccess ( result ) ;
4068+
4069+ expect ( result . supergraphSdl ) . toContainGraphQL ( /* GraphQL */ `
4070+ type Product
4071+ @join__type(graph: A, key: "id")
4072+ @join__type(graph: B, key: "id") {
4073+ id: ID! @tag(name: "public")
4074+ name: String! @join__field(graph: A) @tag(name: "public")
4075+ inStock: Int!
4076+ @join__field(graph: A)
4077+ @join__field(graph: B, external: true)
4078+ @tag(name: "public")
4079+ isAvailable: String!
4080+ @join__field(graph: B, requires: "inStock")
4081+ @tag(name: "public")
4082+ }
4083+ ` ) ;
4084+ } ) ;
4085+
40294086 test ( "@tag" , ( ) => {
40304087 const result = composeServices ( [
40314088 {
@@ -7224,6 +7281,75 @@ testImplementations((api) => {
72247281 } ) ;
72257282
72267283 test ( "external on non-key field of an entity type" , ( ) => {
7284+ /** "apollo" errors on this schema definition */
7285+ api . runIf ( "guild" , ( ) => {
7286+ let result = api . composeServices ( [
7287+ {
7288+ name : "a" ,
7289+ typeDefs : parse ( /* GraphQL */ `
7290+ extend schema
7291+ @link(url: "https://specs.apollo.dev/link/v1.0")
7292+ @link(
7293+ url: "https://specs.apollo.dev/federation/v2.8"
7294+ import: ["@key", "@external", "@requires", "@tag"]
7295+ )
7296+
7297+ type User @key(fields: "id") {
7298+ id: ID! @tag(name: "public")
7299+ creditScore: Int @requires(fields: "ssn") @tag(name: "public")
7300+ }
7301+
7302+ extend type User @external {
7303+ ssn: String
7304+ }
7305+ ` ) ,
7306+ } ,
7307+ {
7308+ name : "b" ,
7309+ typeDefs : parse ( /* GraphQL */ `
7310+ schema
7311+ @link(url: "https://specs.apollo.dev/link/v1.0")
7312+ @link(
7313+ url: "https://specs.apollo.dev/federation/v2.8"
7314+ import: ["@key", "@tag"]
7315+ ) {
7316+ query: Query
7317+ }
7318+
7319+ type Query {
7320+ user: User @tag(name: "public")
7321+ }
7322+
7323+ type User @key(fields: "id") {
7324+ id: ID! @tag(name: "public")
7325+ ssn: String
7326+ }
7327+ ` ) ,
7328+ } ,
7329+ ] ) ;
7330+
7331+ expect ( result . errors ) . toEqual ( undefined ) ;
7332+ assertCompositionSuccess ( result ) ;
7333+
7334+ expect ( result . supergraphSdl ) . toContainGraphQL ( /* GraphQL */ `
7335+ type Query @join__type(graph: A) @join__type(graph: B) {
7336+ user: User @join__field(graph: B) @tag(name: "public")
7337+ }
7338+
7339+ type User
7340+ @join__type(graph: A, key: "id")
7341+ @join__type(graph: B, key: "id") {
7342+ id: ID! @tag(name: "public")
7343+ creditScore: Int
7344+ @join__field(graph: A, requires: "ssn")
7345+ @tag(name: "public")
7346+ ssn: String
7347+ @join__field(external: true, graph: A)
7348+ @join__field(graph: B)
7349+ }
7350+ ` ) ;
7351+ } ) ;
7352+
72277353 let result = api . composeServices ( [
72287354 {
72297355 name : "foo" ,
@@ -7233,22 +7359,18 @@ testImplementations((api) => {
72337359 url: "https://specs.apollo.dev/federation/v2.3"
72347360 import: ["@key", "@external", "@provides", "@shareable"]
72357361 )
7236-
72377362 type Note @key(fields: "id") @shareable {
72387363 id: ID!
72397364 name: String @external
72407365 author: User @external
72417366 }
7242-
72437367 type User @key(fields: "id", resolvable: false) {
72447368 id: ID!
72457369 }
7246-
72477370 type PrivateNote @key(fields: "id") @shareable {
72487371 id: ID!
72497372 note: Note @provides(fields: "name author { id }")
72507373 }
7251-
72527374 type Query {
72537375 note: Note @shareable
72547376 privateNote: PrivateNote @shareable
@@ -7260,29 +7382,25 @@ testImplementations((api) => {
72607382 typeDefs : parse ( /* GraphQL */ `
72617383 extend schema
72627384 @link(
7263- url: "https://specs.apollo.dev/federation/v2.3"
7264- import: ["@key", "@shareable"]
7385+ url: "https://specs.apollo.dev/federation/v2.3"
7386+ import: ["@key", "@shareable"]
72657387 )
7266-
72677388 type Note @key(fields: "id") @shareable {
72687389 id: ID!
72697390 name: String
72707391 author: User
72717392 }
7272-
72737393 type User @key(fields: "id") {
7274- id: ID!
7275- name: String
7276- }
7277-
7278- type PrivateNote @key(fields: "id") @shareable {
7279- id: ID!
7280- note: Note
7394+ id: ID!
7395+ name: String
72817396 }
7282-
7283- type Query {
7284- note: Note @shareable
7285- privateNote: PrivateNote @shareable
7397+ type PrivateNote @key(fields: "id") @shareable {
7398+ id: ID!
7399+ note: Note
7400+ }
7401+ type Query {
7402+ note: Note @shareable
7403+ privateNote: PrivateNote @shareable
72867404 }
72877405 ` ) ,
72887406 } ,
@@ -7307,29 +7425,25 @@ testImplementations((api) => {
73077425 result = api . composeServices ( [
73087426 {
73097427 name : "foo" ,
7310- typeDefs : parse ( /* GraphQL */ `
7428+ typeDefs : parse ( /* GraphQL */ `
73117429 extend schema
7312- @link(
7430+ @link(
73137431 url: "https://specs.apollo.dev/federation/v2.3"
73147432 import: ["@key", "@external", "@provides", "@shareable"]
73157433 )
7316-
73177434 type Note @key(fields: "id") @shareable {
73187435 id: ID!
73197436 name: String @external
73207437 author: User @external
73217438 }
7322-
73237439 type User @key(fields: "id", resolvable: false) {
73247440 id: ID!
73257441 }
7326-
73277442 type PrivateNote @key(fields: "id") @shareable {
73287443 id: ID!
73297444 note: Note @provides(fields: "name author { id }")
7330- }
7331-
7332- type Query {
7445+ }
7446+ type Query {
73337447 note: Note @shareable
73347448 privateNote: PrivateNote @shareable
73357449 }
@@ -7343,23 +7457,19 @@ testImplementations((api) => {
73437457 url: "https://specs.apollo.dev/federation/v2.3"
73447458 import: ["@key", "@shareable"]
73457459 )
7346-
73477460 type Note @key(fields: "id") @shareable {
73487461 id: ID!
73497462 name: String
73507463 author: User
7351- }
7352-
7353- type User @key(fields: "id") {
7464+ }
7465+ type User @key(fields: "id") {
73547466 id: ID!
73557467 name: String
73567468 }
7357-
73587469 type PrivateNote @key(fields: "id") @shareable {
73597470 id: ID!
73607471 note: Note
73617472 }
7362-
73637473 type Query {
73647474 note: Note @shareable
73657475 privateNote: PrivateNote @shareable
@@ -7374,15 +7484,13 @@ testImplementations((api) => {
73747484 url: "https://specs.apollo.dev/federation/v2.3"
73757485 import: ["@key", "@external", "@provides", "@shareable"]
73767486 )
7377-
73787487 type Query {
73797488 hello: String
73807489 }
7381-
73827490 type Note @key(fields: "id") @shareable {
73837491 id: ID!
73847492 tag: String
7385- }
7493+ }
73867494 ` ) ,
73877495 } ,
73887496 ] ) ;
@@ -7402,7 +7510,7 @@ testImplementations((api) => {
74027510 @join__field(external: true, graph: FOO)
74037511 @join__field(graph: BAR)
74047512 tag: String @join__field(graph: BAZ)
7405- }
7513+ }
74067514 ` ) ;
74077515 } ) ;
74087516
0 commit comments