@@ -8271,4 +8271,380 @@ testImplementations((api) => {
82718271 assertCompositionSuccess ( result ) ;
82728272 expect ( result . supergraphSdl ) . not . includes ( "scalar FieldSet" ) ;
82738273 } ) ;
8274+
8275+ test ( "keeps @join__field for object type extension with @key being @external" , ( ) => {
8276+ const result = api . composeServices ( [
8277+ {
8278+ name : "owner-service" ,
8279+ typeDefs : parse ( /* GraphQL */ `
8280+ extend schema
8281+ @link(
8282+ url: "https://specs.apollo.dev/federation/v2.3"
8283+ import: ["@key", "@external"]
8284+ )
8285+
8286+ extend type Repository @key(fields: "id name") {
8287+ id: ID! @external
8288+ name: String! @external
8289+ }
8290+ ` ) ,
8291+ } ,
8292+ {
8293+ name : "team-service" ,
8294+ typeDefs : parse ( /* GraphQL */ `
8295+ extend schema
8296+ @link(
8297+ url: "https://specs.apollo.dev/federation/v2.3"
8298+ import: ["@key", "@external"]
8299+ )
8300+
8301+ extend type Repository @key(fields: "id") {
8302+ id: ID! @external
8303+ }
8304+ ` ) ,
8305+ } ,
8306+ {
8307+ name : "repo-service" ,
8308+ typeDefs : parse ( /* GraphQL */ `
8309+ extend schema
8310+ @link(
8311+ url: "https://specs.apollo.dev/federation/v2.3"
8312+ import: ["@key", "@shareable"]
8313+ )
8314+
8315+ type Query {
8316+ repo: Repository
8317+ }
8318+
8319+ type Repository @key(fields: "id") {
8320+ id: ID!
8321+ name: String! @shareable
8322+ }
8323+ ` ) ,
8324+ } ,
8325+ ] ) ;
8326+
8327+ assertCompositionSuccess ( result ) ;
8328+
8329+ expect ( result . supergraphSdl ) . toContainGraphQL ( /* GraphQL */ `
8330+ type Repository
8331+ @join__type(extension: true, graph: OWNER_SERVICE, key: "id name")
8332+ @join__type(extension: true, graph: TEAM_SERVICE, key: "id")
8333+ @join__type(graph: REPO_SERVICE, key: "id") {
8334+ id: ID!
8335+ name: String!
8336+ @join__field(graph: OWNER_SERVICE)
8337+ @join__field(graph: REPO_SERVICE)
8338+ }
8339+ ` ) ;
8340+ } ) ;
8341+
8342+ test ( "keep @join__field for object type extension where @key is @external and have other @external fields used with @requires" , ( ) => {
8343+ const result = api . composeServices ( [
8344+ {
8345+ name : "developer-service" ,
8346+ typeDefs : parse ( /* GraphQL */ `
8347+ extend schema
8348+ @link(
8349+ url: "https://specs.apollo.dev/federation/v2.3"
8350+ import: ["@key", "@shareable"]
8351+ )
8352+
8353+ type Query {
8354+ me: Developer
8355+ }
8356+
8357+ type Developer @key(fields: "id") @key(fields: "guestGuid") {
8358+ id: ID!
8359+ guestGuid: ID! @shareable
8360+ isMe: Boolean! @shareable
8361+ myFollowingStatus: String! @shareable
8362+ userVisibility: String! @shareable
8363+ }
8364+ ` ) ,
8365+ } ,
8366+ {
8367+ name : "team-service" ,
8368+ typeDefs : parse ( /* GraphQL */ `
8369+ extend schema
8370+ @link(
8371+ url: "https://specs.apollo.dev/federation/v2.3"
8372+ import: ["@key", "@external", "@requires"]
8373+ )
8374+
8375+ extend type Developer @key(fields: "guestGuid") {
8376+ guestGuid: ID! @external
8377+ myFollowingStatus: String! @external
8378+ userVisibility: String! @external
8379+ guestSavedLists: [ID!]!
8380+ @requires(fields: "myFollowingStatus userVisibility")
8381+ }
8382+ ` ) ,
8383+ } ,
8384+ {
8385+ name : "commit-service" ,
8386+ typeDefs : parse ( /* GraphQL */ `
8387+ extend schema
8388+ @link(
8389+ url: "https://specs.apollo.dev/federation/v2.3"
8390+ import: ["@key", "@external", "@requires"]
8391+ )
8392+
8393+ extend type Developer @key(fields: "id") {
8394+ id: ID! @external
8395+ isMe: Boolean! @external
8396+ userVisibility: String! @external
8397+ commits: [ID!]! @requires(fields: "isMe userVisibility")
8398+ }
8399+ ` ) ,
8400+ } ,
8401+ {
8402+ name : "reaction-service" ,
8403+ typeDefs : parse ( /* GraphQL */ `
8404+ extend schema
8405+ @link(
8406+ url: "https://specs.apollo.dev/federation/v2.3"
8407+ import: ["@key", "@external"]
8408+ )
8409+
8410+ extend type Developer @key(fields: "id") {
8411+ id: ID! @external
8412+ }
8413+ ` ) ,
8414+ } ,
8415+ ] ) ;
8416+
8417+ assertCompositionSuccess ( result ) ;
8418+
8419+ expect ( result . supergraphSdl ) . toContainGraphQL ( /* GraphQL */ `
8420+ type Developer
8421+ @join__type(extension: true, graph: TEAM_SERVICE, key: "guestGuid")
8422+ @join__type(extension: true, graph: REACTION_SERVICE, key: "id")
8423+ @join__type(extension: true, graph: COMMIT_SERVICE, key: "id")
8424+ @join__type(graph: DEVELOPER_SERVICE, key: "guestGuid")
8425+ @join__type(graph: DEVELOPER_SERVICE, key: "id") {
8426+ guestGuid: ID!
8427+ @join__field(graph: TEAM_SERVICE)
8428+ @join__field(graph: DEVELOPER_SERVICE)
8429+ guestSavedLists: [ID!]!
8430+ @join__field(
8431+ graph: TEAM_SERVICE
8432+ requires: "myFollowingStatus userVisibility"
8433+ )
8434+ id: ID!
8435+ @join__field(graph: REACTION_SERVICE)
8436+ @join__field(graph: COMMIT_SERVICE)
8437+ @join__field(graph: DEVELOPER_SERVICE)
8438+ isMe: Boolean!
8439+ @join__field(external: true, graph: COMMIT_SERVICE)
8440+ @join__field(graph: DEVELOPER_SERVICE)
8441+ myFollowingStatus: String!
8442+ @join__field(external: true, graph: TEAM_SERVICE)
8443+ @join__field(graph: DEVELOPER_SERVICE)
8444+ commits: [ID!]!
8445+ @join__field(graph: COMMIT_SERVICE, requires: "isMe userVisibility")
8446+ userVisibility: String!
8447+ @join__field(external: true, graph: TEAM_SERVICE)
8448+ @join__field(external: true, graph: COMMIT_SERVICE)
8449+ @join__field(graph: DEVELOPER_SERVICE)
8450+ }
8451+ ` ) ;
8452+ } ) ;
8453+
8454+ test ( "@external on non-key field in Federation v1" , ( ) => {
8455+ let result = api . composeServices ( [
8456+ {
8457+ name : "users" ,
8458+ typeDefs : parse ( /* GraphQL */ `
8459+ type Query {
8460+ users: [User]
8461+ }
8462+
8463+ type User @key(fields: "id") {
8464+ id: ID!
8465+ name: String! @external
8466+ }
8467+ ` ) ,
8468+ } ,
8469+ {
8470+ name : "extra" ,
8471+ typeDefs : parse ( /* GraphQL */ `
8472+ type User @key(fields: "id") {
8473+ id: ID!
8474+ name: String!
8475+ }
8476+ ` ) ,
8477+ } ,
8478+ ] ) ;
8479+
8480+ assertCompositionSuccess ( result ) ;
8481+ expect ( result . supergraphSdl ) . toContainGraphQL ( /* GraphQL */ `
8482+ type User
8483+ @join__type(graph: EXTRA, key: "id")
8484+ @join__type(graph: USERS, key: "id") {
8485+ id: ID!
8486+ name: String! @join__field(graph: EXTRA)
8487+ }
8488+ ` ) ;
8489+ } ) ;
8490+
8491+ test ( "@external on non-key field in Federation v1" , ( ) => {
8492+ let result = api . composeServices ( [
8493+ {
8494+ name : "users" ,
8495+ typeDefs : parse ( /* GraphQL */ `
8496+ type Query {
8497+ users: [User]
8498+ }
8499+
8500+ type User @key(fields: "id") {
8501+ id: ID!
8502+ name: String! @external
8503+ }
8504+ ` ) ,
8505+ } ,
8506+ {
8507+ name : "extra" ,
8508+ typeDefs : parse ( /* GraphQL */ `
8509+ type User @key(fields: "id") {
8510+ id: ID!
8511+ name: String!
8512+ }
8513+ ` ) ,
8514+ } ,
8515+ ] ) ;
8516+
8517+ assertCompositionSuccess ( result ) ;
8518+ expect ( result . supergraphSdl ) . toContainGraphQL ( /* GraphQL */ `
8519+ type User
8520+ @join__type(graph: EXTRA, key: "id")
8521+ @join__type(graph: USERS, key: "id") {
8522+ id: ID!
8523+ name: String! @join__field(graph: EXTRA)
8524+ }
8525+ ` ) ;
8526+ } ) ;
8527+
8528+ test ( "@external on non-key field in Federation v2" , ( ) => {
8529+ let result = api . composeServices ( [
8530+ {
8531+ name : "users" ,
8532+ typeDefs : parse ( /* GraphQL */ `
8533+ extend schema
8534+ @link(
8535+ url: "https://specs.apollo.dev/federation/v2.3"
8536+ import: ["@key", "@external"]
8537+ )
8538+
8539+ type Query {
8540+ users: [User]
8541+ }
8542+
8543+ type User @key(fields: "id") {
8544+ id: ID!
8545+ name: String! @external
8546+ }
8547+ ` ) ,
8548+ } ,
8549+ {
8550+ name : "extra" ,
8551+ typeDefs : parse ( /* GraphQL */ `
8552+ extend schema
8553+ @link(
8554+ url: "https://specs.apollo.dev/federation/v2.3"
8555+ import: ["@key", "@external"]
8556+ )
8557+
8558+ type User @key(fields: "id") {
8559+ id: ID!
8560+ name: String!
8561+ }
8562+ ` ) ,
8563+ } ,
8564+ ] ) ;
8565+
8566+ assertCompositionFailure ( result ) ;
8567+ } ) ;
8568+
8569+ test ( "@external object type field implementing interface field" , ( ) => {
8570+ const result = api . composeServices ( [
8571+ {
8572+ name : "github_core" ,
8573+ typeDefs : parse ( /* GraphQL */ `
8574+ extend schema
8575+ @link(
8576+ url: "https://specs.apollo.dev/federation/v2.3"
8577+ import: ["@key"]
8578+ )
8579+
8580+ type Query {
8581+ checks: QueuedCheckRunInfo
8582+ }
8583+
8584+ interface CheckRunInfo {
8585+ id: ID!
8586+ status: String!
8587+ }
8588+
8589+ type QueuedCheckRunInfo implements CheckRunInfo @key(fields: "id") {
8590+ id: ID!
8591+ status: String!
8592+ commitOid: String!
8593+ }
8594+ ` ) ,
8595+ } ,
8596+ {
8597+ name : "github_action" ,
8598+ typeDefs : parse ( /* GraphQL */ `
8599+ extend schema
8600+ @link(
8601+ url: "https://specs.apollo.dev/federation/v2.3"
8602+ import: ["@key", "@external", "@requires"]
8603+ )
8604+
8605+ extend type QueuedCheckRunInfo implements CheckRunInfo
8606+ @key(fields: "id") {
8607+ id: ID! @external
8608+ status: String! @external
8609+ commitOid: String! @external
8610+ workflowRunId: ID! @requires(fields: "commitOid")
8611+ }
8612+
8613+ interface CheckRunInfo {
8614+ id: ID!
8615+ status: String!
8616+ }
8617+ ` ) ,
8618+ } ,
8619+ ] ) ;
8620+
8621+ assertCompositionSuccess ( result ) ;
8622+
8623+ expect ( result . supergraphSdl ) . toContainGraphQL ( /* GraphQL */ `
8624+ interface CheckRunInfo
8625+ @join__type(graph: GITHUB_ACTION)
8626+ @join__type(graph: GITHUB_CORE) {
8627+ id: ID!
8628+ status: String!
8629+ }
8630+ ` ) ;
8631+
8632+ expect ( result . supergraphSdl ) . toContainGraphQL ( /* GraphQL */ `
8633+ type QueuedCheckRunInfo implements CheckRunInfo
8634+ @join__implements(graph: GITHUB_ACTION, interface: "CheckRunInfo")
8635+ @join__implements(graph: GITHUB_CORE, interface: "CheckRunInfo")
8636+ @join__type(graph: GITHUB_CORE, key: "id")
8637+ @join__type(graph: GITHUB_ACTION, key: "id", extension: true) {
8638+ id: ID!
8639+ status: String!
8640+ @join__field(graph: GITHUB_CORE)
8641+ @join__field(graph: GITHUB_ACTION, external: true)
8642+ commitOid: String!
8643+ @join__field(graph: GITHUB_CORE)
8644+ @join__field(graph: GITHUB_ACTION, external: true)
8645+ workflowRunId: ID!
8646+ @join__field(graph: GITHUB_ACTION, requires: "commitOid")
8647+ }
8648+ ` ) ;
8649+ } ) ;
82748650} ) ;
0 commit comments