diff --git a/.changeset/afraid-queens-drive.md b/.changeset/afraid-queens-drive.md new file mode 100644 index 000000000..d51a14cad --- /dev/null +++ b/.changeset/afraid-queens-drive.md @@ -0,0 +1,11 @@ +--- +"apollo-federation-integration-testsuite": patch +"@apollo/query-planner": patch +"@apollo/query-graphs": patch +"@apollo/composition": patch +"@apollo/federation-internals": patch +"@apollo/subgraph": patch +"@apollo/gateway": patch +--- + +Preparing preview.2 release diff --git a/.changeset/lucky-pillows-rhyme.md b/.changeset/lucky-pillows-rhyme.md new file mode 100644 index 000000000..64982e721 --- /dev/null +++ b/.changeset/lucky-pillows-rhyme.md @@ -0,0 +1,11 @@ +--- +"@apollo/composition": minor +"@apollo/federation-internals": minor +"apollo-federation-integration-testsuite": minor +"@apollo/gateway": minor +"@apollo/query-graphs": minor +"@apollo/query-planner": minor +"@apollo/subgraph": minor +--- + +Add connect spec v0.2 diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 000000000..ff5bfef03 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,18 @@ +{ + "mode": "exit", + "tag": "preview", + "initialVersions": { + "@apollo/composition": "2.10.0", + "apollo-federation-integration-testsuite": "2.10.0", + "@apollo/gateway": "2.10.0", + "@apollo/federation-internals": "2.10.0", + "@apollo/query-graphs": "2.10.0", + "@apollo/query-planner": "2.10.0", + "@apollo/subgraph": "2.10.0" + }, + "changesets": [ + "afraid-queens-drive", + "five-suits-drum", + "lucky-pillows-rhyme" + ] +} diff --git a/.changeset/sixty-plums-enjoy.md b/.changeset/sixty-plums-enjoy.md new file mode 100644 index 000000000..10fa1eab4 --- /dev/null +++ b/.changeset/sixty-plums-enjoy.md @@ -0,0 +1,5 @@ +--- +"@apollo/composition": patch +--- + +Allow merging external types when using arrays as default arguments. diff --git a/composition-js/CHANGELOG.md b/composition-js/CHANGELOG.md index 755b1e92d..fcd5aa16f 100644 --- a/composition-js/CHANGELOG.md +++ b/composition-js/CHANGELOG.md @@ -1,5 +1,35 @@ # CHANGELOG for `@apollo/composition` +## 2.11.0-preview.2 + +### Patch Changes + +- Preparing preview.2 release ([#3255](https://github.com/apollographql/federation/pull/3255)) + +- Updated dependencies [[`3e2b0a8569a9fe46726182887ed0b4bfc0b52468`](https://github.com/apollographql/federation/commit/3e2b0a8569a9fe46726182887ed0b4bfc0b52468)]: + - @apollo/query-graphs@2.11.0-preview.2 + - @apollo/federation-internals@2.11.0-preview.2 + +## 2.11.0-preview.1 + +### Patch Changes + +- Updated dependencies [[`1462c91879d41884c0a7e60551d8dd0d67c832d3`](https://github.com/apollographql/federation/commit/1462c91879d41884c0a7e60551d8dd0d67c832d3)]: + - @apollo/query-graphs@2.11.0-preview.1 + - @apollo/federation-internals@2.11.0-preview.1 + +## 2.11.0-preview.0 + +### Minor Changes + +- Add connect spec v0.2 ([#3228](https://github.com/apollographql/federation/pull/3228)) + +### Patch Changes + +- Updated dependencies [[`e7e67579908d5cd2fa6fe558228dffe4808cd98d`](https://github.com/apollographql/federation/commit/e7e67579908d5cd2fa6fe558228dffe4808cd98d)]: + - @apollo/federation-internals@2.11.0-preview.0 + - @apollo/query-graphs@2.11.0-preview.0 + ## 2.10.0 ### Minor Changes diff --git a/composition-js/package.json b/composition-js/package.json index ff2469f1e..aa1f084ef 100644 --- a/composition-js/package.json +++ b/composition-js/package.json @@ -1,6 +1,6 @@ { "name": "@apollo/composition", - "version": "2.10.0", + "version": "2.11.0-preview.2", "description": "Apollo Federation composition utilities", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -27,8 +27,8 @@ "access": "public" }, "dependencies": { - "@apollo/federation-internals": "2.10.0", - "@apollo/query-graphs": "2.10.0" + "@apollo/federation-internals": "2.11.0-preview.2", + "@apollo/query-graphs": "2.11.0-preview.2" }, "peerDependencies": { "graphql": "^16.5.0" diff --git a/composition-js/src/__tests__/compose.test.ts b/composition-js/src/__tests__/compose.test.ts index df63bf699..3cc57c12f 100644 --- a/composition-js/src/__tests__/compose.test.ts +++ b/composition-js/src/__tests__/compose.test.ts @@ -614,6 +614,47 @@ describe('composition', () => { `); }); + it('merges default arguments when they are arrays', () => { + const subgraphA = { + name: 'subgraph-a', + typeDefs: gql` + type Query { + a: A @shareable + } + + type A @key(fields: "id") { + id: ID + get(ids: [ID] = []): [B] @external + req: Int @requires(fields: "get { __typename }") + } + + type B @key(fields: "id", resolvable: false) { + id: ID + } + ` + }; + const subgraphB = { + name: 'subgraph-b', + typeDefs: gql` + type Query { + a: A @shareable + } + + type A @key(fields: "id") { + id: ID + get(ids: [ID] = []): [B] + } + + type B @key(fields: "id") { + id: ID + } + ` + }; + + const result = composeAsFed2Subgraphs([subgraphA, subgraphB]); + assertCompositionSuccess(result); + }); + describe('merging of type references', () => { describe('for field types', () => { it('errors on incompatible types', () => { diff --git a/composition-js/src/__tests__/connectors.test.ts b/composition-js/src/__tests__/connectors.test.ts index 353b95c01..06a984e88 100644 --- a/composition-js/src/__tests__/connectors.test.ts +++ b/composition-js/src/__tests__/connectors.test.ts @@ -39,7 +39,7 @@ describe("connect spec and join__directive", () => { "schema @link(url: \\"https://specs.apollo.dev/link/v1.0\\") @link(url: \\"https://specs.apollo.dev/join/v0.5\\", for: EXECUTION) - @link(url: \\"https://specs.apollo.dev/connect/v0.1\\", for: EXECUTION) + @link(url: \\"https://specs.apollo.dev/connect/v0.2\\", for: EXECUTION) @join__directive(graphs: [WITH_CONNECTORS], name: \\"link\\", args: {url: \\"https://specs.apollo.dev/connect/v0.1\\", import: [\\"@connect\\", \\"@source\\"]}) @join__directive(graphs: [WITH_CONNECTORS], name: \\"source\\", args: {name: \\"v1\\", http: {baseURL: \\"http://v1\\"}}) { @@ -121,6 +121,424 @@ describe("connect spec and join__directive", () => { } }); + it("does not require importing @connect", () => { + const subgraphs = [ + { + name: "with-connectors", + typeDefs: parse(` + extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.10" + import: ["@key"] + ) + @link( + url: "https://specs.apollo.dev/connect/v0.1" + import: ["@source"] + ) + @source(name: "v1", http: { baseURL: "http://v1" }) + + type Query { + resources: [Resource!]! + @connect(source: "v1", http: { GET: "/resources" }, selection: "") + } + + type Resource @key(fields: "id") { + id: ID! + name: String! + } + `), + }, + ]; + + const result = composeServices(subgraphs); + expect(result.errors ?? []).toEqual([]); + const printed = printSchema(result.schema!); + expect(printed).toMatchInlineSnapshot(` + "schema + @link(url: \\"https://specs.apollo.dev/link/v1.0\\") + @link(url: \\"https://specs.apollo.dev/join/v0.5\\", for: EXECUTION) + @link(url: \\"https://specs.apollo.dev/connect/v0.2\\", for: EXECUTION) + @join__directive(graphs: [WITH_CONNECTORS], name: \\"link\\", args: {url: \\"https://specs.apollo.dev/connect/v0.1\\", import: [\\"@source\\"]}) + @join__directive(graphs: [WITH_CONNECTORS], name: \\"source\\", args: {name: \\"v1\\", http: {baseURL: \\"http://v1\\"}}) + { + query: Query + } + + directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + + directive @join__graph(name: String!, url: String!) on ENUM_VALUE + + directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + + directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + + directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE + + directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + + directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + + directive @join__directive(graphs: [join__Graph!], name: String!, args: join__DirectiveArguments) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + + enum link__Purpose { + \\"\\"\\" + \`SECURITY\` features provide metadata necessary to securely resolve fields. + \\"\\"\\" + SECURITY + + \\"\\"\\" + \`EXECUTION\` features provide metadata necessary for operation execution. + \\"\\"\\" + EXECUTION + } + + scalar link__Import + + enum join__Graph { + WITH_CONNECTORS @join__graph(name: \\"with-connectors\\", url: \\"\\") + } + + scalar join__FieldSet + + scalar join__DirectiveArguments + + scalar join__FieldValue + + input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! + } + + type Query + @join__type(graph: WITH_CONNECTORS) + { + resources: [Resource!]! @join__directive(graphs: [WITH_CONNECTORS], name: \\"connect\\", args: {source: \\"v1\\", http: {GET: \\"/resources\\"}, selection: \\"\\"}) + } + + type Resource + @join__type(graph: WITH_CONNECTORS, key: \\"id\\") + { + id: ID! + name: String! + }" + `); + + if (result.schema) { + expect(printSchema(result.schema.toAPISchema())).toMatchInlineSnapshot(` + "type Query { + resources: [Resource!]! + } + + type Resource { + id: ID! + name: String! + }" + `); + } + }); + + it("using as:", () => { + const subgraphs = [ + { + name: "with-connectors", + typeDefs: parse(` + extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.10" + import: ["@key"] + ) + @link( + url: "https://specs.apollo.dev/connect/v0.1" + as: "http" + import: ["@source"] + ) + @source(name: "v1", http: { baseURL: "http://v1" }) + + type Query { + resources: [Resource!]! + @http(source: "v1", http: { GET: "/resources" }, selection: "") + } + + type Resource @key(fields: "id") { + id: ID! + name: String! + } + `), + }, + ]; + + const result = composeServices(subgraphs); + expect(result.errors ?? []).toEqual([]); + const printed = printSchema(result.schema!); + expect(printed).toMatchInlineSnapshot(` + "schema + @link(url: \\"https://specs.apollo.dev/link/v1.0\\") + @link(url: \\"https://specs.apollo.dev/join/v0.5\\", for: EXECUTION) + @link(url: \\"https://specs.apollo.dev/connect/v0.2\\", for: EXECUTION) + @join__directive(graphs: [WITH_CONNECTORS], name: \\"link\\", args: {url: \\"https://specs.apollo.dev/connect/v0.1\\", as: \\"http\\", import: [\\"@source\\"]}) + @join__directive(graphs: [WITH_CONNECTORS], name: \\"source\\", args: {name: \\"v1\\", http: {baseURL: \\"http://v1\\"}}) + { + query: Query + } + + directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + + directive @join__graph(name: String!, url: String!) on ENUM_VALUE + + directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + + directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + + directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE + + directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + + directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + + directive @join__directive(graphs: [join__Graph!], name: String!, args: join__DirectiveArguments) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + + enum link__Purpose { + \\"\\"\\" + \`SECURITY\` features provide metadata necessary to securely resolve fields. + \\"\\"\\" + SECURITY + + \\"\\"\\" + \`EXECUTION\` features provide metadata necessary for operation execution. + \\"\\"\\" + EXECUTION + } + + scalar link__Import + + enum join__Graph { + WITH_CONNECTORS @join__graph(name: \\"with-connectors\\", url: \\"\\") + } + + scalar join__FieldSet + + scalar join__DirectiveArguments + + scalar join__FieldValue + + input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! + } + + type Query + @join__type(graph: WITH_CONNECTORS) + { + resources: [Resource!]! @join__directive(graphs: [WITH_CONNECTORS], name: \\"http\\", args: {source: \\"v1\\", http: {GET: \\"/resources\\"}, selection: \\"\\"}) + } + + type Resource + @join__type(graph: WITH_CONNECTORS, key: \\"id\\") + { + id: ID! + name: String! + }" + `); + + if (result.schema) { + expect(printSchema(result.schema.toAPISchema())).toMatchInlineSnapshot(` + "type Query { + resources: [Resource!]! + } + + type Resource { + id: ID! + name: String! + }" + `); + } + }); + + it("composes v0.2", () => { + const subgraphs = [ + { + name: "with-connectors-v0_2", + typeDefs: parse(` + extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.11" + import: ["@key"] + ) + @link( + url: "https://specs.apollo.dev/connect/v0.2" + import: ["@connect", "@source"] + ) + @source( + name: "v1" + http: { + baseURL: "http://v1" + path: "" + queryParams: "" + } + errors: { message: "" extensions: "" } + ) + + type Query { + resources: [Resource!]! + @connect(source: "v1", http: { GET: "/resources" }, selection: "") + } + + type Resource @key(fields: "id") + @connect( + source: "v1" + http: { + GET: "/resources" + path: "" + queryParams: "" + } + batch: { maxSize: 5 } + errors: { message: "" extensions: "" } + selection: "" + ) { + id: ID! + name: String! + } + `), + }, + { + name: "with-connectors-v0_1", + typeDefs: parse(` + extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.10" + import: ["@key"] + ) + @link( + url: "https://specs.apollo.dev/connect/v0.1" + import: ["@connect", "@source"] + ) + @source(name: "v1", http: { baseURL: "http://v1" }) + + type Query { + widgets: [Widget!]! + @connect(source: "v1", http: { GET: "/widgets" }, selection: "") + } + + type Widget @key(fields: "id") { + id: ID! + name: String! + } + `), + }, + ]; + + const result = composeServices(subgraphs); + expect(result.errors ?? []).toEqual([]); + const printed = printSchema(result.schema!); + expect(printed).toMatchInlineSnapshot(` + "schema + @link(url: \\"https://specs.apollo.dev/link/v1.0\\") + @link(url: \\"https://specs.apollo.dev/join/v0.5\\", for: EXECUTION) + @link(url: \\"https://specs.apollo.dev/connect/v0.2\\", for: EXECUTION) + @join__directive(graphs: [WITH_CONNECTORS_V0_1_], name: \\"link\\", args: {url: \\"https://specs.apollo.dev/connect/v0.1\\", import: [\\"@connect\\", \\"@source\\"]}) + @join__directive(graphs: [WITH_CONNECTORS_V0_2_], name: \\"link\\", args: {url: \\"https://specs.apollo.dev/connect/v0.2\\", import: [\\"@connect\\", \\"@source\\"]}) + @join__directive(graphs: [WITH_CONNECTORS_V0_1_], name: \\"source\\", args: {name: \\"v1\\", http: {baseURL: \\"http://v1\\"}}) + @join__directive(graphs: [WITH_CONNECTORS_V0_2_], name: \\"source\\", args: {name: \\"v1\\", http: {baseURL: \\"http://v1\\", path: \\"\\", queryParams: \\"\\"}, errors: {message: \\"\\", extensions: \\"\\"}}) + { + query: Query + } + + directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + + directive @join__graph(name: String!, url: String!) on ENUM_VALUE + + directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + + directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + + directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE + + directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + + directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + + directive @join__directive(graphs: [join__Graph!], name: String!, args: join__DirectiveArguments) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + + enum link__Purpose { + \\"\\"\\" + \`SECURITY\` features provide metadata necessary to securely resolve fields. + \\"\\"\\" + SECURITY + + \\"\\"\\" + \`EXECUTION\` features provide metadata necessary for operation execution. + \\"\\"\\" + EXECUTION + } + + scalar link__Import + + enum join__Graph { + WITH_CONNECTORS_V0_1_ @join__graph(name: \\"with-connectors-v0_1\\", url: \\"\\") + WITH_CONNECTORS_V0_2_ @join__graph(name: \\"with-connectors-v0_2\\", url: \\"\\") + } + + scalar join__FieldSet + + scalar join__DirectiveArguments + + scalar join__FieldValue + + input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! + } + + type Query + @join__type(graph: WITH_CONNECTORS_V0_1_) + @join__type(graph: WITH_CONNECTORS_V0_2_) + { + widgets: [Widget!]! @join__field(graph: WITH_CONNECTORS_V0_1_) @join__directive(graphs: [WITH_CONNECTORS_V0_1_], name: \\"connect\\", args: {source: \\"v1\\", http: {GET: \\"/widgets\\"}, selection: \\"\\"}) + resources: [Resource!]! @join__field(graph: WITH_CONNECTORS_V0_2_) @join__directive(graphs: [WITH_CONNECTORS_V0_2_], name: \\"connect\\", args: {source: \\"v1\\", http: {GET: \\"/resources\\"}, selection: \\"\\"}) + } + + type Widget + @join__type(graph: WITH_CONNECTORS_V0_1_, key: \\"id\\") + { + id: ID! + name: String! + } + + type Resource + @join__type(graph: WITH_CONNECTORS_V0_2_, key: \\"id\\") + @join__directive(graphs: [WITH_CONNECTORS_V0_2_], name: \\"connect\\", args: {source: \\"v1\\", http: {GET: \\"/resources\\", path: \\"\\", queryParams: \\"\\"}, batch: {maxSize: 5}, errors: {message: \\"\\", extensions: \\"\\"}, selection: \\"\\"}) + { + id: ID! + name: String! + }" + `); + + if (result.schema) { + expect(printSchema(result.schema.toAPISchema())).toMatchInlineSnapshot(` + "type Query { + widgets: [Widget!]! + resources: [Resource!]! + } + + type Widget { + id: ID! + name: String! + } + + type Resource { + id: ID! + name: String! + }" + `); + } + }); + it("composes with renames", () => { const subgraphs = [ { @@ -161,7 +579,7 @@ describe("connect spec and join__directive", () => { "schema @link(url: \\"https://specs.apollo.dev/link/v1.0\\") @link(url: \\"https://specs.apollo.dev/join/v0.5\\", for: EXECUTION) - @link(url: \\"https://specs.apollo.dev/connect/v0.1\\", for: EXECUTION) + @link(url: \\"https://specs.apollo.dev/connect/v0.2\\", for: EXECUTION) @join__directive(graphs: [WITH_CONNECTORS], name: \\"link\\", args: {url: \\"https://specs.apollo.dev/connect/v0.1\\", as: \\"http\\", import: [{name: \\"@connect\\", as: \\"@http\\"}, {name: \\"@source\\", as: \\"@api\\"}]}) @join__directive(graphs: [WITH_CONNECTORS], name: \\"api\\", args: {name: \\"v1\\", http: {baseURL: \\"http://v1\\"}}) { diff --git a/composition-js/src/merging/merge.ts b/composition-js/src/merging/merge.ts index 11975a65a..d6f7d4915 100644 --- a/composition-js/src/merging/merge.ts +++ b/composition-js/src/merging/merge.ts @@ -84,6 +84,8 @@ import { DirectiveCompositionSpecification, CoreImport, inaccessibleIdentity, + FeatureDefinitions, + CONNECT_VERSIONS, } from "@apollo/federation-internals"; import { ASTNode, GraphQLError, DirectiveLocation } from "graphql"; import { @@ -376,7 +378,7 @@ class Merger { private linkSpec: CoreSpecDefinition; private inaccessibleDirectiveInSupergraph?: DirectiveDefinition; private latestFedVersionUsed: FeatureVersion; - private joinDirectiveIdentityURLs = new Set(); + private joinDirectiveFeatureDefinitionsByIdentity = new Map(); private schemaToImportNameToFeatureUrl = new Map>(); private fieldsWithFromContext: Set; private fieldsWithOverride: Set; @@ -413,10 +415,9 @@ class Merger { this.subgraphNamesToJoinSpecName = this.prepareSupergraph(); this.appliedDirectivesToMerge = []; - [ // Represent any applications of directives imported from these spec URLs - // using @join__directive in the merged supergraph. - connectIdentity, - ].forEach(url => this.joinDirectiveIdentityURLs.add(url)); + // Represent any applications of directives imported from these spec URLs + // using @join__directive in the merged supergraph. + this.joinDirectiveFeatureDefinitionsByIdentity.set(CONNECT_VERSIONS.identity, CONNECT_VERSIONS); } private getLatestFederationVersionUsed(): FeatureVersion { @@ -1102,7 +1103,6 @@ class Merger { if (!source) { continue; } - const sourceMetadata = this.subgraphs.values()[idx].metadata(); const keyDirective = sourceMetadata.keyDirective(); if (source.hasAppliedDirective(keyDirective)) { @@ -1874,7 +1874,7 @@ class Merger { if (!sameType(destArg.type!, arg.type!) && !this.isStrictSubtype(arg.type!, destArg.type!)) { invalidArgsTypes.add(name); } - if (destArg.defaultValue !== arg.defaultValue) { + if (!valueEquals(destArg.defaultValue, arg.defaultValue)) { invalidArgsDefaults.add(name); } } @@ -3105,10 +3105,7 @@ class Merger { } private shouldUseJoinDirectiveForURL(url: FeatureUrl | undefined): boolean { - return Boolean( - url && - this.joinDirectiveIdentityURLs.has(url.identity) - ); + return Boolean(url && this.joinDirectiveFeatureDefinitionsByIdentity.has(url.identity)); } private computeMapFromImportNameToIdentityUrl( @@ -3118,14 +3115,19 @@ class Merger { // identity url in a Map, reachable from all its imported names. const map = new Map(); for (const linkDirective of schema.schemaDefinition.appliedDirectivesOf('link')) { - const { url, import: imports } = linkDirective.arguments(); + const { url, as, import: imports } = linkDirective.arguments(); const parsedUrl = FeatureUrl.maybeParse(url); - if (parsedUrl && imports) { - for (const i of imports) { - if (typeof i === 'string') { - map.set(i, parsedUrl); - } else { - map.set(i.as ?? i.name, parsedUrl); + + if (parsedUrl) { + // always add the main directive to the map, regardless of whether it is imported + map.set(`@${as ?? parsedUrl.name}`, parsedUrl); + if (imports) { + for (const i of imports) { + if (typeof i === 'string') { + map.set(i, parsedUrl); + } else { + map.set(i.as ?? i.name, parsedUrl); + } } } } @@ -3208,7 +3210,30 @@ class Merger { } const linkDirective = this.linkSpec.coreDirective(this.merged); - for (const link of linksToPersist) { + + // When persisting features as @link directives in the supergraph, we have + // to pick a single version. For these features, we've decided to always + // pick the latest known version, regardless of what version is use in + // subgraphs. This means that a composition version change will change the + // output, even if the subgraphs don't change, requiring a newer version of + // the router. We made this decision because these features are pre-1.0 and + // change more frequently than federation features. + // + // (The original feature version is still recorded in a @join__directive + // so we're not losing any information.) + const latestOrHighestLinkByIdentity = [...linksToPersist].reduce((map, link) => { + let latest = this.joinDirectiveFeatureDefinitionsByIdentity.get(link.identity)?.latest(); + + const existing = map.get(link.identity) ?? link; + if (!latest || existing?.version.gt(latest.version)) { + latest = existing; + } + + map.set(link.identity, latest); + return map; + }, new Map()); + + for (const [_, link] of latestOrHighestLinkByIdentity) { dest.applyDirective(linkDirective, { url: link.toString(), for: link.defaultCorePurpose, diff --git a/docs/source/schema-design/federated-schemas/entities/intro.mdx b/docs/source/schema-design/federated-schemas/entities/intro.mdx index 2ee4c1de1..199851047 100644 --- a/docs/source/schema-design/federated-schemas/entities/intro.mdx +++ b/docs/source/schema-design/federated-schemas/entities/intro.mdx @@ -106,7 +106,7 @@ type Product @key(fields: "upc") { ```graphql title="Reviews subgraph" type Product @key(fields: "productUpc") { productUpc: ID! - inStock: Boolean! + rating: Int! } ``` diff --git a/docs/source/schema-design/federated-schemas/reference/backward-compatibility.mdx b/docs/source/schema-design/federated-schemas/reference/backward-compatibility.mdx index fa1bee5f1..0a23513f9 100644 --- a/docs/source/schema-design/federated-schemas/reference/backward-compatibility.mdx +++ b/docs/source/schema-design/federated-schemas/reference/backward-compatibility.mdx @@ -6,7 +6,7 @@ description: Frequently asked questions when transitioning from Apollo Federatio ## Is official support ending for `@apollo/gateway` v0.x? -Yes. As of 15 November 2022, `@apollo/gateway` v0.x is officially deprecated, with end-of-life scheduled for 22 September 2023. `@apollo/gateway` v2.x remains fully supported. +Yes. `@apollo/gateway` v0.x was officially deprecated as of 15 November 2022 and reached end-of-life on 22 September 2023. `@apollo/gateway` v2.x remains fully supported. [Learn more about deprecation and end-of-life.](https://www.apollographql.com/docs/resources/product-launch-stages#stages-for-discontinuing-support) diff --git a/docs/source/schema-design/federated-schemas/reference/versions.mdx b/docs/source/schema-design/federated-schemas/reference/versions.mdx index 168631d52..f60ae2eaf 100644 --- a/docs/source/schema-design/federated-schemas/reference/versions.mdx +++ b/docs/source/schema-design/federated-schemas/reference/versions.mdx @@ -19,47 +19,34 @@ For a comprehensive changelog for Apollo Federation and its associated libraries The example above must target at least Federation v2.3, because the `@interfaceObject` directive was introduced in that version. - + Before you increment a subgraph's federation version, update your router and build pipeline. For details, see [Updating your graph safely](/graphos/platform/graph-management/updates). - If you maintain a [subgraph-compatible library](/graphos/reference/federation/compatible-subgraphs), consult this article to stay current with recently added directives. All of these directive definitions are also listed in the [subgraph specification](/graphos/reference/federation/subgraph-spec/#subgraph-schema-additions). -## v2.10 +## v2.11
| First release | Available in GraphOS? | Minimum router version | | ------------- | --------------------- | ---------------------- | -| **February 2025** | **Yes** | **`2.0.0`** | - -#### Directive changes +| **June 2025** | **Yes** | **`2.3.0`** | -#### `@connect` +Federation v2.11 is a prerequisite for the Connector specification version 0.2. +[Learn more.](/graphos/schema-design/connectors/directives) -Introduced. [Learn more](/graphos/schema-design/connectors/directives#connect). - -```graphql showLineNumbers=false disableCopy=true -directive @connect( - source: String - http: ConnectHTTP! - selection: JSONSelection! - entity: Boolean -) repeatable on FIELD_DEFINITION; - -``` +## v2.10 -#### `@source` +
-Introduced. [Learn more](/graphos/schema-design/connectors/directives#source). +| First release | Available in GraphOS? | Minimum router version | +| ------------- | --------------------- | ---------------------- | +| **February 2025** | **Yes** | **`2.0.0`** | -```graphql showLineNumbers=false disableCopy=true -directive @source( - name: String! - http: SourceHTTP! -) repeatable on SCHEMA; -``` +Federation v2.10 is a prerequisite for the Connector specification that introduces the `@connect` and `@source` directives. +[Learn more.](/graphos/schema-design/connectors/directives) ## v2.9 @@ -78,10 +65,10 @@ Introduced. [Learn more](/federation/federated-schemas/federated-directives#cost ```graphql showLineNumbers=false disableCopy=true directive @cost(weight: Int!) on | ARGUMENT_DEFINITION - | ENUM - | FIELD_DEFINITION - | INPUT_FIELD_DEFINITION - | OBJECT + | ENUM + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | OBJECT | SCALAR; ``` diff --git a/federation-integration-testsuite-js/CHANGELOG.md b/federation-integration-testsuite-js/CHANGELOG.md index 7f89815ca..c934fca4d 100644 --- a/federation-integration-testsuite-js/CHANGELOG.md +++ b/federation-integration-testsuite-js/CHANGELOG.md @@ -1,5 +1,19 @@ # CHANGELOG for `federation-integration-testsuite-js` +## 2.11.0-preview.2 + +### Patch Changes + +- Preparing preview.2 release ([#3255](https://github.com/apollographql/federation/pull/3255)) + +## 2.11.0-preview.1 + +## 2.11.0-preview.0 + +### Minor Changes + +- Add connect spec v0.2 ([#3228](https://github.com/apollographql/federation/pull/3228)) + ## 2.10.0 ### Minor Changes diff --git a/federation-integration-testsuite-js/package.json b/federation-integration-testsuite-js/package.json index abd1a69d8..67926d433 100644 --- a/federation-integration-testsuite-js/package.json +++ b/federation-integration-testsuite-js/package.json @@ -1,7 +1,7 @@ { "name": "apollo-federation-integration-testsuite", "private": true, - "version": "2.10.0", + "version": "2.11.0-preview.2", "description": "Apollo Federation Integrations / Test Fixtures", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/gateway-js/CHANGELOG.md b/gateway-js/CHANGELOG.md index 2db6d8dc2..e0281f230 100644 --- a/gateway-js/CHANGELOG.md +++ b/gateway-js/CHANGELOG.md @@ -1,5 +1,42 @@ # CHANGELOG for `@apollo/gateway` +## 2.11.0-preview.2 + +### Patch Changes + +- Preparing preview.2 release ([#3255](https://github.com/apollographql/federation/pull/3255)) + +- Updated dependencies [[`3e2b0a8569a9fe46726182887ed0b4bfc0b52468`](https://github.com/apollographql/federation/commit/3e2b0a8569a9fe46726182887ed0b4bfc0b52468)]: + - @apollo/query-planner@2.11.0-preview.2 + - @apollo/composition@2.11.0-preview.2 + - @apollo/federation-internals@2.11.0-preview.2 + +## 2.11.0-preview.1 + +### Patch Changes + +- Corrects a set of denial-of-service (DOS) vulnerabilities that made it possible for an attacker to render gateway inoperable with certain simple query patterns due to uncontrolled resource consumption. All prior-released versions and configurations are vulnerable. ([#3238](https://github.com/apollographql/federation/pull/3238)) + + See the associated GitHub Advisories [GHSA-q2f9-x4p4-7xmh](https://github.com/apollographql/federation/security/advisories/GHSA-q2f9-x4p4-7xmh) and [GHSA-p2q6-pwh5-m6jr](https://github.com/apollographql/federation/security/advisories/GHSA-p2q6-pwh5-m6jr) for more information. + +- Updated dependencies [[`1462c91879d41884c0a7e60551d8dd0d67c832d3`](https://github.com/apollographql/federation/commit/1462c91879d41884c0a7e60551d8dd0d67c832d3)]: + - @apollo/query-planner@2.11.0-preview.1 + - @apollo/federation-internals@2.11.0-preview.1 + - @apollo/composition@2.11.0-preview.1 + +## 2.11.0-preview.0 + +### Minor Changes + +- Add connect spec v0.2 ([#3228](https://github.com/apollographql/federation/pull/3228)) + +### Patch Changes + +- Updated dependencies [[`e7e67579908d5cd2fa6fe558228dffe4808cd98d`](https://github.com/apollographql/federation/commit/e7e67579908d5cd2fa6fe558228dffe4808cd98d)]: + - @apollo/composition@2.11.0-preview.0 + - @apollo/federation-internals@2.11.0-preview.0 + - @apollo/query-planner@2.11.0-preview.0 + ## 2.10.0 ### Patch Changes diff --git a/gateway-js/package.json b/gateway-js/package.json index 696366124..fc7f8e9ee 100644 --- a/gateway-js/package.json +++ b/gateway-js/package.json @@ -1,6 +1,6 @@ { "name": "@apollo/gateway", - "version": "2.10.0", + "version": "2.11.0-preview.2", "description": "Apollo Gateway", "author": "Apollo ", "main": "dist/index.js", @@ -25,9 +25,9 @@ "access": "public" }, "dependencies": { - "@apollo/composition": "2.10.0", - "@apollo/federation-internals": "2.10.0", - "@apollo/query-planner": "2.10.0", + "@apollo/composition": "2.11.0-preview.2", + "@apollo/federation-internals": "2.11.0-preview.2", + "@apollo/query-planner": "2.11.0-preview.2", "@apollo/server-gateway-interface": "^1.1.0", "@apollo/usage-reporting-protobuf": "^4.1.0", "@apollo/utils.createhash": "^2.0.0", diff --git a/internals-js/CHANGELOG.md b/internals-js/CHANGELOG.md index 6b4963ea4..1ce8f77bf 100644 --- a/internals-js/CHANGELOG.md +++ b/internals-js/CHANGELOG.md @@ -1,5 +1,25 @@ # CHANGELOG for `@apollo/federation-internals` +## 2.11.0-preview.2 + +### Patch Changes + +- Preparing preview.2 release ([#3255](https://github.com/apollographql/federation/pull/3255)) + +## 2.11.0-preview.1 + +### Patch Changes + +- Corrects a set of denial-of-service (DOS) vulnerabilities that made it possible for an attacker to render gateway inoperable with certain simple query patterns due to uncontrolled resource consumption. All prior-released versions and configurations are vulnerable. ([#3238](https://github.com/apollographql/federation/pull/3238)) + + See the associated GitHub Advisories [GHSA-q2f9-x4p4-7xmh](https://github.com/apollographql/federation/security/advisories/GHSA-q2f9-x4p4-7xmh) and [GHSA-p2q6-pwh5-m6jr](https://github.com/apollographql/federation/security/advisories/GHSA-p2q6-pwh5-m6jr) for more information. + +## 2.11.0-preview.0 + +### Minor Changes + +- Add connect spec v0.2 ([#3228](https://github.com/apollographql/federation/pull/3228)) + ## 2.10.0 ### Minor Changes diff --git a/internals-js/package.json b/internals-js/package.json index 837475c8a..2a928c143 100644 --- a/internals-js/package.json +++ b/internals-js/package.json @@ -1,6 +1,6 @@ { "name": "@apollo/federation-internals", - "version": "2.10.0", + "version": "2.11.0-preview.2", "description": "Apollo Federation internal utilities", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/internals-js/src/federation.ts b/internals-js/src/federation.ts index 3e18dd5c4..835168e5c 100644 --- a/internals-js/src/federation.ts +++ b/internals-js/src/federation.ts @@ -1954,9 +1954,9 @@ export function setSchemaAsFed2Subgraph(schema: Schema, useLatest: boolean = fal // This is the full @link declaration as added by `asFed2SubgraphDocument`. It's here primarily for uses by tests that print and match // subgraph schema to avoid having to update 20+ tests every time we use a new directive or the order of import changes ... -export const FEDERATION2_LINK_WITH_FULL_IMPORTS = '@link(url: "https://specs.apollo.dev/federation/v2.10", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject", "@authenticated", "@requiresScopes", "@policy", "@context", "@fromContext", "@cost", "@listSize"])'; +export const FEDERATION2_LINK_WITH_FULL_IMPORTS = '@link(url: "https://specs.apollo.dev/federation/v2.11", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject", "@authenticated", "@requiresScopes", "@policy", "@context", "@fromContext", "@cost", "@listSize"])'; // This is the full @link declaration that is added when upgrading fed v1 subgraphs to v2 version. It should only be used by tests. -export const FEDERATION2_LINK_WITH_AUTO_EXPANDED_IMPORTS = '@link(url: "https://specs.apollo.dev/federation/v2.10", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject"])'; +export const FEDERATION2_LINK_WITH_AUTO_EXPANDED_IMPORTS = '@link(url: "https://specs.apollo.dev/federation/v2.11", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject"])'; // This is the federation @link for tests that go through the SchemaUpgrader. export const FEDERATION2_LINK_WITH_AUTO_EXPANDED_IMPORTS_UPGRADED = '@link(url: "https://specs.apollo.dev/federation/v2.4", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject"])'; diff --git a/internals-js/src/specs/connectSpec.ts b/internals-js/src/specs/connectSpec.ts index 213325061..43111d1ab 100644 --- a/internals-js/src/specs/connectSpec.ts +++ b/internals-js/src/specs/connectSpec.ts @@ -1,5 +1,11 @@ -import {DirectiveLocation, GraphQLError} from 'graphql'; -import { CorePurpose, FeatureDefinition, FeatureDefinitions, FeatureUrl, FeatureVersion } from "./coreSpec"; +import { DirectiveLocation, GraphQLError } from 'graphql'; +import { + CorePurpose, + FeatureDefinition, + FeatureDefinitions, + FeatureUrl, + FeatureVersion, +} from './coreSpec'; import { Schema, NonNullType, @@ -8,40 +14,57 @@ import { ListType, } from '../definitions'; import { registerKnownFeature } from '../knownCoreFeatures'; -import { createDirectiveSpecification, createScalarTypeSpecification } from '../directiveAndTypeSpecification'; +import { + createDirectiveSpecification, + createScalarTypeSpecification, +} from '../directiveAndTypeSpecification'; export const connectIdentity = 'https://specs.apollo.dev/connect'; -const CONNECT = "connect"; -const SOURCE = "source"; -const URL_PATH_TEMPLATE = "URLPathTemplate"; -const JSON_SELECTION = "JSONSelection"; -const CONNECT_HTTP = "ConnectHTTP"; +const CONNECT = 'connect'; +const SOURCE = 'source'; +const URL_PATH_TEMPLATE = 'URLPathTemplate'; +const JSON_SELECTION = 'JSONSelection'; +const CONNECT_HTTP = 'ConnectHTTP'; +const CONNECT_BATCH = 'ConnectBatch'; +const CONNECTOR_ERRORS = "ConnectorErrors"; const SOURCE_HTTP = "SourceHTTP"; -const HTTP_HEADER_MAPPING = "HTTPHeaderMapping"; +const HTTP_HEADER_MAPPING = 'HTTPHeaderMapping'; export class ConnectSpecDefinition extends FeatureDefinition { - constructor(version: FeatureVersion, readonly minimumFederationVersion: FeatureVersion) { - super(new FeatureUrl(connectIdentity, CONNECT, version), minimumFederationVersion); - - this.registerDirective(createDirectiveSpecification({ - name: CONNECT, - locations: [DirectiveLocation.FIELD_DEFINITION], - repeatable: true, - // We "compose" these directives using the `@join__directive` mechanism, - // so they do not need to be composed in the way passing `composes: true` - // here implies. - composes: false, - })); - - this.registerDirective(createDirectiveSpecification({ - name: SOURCE, - locations: [DirectiveLocation.SCHEMA], - repeatable: true, - composes: false, - })); - - this.registerType(createScalarTypeSpecification({ name: URL_PATH_TEMPLATE })); + constructor( + version: FeatureVersion, + readonly minimumFederationVersion: FeatureVersion, + ) { + super( + new FeatureUrl(connectIdentity, CONNECT, version), + minimumFederationVersion, + ); + + this.registerDirective( + createDirectiveSpecification({ + name: CONNECT, + locations: [DirectiveLocation.FIELD_DEFINITION], + repeatable: true, + // We "compose" these directives using the `@join__directive` mechanism, + // so they do not need to be composed in the way passing `composes: true` + // here implies. + composes: false, + }), + ); + + this.registerDirective( + createDirectiveSpecification({ + name: SOURCE, + locations: [DirectiveLocation.SCHEMA], + repeatable: true, + composes: false, + }), + ); + + this.registerType( + createScalarTypeSpecification({ name: URL_PATH_TEMPLATE }), + ); this.registerType(createScalarTypeSpecification({ name: JSON_SELECTION })); this.registerType({ name: CONNECT_HTTP, checkOrAdd: () => [] }); this.registerType({ name: SOURCE_HTTP, checkOrAdd: () => [] }); @@ -61,9 +84,14 @@ export class ConnectSpecDefinition extends FeatureDefinition { http: ConnectHTTP selection: JSONSelection! entity: Boolean = false + errors: ConnectorErrors ) repeatable on FIELD_DEFINITION + | OBJECT # added in v0.2, validation enforced in rust */ - const connect = this.addDirective(schema, CONNECT).addLocations(DirectiveLocation.FIELD_DEFINITION); + const connect = this.addDirective(schema, CONNECT).addLocations( + DirectiveLocation.FIELD_DEFINITION, + DirectiveLocation.OBJECT, + ); connect.repeatable = true; connect.addArgument(SOURCE, schema.stringType()); @@ -75,7 +103,9 @@ export class ConnectSpecDefinition extends FeatureDefinition { value: String } */ - const HTTPHeaderMapping = schema.addType(new InputObjectType(this.typeNameInSchema(schema, HTTP_HEADER_MAPPING)!)); + const HTTPHeaderMapping = schema.addType( + new InputObjectType(this.typeNameInSchema(schema, HTTP_HEADER_MAPPING)!), + ); HTTPHeaderMapping.addField(new InputFieldDefinition('name')).type = new NonNullType(schema.stringType()); HTTPHeaderMapping.addField(new InputFieldDefinition('from')).type = @@ -92,19 +122,44 @@ export class ConnectSpecDefinition extends FeatureDefinition { DELETE: URLPathTemplate body: JSONSelection headers: [HTTPHeaderMapping!] + + # added in v0.2 + path: JSONSelection + query: JSONSelection } */ - const ConnectHTTP = schema.addType(new InputObjectType(this.typeNameInSchema(schema, CONNECT_HTTP)!)); - ConnectHTTP.addField(new InputFieldDefinition('GET')).type = URLPathTemplate; - ConnectHTTP.addField(new InputFieldDefinition('POST')).type = URLPathTemplate; - ConnectHTTP.addField(new InputFieldDefinition('PUT')).type = URLPathTemplate; - ConnectHTTP.addField(new InputFieldDefinition('PATCH')).type = URLPathTemplate; - ConnectHTTP.addField(new InputFieldDefinition('DELETE')).type = URLPathTemplate; + const ConnectHTTP = schema.addType( + new InputObjectType(this.typeNameInSchema(schema, CONNECT_HTTP)!), + ); + ConnectHTTP.addField(new InputFieldDefinition('GET')).type = + URLPathTemplate; + ConnectHTTP.addField(new InputFieldDefinition('POST')).type = + URLPathTemplate; + ConnectHTTP.addField(new InputFieldDefinition('PUT')).type = + URLPathTemplate; + ConnectHTTP.addField(new InputFieldDefinition('PATCH')).type = + URLPathTemplate; + ConnectHTTP.addField(new InputFieldDefinition('DELETE')).type = + URLPathTemplate; ConnectHTTP.addField(new InputFieldDefinition('body')).type = JSONSelection; ConnectHTTP.addField(new InputFieldDefinition('headers')).type = new ListType(new NonNullType(HTTPHeaderMapping)); + + ConnectHTTP.addField(new InputFieldDefinition('path')).type = JSONSelection; + ConnectHTTP.addField(new InputFieldDefinition('queryParams')).type = + JSONSelection; + connect.addArgument('http', new NonNullType(ConnectHTTP)); + const ConnectBatch = schema.addType(new InputObjectType(this.typeNameInSchema(schema, CONNECT_BATCH)!)); + ConnectBatch.addField(new InputFieldDefinition('maxSize')).type = schema.intType(); + connect.addArgument('batch', ConnectBatch); + + const ConnectorErrors = schema.addType(new InputObjectType(this.typeNameInSchema(schema, CONNECTOR_ERRORS)!)); + ConnectorErrors.addField(new InputFieldDefinition('message')).type = JSONSelection; + ConnectorErrors.addField(new InputFieldDefinition('extensions')).type = JSONSelection; + connect.addArgument('errors', ConnectorErrors); + connect.addArgument('selection', new NonNullType(JSONSelection)); connect.addArgument('entity', schema.booleanType(), false); @@ -112,6 +167,7 @@ export class ConnectSpecDefinition extends FeatureDefinition { directive @source( name: String! http: ConnectHTTP + errors: ConnectorErrors ) repeatable on SCHEMA */ const source = this.addDirective(schema, SOURCE).addLocations( @@ -124,15 +180,25 @@ export class ConnectSpecDefinition extends FeatureDefinition { input SourceHTTP { baseURL: String! headers: [HTTPHeaderMapping!] + + # added in v0.2 + path: JSONSelection + query: JSONSelection } */ - const SourceHTTP = schema.addType(new InputObjectType(this.typeNameInSchema(schema, SOURCE_HTTP)!)); + const SourceHTTP = schema.addType( + new InputObjectType(this.typeNameInSchema(schema, SOURCE_HTTP)!), + ); SourceHTTP.addField(new InputFieldDefinition('baseURL')).type = new NonNullType(schema.stringType()); SourceHTTP.addField(new InputFieldDefinition('headers')).type = new ListType(new NonNullType(HTTPHeaderMapping)); + SourceHTTP.addField(new InputFieldDefinition('path')).type = JSONSelection; + SourceHTTP.addField(new InputFieldDefinition('queryParams')).type = JSONSelection; + source.addArgument('http', new NonNullType(SourceHTTP)); + source.addArgument('errors', ConnectorErrors); return []; } @@ -142,7 +208,20 @@ export class ConnectSpecDefinition extends FeatureDefinition { } } -export const CONNECT_VERSIONS = new FeatureDefinitions(connectIdentity) - .add(new ConnectSpecDefinition(new FeatureVersion(0, 1), new FeatureVersion(2, 10))); +export const CONNECT_VERSIONS = new FeatureDefinitions( + connectIdentity, +) + .add( + new ConnectSpecDefinition( + new FeatureVersion(0, 1), + new FeatureVersion(2, 10), + ), + ) + .add( + new ConnectSpecDefinition( + new FeatureVersion(0, 2), + new FeatureVersion(2, 10), + ), + ); registerKnownFeature(CONNECT_VERSIONS); diff --git a/internals-js/src/specs/federationSpec.ts b/internals-js/src/specs/federationSpec.ts index 37084b057..18f112fc2 100644 --- a/internals-js/src/specs/federationSpec.ts +++ b/internals-js/src/specs/federationSpec.ts @@ -195,6 +195,7 @@ export const FEDERATION_VERSIONS = new FeatureDefinitions=14.15.0" @@ -85,7 +85,7 @@ }, "federation-integration-testsuite-js": { "name": "apollo-federation-integration-testsuite", - "version": "2.10.0", + "version": "2.11.0-preview.2", "license": "Elastic-2.0", "dependencies": { "graphql-tag": "^2.12.6", @@ -94,12 +94,12 @@ }, "gateway-js": { "name": "@apollo/gateway", - "version": "2.10.0", + "version": "2.11.0-preview.2", "license": "Elastic-2.0", "dependencies": { - "@apollo/composition": "2.10.0", - "@apollo/federation-internals": "2.10.0", - "@apollo/query-planner": "2.10.0", + "@apollo/composition": "2.11.0-preview.2", + "@apollo/federation-internals": "2.11.0-preview.2", + "@apollo/query-planner": "2.11.0-preview.2", "@apollo/server-gateway-interface": "^1.1.0", "@apollo/usage-reporting-protobuf": "^4.1.0", "@apollo/utils.createhash": "^2.0.0", @@ -125,7 +125,7 @@ }, "internals-js": { "name": "@apollo/federation-internals", - "version": "2.10.0", + "version": "2.11.0-preview.2", "license": "Elastic-2.0", "dependencies": { "@types/uuid": "^9.0.0", @@ -17841,10 +17841,10 @@ }, "query-graphs-js": { "name": "@apollo/query-graphs", - "version": "2.10.0", + "version": "2.11.0-preview.2", "license": "Elastic-2.0", "dependencies": { - "@apollo/federation-internals": "2.10.0", + "@apollo/federation-internals": "2.11.0-preview.2", "deep-equal": "^2.0.5", "ts-graphviz": "^1.5.4", "uuid": "^9.0.0" @@ -17858,11 +17858,11 @@ }, "query-planner-js": { "name": "@apollo/query-planner", - "version": "2.10.0", + "version": "2.11.0-preview.2", "license": "Elastic-2.0", "dependencies": { - "@apollo/federation-internals": "2.10.0", - "@apollo/query-graphs": "2.10.0", + "@apollo/federation-internals": "2.11.0-preview.2", + "@apollo/query-graphs": "2.11.0-preview.2", "@apollo/utils.keyvaluecache": "^2.1.0", "chalk": "^4.1.0", "deep-equal": "^2.0.5", @@ -17891,11 +17891,11 @@ }, "subgraph-js": { "name": "@apollo/subgraph", - "version": "2.10.0", + "version": "2.11.0-preview.2", "license": "MIT", "dependencies": { "@apollo/cache-control-types": "^1.0.2", - "@apollo/federation-internals": "2.10.0" + "@apollo/federation-internals": "2.11.0-preview.2" }, "engines": { "node": ">=14.15.0" diff --git a/query-graphs-js/CHANGELOG.md b/query-graphs-js/CHANGELOG.md index 653482957..ca74c3ded 100644 --- a/query-graphs-js/CHANGELOG.md +++ b/query-graphs-js/CHANGELOG.md @@ -1,5 +1,36 @@ # CHANGELOG for `@apollo/query-graphs` +## 2.11.0-preview.2 + +### Patch Changes + +- Preparing preview.2 release ([#3255](https://github.com/apollographql/federation/pull/3255)) + +- Updated dependencies [[`3e2b0a8569a9fe46726182887ed0b4bfc0b52468`](https://github.com/apollographql/federation/commit/3e2b0a8569a9fe46726182887ed0b4bfc0b52468)]: + - @apollo/federation-internals@2.11.0-preview.2 + +## 2.11.0-preview.1 + +### Patch Changes + +- Corrects a set of denial-of-service (DOS) vulnerabilities that made it possible for an attacker to render gateway inoperable with certain simple query patterns due to uncontrolled resource consumption. All prior-released versions and configurations are vulnerable. ([#3238](https://github.com/apollographql/federation/pull/3238)) + + See the associated GitHub Advisories [GHSA-q2f9-x4p4-7xmh](https://github.com/apollographql/federation/security/advisories/GHSA-q2f9-x4p4-7xmh) and [GHSA-p2q6-pwh5-m6jr](https://github.com/apollographql/federation/security/advisories/GHSA-p2q6-pwh5-m6jr) for more information. + +- Updated dependencies [[`1462c91879d41884c0a7e60551d8dd0d67c832d3`](https://github.com/apollographql/federation/commit/1462c91879d41884c0a7e60551d8dd0d67c832d3)]: + - @apollo/federation-internals@2.11.0-preview.1 + +## 2.11.0-preview.0 + +### Minor Changes + +- Add connect spec v0.2 ([#3228](https://github.com/apollographql/federation/pull/3228)) + +### Patch Changes + +- Updated dependencies [[`e7e67579908d5cd2fa6fe558228dffe4808cd98d`](https://github.com/apollographql/federation/commit/e7e67579908d5cd2fa6fe558228dffe4808cd98d)]: + - @apollo/federation-internals@2.11.0-preview.0 + ## 2.10.0 ### Minor Changes diff --git a/query-graphs-js/package.json b/query-graphs-js/package.json index 75fcb3fe8..10663048d 100644 --- a/query-graphs-js/package.json +++ b/query-graphs-js/package.json @@ -1,6 +1,6 @@ { "name": "@apollo/query-graphs", - "version": "2.10.0", + "version": "2.11.0-preview.2", "description": "Apollo Federation library to work with 'query graphs'", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -23,7 +23,7 @@ "node": ">=14.15.0" }, "dependencies": { - "@apollo/federation-internals": "2.10.0", + "@apollo/federation-internals": "2.11.0-preview.2", "deep-equal": "^2.0.5", "ts-graphviz": "^1.5.4", "uuid": "^9.0.0" diff --git a/query-planner-js/CHANGELOG.md b/query-planner-js/CHANGELOG.md index b90e43215..c6ffe8855 100644 --- a/query-planner-js/CHANGELOG.md +++ b/query-planner-js/CHANGELOG.md @@ -1,5 +1,39 @@ # CHANGELOG for `@apollo/query-planner` +## 2.11.0-preview.2 + +### Patch Changes + +- Preparing preview.2 release ([#3255](https://github.com/apollographql/federation/pull/3255)) + +- Updated dependencies [[`3e2b0a8569a9fe46726182887ed0b4bfc0b52468`](https://github.com/apollographql/federation/commit/3e2b0a8569a9fe46726182887ed0b4bfc0b52468)]: + - @apollo/query-graphs@2.11.0-preview.2 + - @apollo/federation-internals@2.11.0-preview.2 + +## 2.11.0-preview.1 + +### Patch Changes + +- Corrects a set of denial-of-service (DOS) vulnerabilities that made it possible for an attacker to render gateway inoperable with certain simple query patterns due to uncontrolled resource consumption. All prior-released versions and configurations are vulnerable. ([#3238](https://github.com/apollographql/federation/pull/3238)) + + See the associated GitHub Advisories [GHSA-q2f9-x4p4-7xmh](https://github.com/apollographql/federation/security/advisories/GHSA-q2f9-x4p4-7xmh) and [GHSA-p2q6-pwh5-m6jr](https://github.com/apollographql/federation/security/advisories/GHSA-p2q6-pwh5-m6jr) for more information. + +- Updated dependencies [[`1462c91879d41884c0a7e60551d8dd0d67c832d3`](https://github.com/apollographql/federation/commit/1462c91879d41884c0a7e60551d8dd0d67c832d3)]: + - @apollo/query-graphs@2.11.0-preview.1 + - @apollo/federation-internals@2.11.0-preview.1 + +## 2.11.0-preview.0 + +### Minor Changes + +- Add connect spec v0.2 ([#3228](https://github.com/apollographql/federation/pull/3228)) + +### Patch Changes + +- Updated dependencies [[`e7e67579908d5cd2fa6fe558228dffe4808cd98d`](https://github.com/apollographql/federation/commit/e7e67579908d5cd2fa6fe558228dffe4808cd98d)]: + - @apollo/federation-internals@2.11.0-preview.0 + - @apollo/query-graphs@2.11.0-preview.0 + ## 2.10.0 ### Minor Changes diff --git a/query-planner-js/package.json b/query-planner-js/package.json index bf0379bc5..a47f11f22 100644 --- a/query-planner-js/package.json +++ b/query-planner-js/package.json @@ -1,6 +1,6 @@ { "name": "@apollo/query-planner", - "version": "2.10.0", + "version": "2.11.0-preview.2", "description": "Apollo Query Planner", "author": "Apollo ", "main": "dist/index.js", @@ -25,8 +25,8 @@ "access": "public" }, "dependencies": { - "@apollo/federation-internals": "2.10.0", - "@apollo/query-graphs": "2.10.0", + "@apollo/federation-internals": "2.11.0-preview.2", + "@apollo/query-graphs": "2.11.0-preview.2", "@apollo/utils.keyvaluecache": "^2.1.0", "chalk": "^4.1.0", "deep-equal": "^2.0.5", diff --git a/subgraph-js/CHANGELOG.md b/subgraph-js/CHANGELOG.md index f7d64e592..35e3c1512 100644 --- a/subgraph-js/CHANGELOG.md +++ b/subgraph-js/CHANGELOG.md @@ -1,5 +1,32 @@ # CHANGELOG for `@apollo/subgraph` +## 2.11.0-preview.2 + +### Patch Changes + +- Preparing preview.2 release ([#3255](https://github.com/apollographql/federation/pull/3255)) + +- Updated dependencies [[`3e2b0a8569a9fe46726182887ed0b4bfc0b52468`](https://github.com/apollographql/federation/commit/3e2b0a8569a9fe46726182887ed0b4bfc0b52468)]: + - @apollo/federation-internals@2.11.0-preview.2 + +## 2.11.0-preview.1 + +### Patch Changes + +- Updated dependencies [[`1462c91879d41884c0a7e60551d8dd0d67c832d3`](https://github.com/apollographql/federation/commit/1462c91879d41884c0a7e60551d8dd0d67c832d3)]: + - @apollo/federation-internals@2.11.0-preview.1 + +## 2.11.0-preview.0 + +### Minor Changes + +- Add connect spec v0.2 ([#3228](https://github.com/apollographql/federation/pull/3228)) + +### Patch Changes + +- Updated dependencies [[`e7e67579908d5cd2fa6fe558228dffe4808cd98d`](https://github.com/apollographql/federation/commit/e7e67579908d5cd2fa6fe558228dffe4808cd98d)]: + - @apollo/federation-internals@2.11.0-preview.0 + ## 2.10.0 ### Patch Changes diff --git a/subgraph-js/package.json b/subgraph-js/package.json index 5394dfd3a..7ab678111 100644 --- a/subgraph-js/package.json +++ b/subgraph-js/package.json @@ -1,6 +1,6 @@ { "name": "@apollo/subgraph", - "version": "2.10.0", + "version": "2.11.0-preview.2", "description": "Apollo Subgraph Utilities", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -25,7 +25,7 @@ }, "dependencies": { "@apollo/cache-control-types": "^1.0.2", - "@apollo/federation-internals": "2.10.0" + "@apollo/federation-internals": "2.11.0-preview.2" }, "peerDependencies": { "graphql": "^16.5.0"