mirror of
https://github.com/graphql-hive/console
synced 2026-04-21 14:37:17 +00:00
Fix an issue in Federation when a type definition is not found for a type extension (#1407)
This commit is contained in:
parent
99617e44b2
commit
965cabc1b6
6 changed files with 166 additions and 21 deletions
|
|
@ -115,7 +115,9 @@
|
|||
"oclif@3.6.5": "patches/oclif@3.6.5.patch",
|
||||
"bullmq@3.7.0": "patches/bullmq@3.7.0.patch",
|
||||
"@slonik/migrator@0.8.5": "patches/@slonik__migrator@0.8.5.patch",
|
||||
"@graphql-inspector/core@3.5.0": "patches/@graphql-inspector__core@3.5.0.patch"
|
||||
"@graphql-inspector/core@3.5.0": "patches/@graphql-inspector__core@3.5.0.patch",
|
||||
"@apollo/federation@0.38.1": "patches/@apollo__federation@0.38.1.patch",
|
||||
"@octokit/webhooks-methods@3.0.1": "patches/@octokit__webhooks-methods@3.0.1.patch"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
54
packages/services/schema/__tests__/federation.spec.ts
Normal file
54
packages/services/schema/__tests__/federation.spec.ts
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import { parse } from 'graphql';
|
||||
import { composeAndValidate } from '@apollo/federation';
|
||||
|
||||
test('patch', () => {
|
||||
const result = composeAndValidate([
|
||||
{
|
||||
typeDefs: parse(/* GraphQL */ `
|
||||
extend type Review @key(fields: "id") {
|
||||
id: String! @external
|
||||
title: String! @external
|
||||
}
|
||||
|
||||
type Product @key(fields: "id") {
|
||||
id: ID!
|
||||
name: String!
|
||||
properties: Properties
|
||||
reviews: [Review] @provides(fields: "id")
|
||||
}
|
||||
|
||||
type Properties {
|
||||
available: Boolean
|
||||
}
|
||||
|
||||
type Query {
|
||||
randomProduct: Product
|
||||
}
|
||||
`),
|
||||
name: 'foo',
|
||||
},
|
||||
{
|
||||
typeDefs: parse(/* GraphQL */ `
|
||||
type Query {
|
||||
bar: Bar
|
||||
}
|
||||
|
||||
type Bar {
|
||||
id: ID!
|
||||
name: String!
|
||||
}
|
||||
`),
|
||||
name: 'bar',
|
||||
},
|
||||
]);
|
||||
|
||||
expect(result.errors!.map(e => e.message)).not.toContainEqual(
|
||||
expect.stringMatching('Unknown type "Bar"'),
|
||||
);
|
||||
expect(result.errors!.map(e => e.message)).not.toContainEqual(
|
||||
expect.stringMatching('Unknown type "Product"'),
|
||||
);
|
||||
expect(result.errors!.map(e => e.message)).toContainEqual(
|
||||
expect.stringMatching('Unknown type "Review"'),
|
||||
);
|
||||
});
|
||||
72
patches/@apollo__federation@0.38.1.patch
Normal file
72
patches/@apollo__federation@0.38.1.patch
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
diff --git a/dist/composition/compose.js b/dist/composition/compose.js
|
||||
index dbf319952c630aa8c0f534e06bd0258e06bcaf8a..101e1afc8803a6899b11e31b2b20faba28c20345 100644
|
||||
--- a/dist/composition/compose.js
|
||||
+++ b/dist/composition/compose.js
|
||||
@@ -148,7 +148,17 @@ function buildMapsFromServiceList(serviceList) {
|
||||
};
|
||||
}
|
||||
exports.buildMapsFromServiceList = buildMapsFromServiceList;
|
||||
+function resolveNamedType(node) {
|
||||
+ if (node.kind === graphql_1.Kind.LIST_TYPE) {
|
||||
+ return resolveNamedType(node.type);
|
||||
+ }
|
||||
+ if (node.kind === graphql_1.Kind.NON_NULL_TYPE) {
|
||||
+ return resolveNamedType(node.type);
|
||||
+ }
|
||||
+ return node.name.value;
|
||||
+}
|
||||
function buildSchemaFromDefinitionsAndExtensions({ typeDefinitionsMap, typeExtensionsMap, directiveDefinitionsMap, directiveMetadata, serviceList, }) {
|
||||
+ var _a, _b;
|
||||
let errors = undefined;
|
||||
const autoIncludedDirectiveDefinitions = directives_1.directivesWithAutoIncludedDefinitions.filter((directive) => directiveMetadata.hasUsages(directive.name));
|
||||
const { FieldSetScalar, JoinFieldDirective, JoinTypeDirective, JoinOwnerDirective, JoinGraphEnum, JoinGraphDirective, } = (0, joinSpec_1.getJoinDefinitions)(serviceList);
|
||||
@@ -169,6 +179,34 @@ function buildSchemaFromDefinitionsAndExtensions({ typeDefinitionsMap, typeExten
|
||||
function nodeHasInterfaces(node) {
|
||||
return 'interfaces' in node;
|
||||
}
|
||||
+ for (const typeName in typeDefinitionsMap) {
|
||||
+ const typeDefinitions = typeDefinitionsMap[typeName];
|
||||
+ for (const typeDefinition of typeDefinitions) {
|
||||
+ if (typeDefinition.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION) {
|
||||
+ const fieldNamesToDelete = [];
|
||||
+ for (const field of (_a = typeDefinition.fields) !== null && _a !== void 0 ? _a : []) {
|
||||
+ const fieldTypeName = resolveNamedType(field.type);
|
||||
+ if (!typeDefinitionsMap[fieldTypeName] && false === ['ID', 'String', 'Boolean', 'Float', 'Int'].includes(fieldTypeName)) {
|
||||
+ if (!typeExtensionsMap[typeName]) {
|
||||
+ typeExtensionsMap[typeName] = [];
|
||||
+ }
|
||||
+ typeExtensionsMap[typeName].push({
|
||||
+ kind: graphql_1.Kind.OBJECT_TYPE_EXTENSION,
|
||||
+ name: {
|
||||
+ kind: graphql_1.Kind.NAME,
|
||||
+ value: typeName,
|
||||
+ },
|
||||
+ fields: [field]
|
||||
+ });
|
||||
+ fieldNamesToDelete.push(field.name.value);
|
||||
+ }
|
||||
+ }
|
||||
+ if (fieldNamesToDelete.length > 0) {
|
||||
+ typeDefinition.fields = (_b = typeDefinition.fields) === null || _b === void 0 ? void 0 : _b.filter(field => !fieldNamesToDelete.includes(field.name.value));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
const definitionsDocument = {
|
||||
kind: graphql_1.Kind.DOCUMENT,
|
||||
definitions: [
|
||||
@@ -200,12 +238,13 @@ function buildSchemaFromDefinitionsAndExtensions({ typeDefinitionsMap, typeExten
|
||||
assumeValidSDL: true,
|
||||
});
|
||||
}
|
||||
- catch (e) { }
|
||||
+ catch { }
|
||||
const extensionsDocument = {
|
||||
kind: graphql_1.Kind.DOCUMENT,
|
||||
definitions: Object.values(typeExtensionsMap).flat(),
|
||||
};
|
||||
errors.push(...(0, validate_1.validateSDL)(extensionsDocument, schema, rules_1.compositionRules));
|
||||
+ errors = errors.filter((error, index, all) => all.findIndex(e => e.message === error.message) === index);
|
||||
try {
|
||||
schema = (0, graphql_1.extendSchema)(schema, extensionsDocument, {
|
||||
assumeValidSDL: true,
|
||||
12
patches/@octokit__webhooks-methods@3.0.1.patch
Normal file
12
patches/@octokit__webhooks-methods@3.0.1.patch
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
diff --git a/package.json b/package.json
|
||||
index 7c6e9a1af624be81938679edba36a046fd78f5f9..3dd36bc7573673a082dd8cc4910e0e3aca51c4a9 100644
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -42,6 +42,5 @@
|
||||
},
|
||||
"source": "dist-src/index.js",
|
||||
"types": "dist-types/index.d.ts",
|
||||
- "main": "dist-node/index.js",
|
||||
- "module": "dist-web/index.js"
|
||||
+ "main": "dist-node/index.js"
|
||||
}
|
||||
|
|
@ -5,33 +5,39 @@ overrides:
|
|||
tsup: 6.5.0
|
||||
|
||||
patchedDependencies:
|
||||
'@tgriesser/schemats@7.0.1':
|
||||
hash: u3kbucfchakklx3sci2vh6wjau
|
||||
path: patches/@tgriesser__schemats@7.0.1.patch
|
||||
mjml-core@4.13.0:
|
||||
hash: zxxsxbqejjmcwuzpigutzzq6wa
|
||||
path: patches/mjml-core@4.13.0.patch
|
||||
slonik@30.1.2:
|
||||
hash: wg2hxbo7txnklmvja4aeqnygfi
|
||||
path: patches/slonik@30.1.2.patch
|
||||
'@theguild/buddy@0.1.0':
|
||||
hash: ryylgra5xglhidfoiaxehn22hq
|
||||
path: patches/@theguild__buddy@0.1.0.patch
|
||||
oclif@3.6.5:
|
||||
hash: rxmtqiusuyruv7tkwux5gvotbm
|
||||
path: patches/oclif@3.6.5.patch
|
||||
'@oclif/core@1.23.0':
|
||||
hash: zhte2hlj7lfobytjpalcwwo474
|
||||
path: patches/@oclif__core@1.23.0.patch
|
||||
bullmq@3.7.0:
|
||||
hash: xbmkiyyfti7h6orsfs6pdmi4s4
|
||||
path: patches/bullmq@3.7.0.patch
|
||||
oclif@3.6.5:
|
||||
hash: rxmtqiusuyruv7tkwux5gvotbm
|
||||
path: patches/oclif@3.6.5.patch
|
||||
'@graphql-inspector/core@3.5.0':
|
||||
hash: wf35oaq7brzyeva5aoncxac66a
|
||||
path: patches/@graphql-inspector__core@3.5.0.patch
|
||||
'@tgriesser/schemats@7.0.1':
|
||||
hash: u3kbucfchakklx3sci2vh6wjau
|
||||
path: patches/@tgriesser__schemats@7.0.1.patch
|
||||
'@slonik/migrator@0.8.5':
|
||||
hash: yfpv2xzdmnkrtu2wvaktxf5mmq
|
||||
path: patches/@slonik__migrator@0.8.5.patch
|
||||
mjml-core@4.13.0:
|
||||
hash: zxxsxbqejjmcwuzpigutzzq6wa
|
||||
path: patches/mjml-core@4.13.0.patch
|
||||
'@apollo/federation@0.38.1':
|
||||
hash: rjgakkkphrejw6qrtph4ar24zq
|
||||
path: patches/@apollo__federation@0.38.1.patch
|
||||
'@octokit/webhooks-methods@3.0.1':
|
||||
hash: ckboo4crezw7uvstxm24ozngtq
|
||||
path: patches/@octokit__webhooks-methods@3.0.1.patch
|
||||
|
||||
importers:
|
||||
|
||||
|
|
@ -284,7 +290,7 @@ importers:
|
|||
'@apollo/server': 4.4.0
|
||||
'@envelop/types': 3.0.1
|
||||
devDependencies:
|
||||
'@apollo/federation': 0.38.1
|
||||
'@apollo/federation': 0.38.1_rjgakkkphrejw6qrtph4ar24zq
|
||||
'@apollo/subgraph': 2.3.2
|
||||
'@types/async-retry': 1.4.5
|
||||
graphql-yoga: 3.6.0
|
||||
|
|
@ -310,7 +316,7 @@ importers:
|
|||
fastify: 3.29.5
|
||||
graphql: 16.6.0
|
||||
devDependencies:
|
||||
'@apollo/federation': 0.38.1_graphql@16.6.0
|
||||
'@apollo/federation': 0.38.1_rjgakkkphrejw6qrtph4ar24zq_graphql@16.6.0
|
||||
esbuild: 0.17.9
|
||||
fastify: 3.29.5
|
||||
graphql: 16.6.0
|
||||
|
|
@ -624,7 +630,7 @@ importers:
|
|||
pino-pretty: 9.3.0
|
||||
zod: 3.20.6
|
||||
dependencies:
|
||||
'@apollo/federation': 0.38.1_graphql@16.6.0
|
||||
'@apollo/federation': 0.38.1_rjgakkkphrejw6qrtph4ar24zq_graphql@16.6.0
|
||||
'@graphql-tools/stitch': 8.7.41_graphql@16.6.0
|
||||
'@graphql-tools/stitching-directives': 2.3.30_graphql@16.6.0
|
||||
'@sentry/node': 7.38.0
|
||||
|
|
@ -1466,7 +1472,7 @@ packages:
|
|||
js-levenshtein: 1.1.6
|
||||
dev: false
|
||||
|
||||
/@apollo/federation/0.38.1:
|
||||
/@apollo/federation/0.38.1_rjgakkkphrejw6qrtph4ar24zq:
|
||||
resolution: {integrity: sha512-miifyAEsFgiYKeM3lUHFH6+vKa2vm9dXKSyWVpX6oeJiPblFLe2/iByN3psZQO2sRdVqO1OKYrGXdgKc74XDKw==}
|
||||
engines: {node: '>=12.13.0'}
|
||||
peerDependencies:
|
||||
|
|
@ -1478,8 +1484,9 @@ packages:
|
|||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: true
|
||||
patched: true
|
||||
|
||||
/@apollo/federation/0.38.1_graphql@16.6.0:
|
||||
/@apollo/federation/0.38.1_rjgakkkphrejw6qrtph4ar24zq_graphql@16.6.0:
|
||||
resolution: {integrity: sha512-miifyAEsFgiYKeM3lUHFH6+vKa2vm9dXKSyWVpX6oeJiPblFLe2/iByN3psZQO2sRdVqO1OKYrGXdgKc74XDKw==}
|
||||
engines: {node: '>=12.13.0'}
|
||||
peerDependencies:
|
||||
|
|
@ -1491,6 +1498,7 @@ packages:
|
|||
lodash.xorby: 4.7.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
patched: true
|
||||
|
||||
/@apollo/gateway/2.3.2_graphql@16.6.0:
|
||||
resolution: {integrity: sha512-D7p1I6wfHA9XY0HJXyBDouaGCcd/+oUU7bhSyVg1MmREL52sZnSk/140nds5L93jHca3Gl3IB4kiQ5JUJXfA6w==}
|
||||
|
|
@ -8902,10 +8910,11 @@ packages:
|
|||
'@octokit/openapi-types': 16.0.0
|
||||
dev: false
|
||||
|
||||
/@octokit/webhooks-methods/3.0.1:
|
||||
/@octokit/webhooks-methods/3.0.1_ckboo4crezw7uvstxm24ozngtq:
|
||||
resolution: {integrity: sha512-XftYVcBxtzC2G05kdBNn9IYLtQ+Cz6ufKkjZd0DU/qGaZEFTPzM2OabXAWG5tvL0q/I+Exio1JnRiPfetiMSEw==}
|
||||
engines: {node: '>= 14'}
|
||||
dev: false
|
||||
patched: true
|
||||
|
||||
/@octokit/webhooks-types/6.7.0:
|
||||
resolution: {integrity: sha512-bykm7UkSnxmb2uhSfcLM1Pity/LQ6ZBSdzy9HU0vXjR+2g+tzlmRhXb7Go8oj0TlgO+vDrTivGXju6zkzOGKjA==}
|
||||
|
|
@ -8916,7 +8925,7 @@ packages:
|
|||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@octokit/request-error': 3.0.2
|
||||
'@octokit/webhooks-methods': 3.0.1
|
||||
'@octokit/webhooks-methods': 3.0.1_ckboo4crezw7uvstxm24ozngtq
|
||||
'@octokit/webhooks-types': 6.7.0
|
||||
aggregate-error: 3.1.0
|
||||
dev: false
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
/*
|
||||
https://github.com/octokit/webhooks-methods.js/issues/45
|
||||
|
||||
That's why we patch package.json of @octokit/webhooks-methods and replace the value of `main` with the value from `source`.
|
||||
*/
|
||||
import fs from 'fs';
|
||||
|
|
@ -41,7 +40,6 @@ function findPackageJson(dirname, until) {
|
|||
|
||||
/*
|
||||
https://github.com/octokit/webhooks-methods.js/issues/45
|
||||
|
||||
That's why we patch package.json of @octokit/webhooks-methods and replace the value of `main` with the value from `source`.
|
||||
*/
|
||||
patchPackage('@octokit/webhooks-methods', pkg => {
|
||||
|
|
@ -50,7 +48,6 @@ patchPackage('@octokit/webhooks-methods', pkg => {
|
|||
|
||||
/*
|
||||
https://github.com/octokit/webhooks-methods.js/issues/45
|
||||
|
||||
That's why we patch package.json of universal-github-app-jwt and replace the value of `main` with the value from `source`.
|
||||
*/
|
||||
patchPackage('universal-github-app-jwt', pkg => {
|
||||
|
|
@ -60,7 +57,6 @@ patchPackage('universal-github-app-jwt', pkg => {
|
|||
/*
|
||||
TSUP (but really esbuild) bundles all node_modules, this is expected, we want that.
|
||||
Unfortunately, `apollo-graphql` and `@apollo/*` libraries are CJS only and we end up with CJS and ESM versions of graphql.
|
||||
|
||||
The very quick fix means we need to patch the graphql module to be CJS-only.
|
||||
*/
|
||||
patchPackage('graphql', pkg => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue