@apollo/federation-internals 2.0.0-preview.8 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/dist/buildSchema.js +1 -1
- package/dist/buildSchema.js.map +1 -1
- package/dist/coreSpec.d.ts +13 -6
- package/dist/coreSpec.d.ts.map +1 -1
- package/dist/coreSpec.js +105 -38
- package/dist/coreSpec.js.map +1 -1
- package/dist/definitions.d.ts +25 -11
- package/dist/definitions.d.ts.map +1 -1
- package/dist/definitions.js +115 -63
- package/dist/definitions.js.map +1 -1
- package/dist/directiveAndTypeSpecification.d.ts +11 -1
- package/dist/directiveAndTypeSpecification.d.ts.map +1 -1
- package/dist/directiveAndTypeSpecification.js +77 -20
- package/dist/directiveAndTypeSpecification.js.map +1 -1
- package/dist/error.d.ts +13 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +28 -2
- package/dist/error.js.map +1 -1
- package/dist/extractSubgraphsFromSupergraph.d.ts.map +1 -1
- package/dist/extractSubgraphsFromSupergraph.js +7 -1
- package/dist/extractSubgraphsFromSupergraph.js.map +1 -1
- package/dist/federation.d.ts +19 -6
- package/dist/federation.d.ts.map +1 -1
- package/dist/federation.js +107 -80
- package/dist/federation.js.map +1 -1
- package/dist/federationSpec.d.ts +3 -3
- package/dist/federationSpec.d.ts.map +1 -1
- package/dist/federationSpec.js +34 -26
- package/dist/federationSpec.js.map +1 -1
- package/dist/inaccessibleSpec.d.ts +11 -5
- package/dist/inaccessibleSpec.d.ts.map +1 -1
- package/dist/inaccessibleSpec.js +631 -29
- package/dist/inaccessibleSpec.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/introspection.d.ts.map +1 -1
- package/dist/introspection.js +8 -3
- package/dist/introspection.js.map +1 -1
- package/dist/joinSpec.d.ts +6 -2
- package/dist/joinSpec.d.ts.map +1 -1
- package/dist/joinSpec.js +6 -0
- package/dist/joinSpec.js.map +1 -1
- package/dist/operations.d.ts +1 -0
- package/dist/operations.d.ts.map +1 -1
- package/dist/operations.js +16 -1
- package/dist/operations.js.map +1 -1
- package/dist/{sharing.d.ts → precompute.d.ts} +1 -1
- package/dist/precompute.d.ts.map +1 -0
- package/dist/{sharing.js → precompute.js} +3 -3
- package/dist/precompute.js.map +1 -0
- package/dist/schemaUpgrader.d.ts.map +1 -1
- package/dist/schemaUpgrader.js +17 -7
- package/dist/schemaUpgrader.js.map +1 -1
- package/dist/suggestions.d.ts +1 -1
- package/dist/suggestions.d.ts.map +1 -1
- package/dist/suggestions.js.map +1 -1
- package/dist/supergraphs.d.ts.map +1 -1
- package/dist/supergraphs.js +2 -0
- package/dist/supergraphs.js.map +1 -1
- package/dist/tagSpec.d.ts +6 -2
- package/dist/tagSpec.d.ts.map +1 -1
- package/dist/tagSpec.js +30 -14
- package/dist/tagSpec.js.map +1 -1
- package/dist/validate.js +13 -7
- package/dist/validate.js.map +1 -1
- package/dist/values.d.ts +2 -2
- package/dist/values.d.ts.map +1 -1
- package/dist/values.js +13 -11
- package/dist/values.js.map +1 -1
- package/package.json +4 -4
- package/src/__tests__/coreSpec.test.ts +112 -0
- package/src/__tests__/removeInaccessibleElements.test.ts +2229 -137
- package/src/__tests__/subgraphValidation.test.ts +357 -1
- package/src/__tests__/values.test.ts +315 -3
- package/src/buildSchema.ts +1 -1
- package/src/coreSpec.ts +161 -48
- package/src/definitions.ts +223 -90
- package/src/directiveAndTypeSpecification.ts +98 -21
- package/src/error.ts +80 -2
- package/src/extractSubgraphsFromSupergraph.ts +7 -1
- package/src/federation.ts +124 -97
- package/src/federationSpec.ts +37 -30
- package/src/inaccessibleSpec.ts +983 -49
- package/src/index.ts +1 -0
- package/src/introspection.ts +8 -3
- package/src/joinSpec.ts +19 -4
- package/src/operations.ts +15 -0
- package/src/{sharing.ts → precompute.ts} +3 -6
- package/src/schemaUpgrader.ts +29 -13
- package/src/suggestions.ts +1 -1
- package/src/supergraphs.ts +2 -0
- package/src/tagSpec.ts +42 -16
- package/src/validate.ts +20 -9
- package/src/values.ts +39 -12
- package/tsconfig.test.tsbuildinfo +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/sharing.d.ts.map +0 -1
- package/dist/sharing.js.map +0 -1
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import { DirectiveLocation, GraphQLError } from "graphql";
|
|
1
|
+
import { ASTNode, DirectiveLocation, GraphQLError } from "graphql";
|
|
2
2
|
import {
|
|
3
3
|
ArgumentDefinition,
|
|
4
4
|
DirectiveDefinition,
|
|
5
|
+
EnumType,
|
|
5
6
|
InputType,
|
|
7
|
+
isCustomScalarType,
|
|
8
|
+
isEnumType,
|
|
9
|
+
isListType,
|
|
6
10
|
isNonNullType,
|
|
7
11
|
isObjectType,
|
|
8
12
|
isUnionType,
|
|
@@ -49,13 +53,16 @@ export function createDirectiveSpecification({
|
|
|
49
53
|
name: string,
|
|
50
54
|
locations: DirectiveLocation[],
|
|
51
55
|
repeatable?: boolean,
|
|
52
|
-
argumentFct?: (schema: Schema) => ArgumentSpecification[],
|
|
56
|
+
argumentFct?: (schema: Schema, nameInSchema?: string) => { args: ArgumentSpecification[], errors: GraphQLError[] },
|
|
53
57
|
}): DirectiveSpecification {
|
|
54
58
|
return {
|
|
55
59
|
name,
|
|
56
60
|
checkOrAdd: (schema: Schema, nameInSchema?: string, asBuiltIn?: boolean) => {
|
|
57
|
-
const args = argumentFct ? argumentFct(schema) : [];
|
|
58
61
|
const actualName = nameInSchema ?? name;
|
|
62
|
+
const {args, errors} = argumentFct ? argumentFct(schema, actualName) : { args: [], errors: []};
|
|
63
|
+
if (errors.length > 0) {
|
|
64
|
+
return errors;
|
|
65
|
+
}
|
|
59
66
|
const existing = schema.directive(actualName);
|
|
60
67
|
if (existing) {
|
|
61
68
|
return ensureSameDirectiveStructure({name: actualName, locations, repeatable, args}, existing);
|
|
@@ -131,7 +138,7 @@ export function createObjectTypeSpecification({
|
|
|
131
138
|
errors = errors.concat(ensureSameArguments(
|
|
132
139
|
{ name, args },
|
|
133
140
|
existingField,
|
|
134
|
-
`field ${existingField.coordinate}`,
|
|
141
|
+
`field "${existingField.coordinate}"`,
|
|
135
142
|
));
|
|
136
143
|
}
|
|
137
144
|
return errors;
|
|
@@ -198,6 +205,44 @@ export function createUnionTypeSpecification({
|
|
|
198
205
|
}
|
|
199
206
|
}
|
|
200
207
|
|
|
208
|
+
export function createEnumTypeSpecification({
|
|
209
|
+
name,
|
|
210
|
+
values,
|
|
211
|
+
}: {
|
|
212
|
+
name: string,
|
|
213
|
+
values: { name: string, description?: string}[],
|
|
214
|
+
}): TypeSpecification {
|
|
215
|
+
return {
|
|
216
|
+
name,
|
|
217
|
+
checkOrAdd: (schema: Schema, nameInSchema?: string, asBuiltIn?: boolean) => {
|
|
218
|
+
const actualName = nameInSchema ?? name;
|
|
219
|
+
const existing = schema.type(actualName);
|
|
220
|
+
const expectedValueNames = values.map((v) => v.name).sort((n1, n2) => n1.localeCompare(n2));
|
|
221
|
+
if (existing) {
|
|
222
|
+
let errors = ensureSameTypeKind('EnumType', existing);
|
|
223
|
+
if (errors.length > 0) {
|
|
224
|
+
return errors;
|
|
225
|
+
}
|
|
226
|
+
assert(isEnumType(existing), 'Should be an enum type');
|
|
227
|
+
const actualValueNames = existing.values.map(v => v.name).sort((n1, n2) => n1.localeCompare(n2));
|
|
228
|
+
if (!arrayEquals(expectedValueNames, actualValueNames)) {
|
|
229
|
+
errors = errors.concat(ERRORS.TYPE_DEFINITION_INVALID.err({
|
|
230
|
+
message: `Invalid definition of type ${name}: expected values [${expectedValueNames}] but found [${actualValueNames}].`,
|
|
231
|
+
nodes: existing.sourceAST
|
|
232
|
+
}));
|
|
233
|
+
}
|
|
234
|
+
return errors;
|
|
235
|
+
} else {
|
|
236
|
+
const type = schema.addType(new EnumType(actualName, asBuiltIn));
|
|
237
|
+
for (const {name, description} of values) {
|
|
238
|
+
type.addValue(name).description = description;
|
|
239
|
+
}
|
|
240
|
+
return [];
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
201
246
|
function ensureSameTypeKind(expected: NamedType['kind'], actual: NamedType): GraphQLError[] {
|
|
202
247
|
return expected === actual.kind
|
|
203
248
|
? []
|
|
@@ -216,18 +261,19 @@ function ensureSameDirectiveStructure(
|
|
|
216
261
|
},
|
|
217
262
|
actual: DirectiveDefinition<any>,
|
|
218
263
|
): GraphQLError[] {
|
|
219
|
-
|
|
264
|
+
const directiveName = `"@${expected.name}"`
|
|
265
|
+
let errors = ensureSameArguments(expected, actual, `directive ${directiveName}`);
|
|
220
266
|
// It's ok to say you'll never repeat a repeatable directive. It's not ok to repeat one that isn't.
|
|
221
267
|
if (!expected.repeatable && actual.repeatable) {
|
|
222
268
|
errors = errors.concat(ERRORS.DIRECTIVE_DEFINITION_INVALID.err({
|
|
223
|
-
message: `Invalid definition for directive ${
|
|
269
|
+
message: `Invalid definition for directive ${directiveName}: ${directiveName} should${expected.repeatable ? "" : " not"} be repeatable`,
|
|
224
270
|
nodes: actual.sourceAST
|
|
225
271
|
}));
|
|
226
272
|
}
|
|
227
273
|
// Similarly, it's ok to say that you will never use a directive in some locations, but not that you will use it in places not allowed by what is expected.
|
|
228
274
|
if (!actual.locations.every(loc => expected.locations.includes(loc))) {
|
|
229
275
|
errors = errors.concat(ERRORS.DIRECTIVE_DEFINITION_INVALID.err({
|
|
230
|
-
message: `Invalid
|
|
276
|
+
message: `Invalid definition for directive ${directiveName}: ${directiveName} should have locations ${expected.locations.join(', ')}, but found (non-subset) ${actual.locations.join(', ')}`,
|
|
231
277
|
nodes: actual.sourceAST
|
|
232
278
|
}));
|
|
233
279
|
}
|
|
@@ -241,17 +287,24 @@ function ensureSameArguments(
|
|
|
241
287
|
},
|
|
242
288
|
actual: { argument(name: string): ArgumentDefinition<any> | undefined, arguments(): readonly ArgumentDefinition<any>[] },
|
|
243
289
|
what: string,
|
|
290
|
+
containerSourceAST?: ASTNode,
|
|
244
291
|
): GraphQLError[] {
|
|
245
292
|
const expectedArguments = expected.args ?? [];
|
|
246
|
-
const
|
|
247
|
-
if (expectedArguments.length !== foundArguments.length) {
|
|
248
|
-
return [ERRORS.DIRECTIVE_DEFINITION_INVALID.err({
|
|
249
|
-
message: `Invalid definition for ${what}: should have ${expectedArguments.length} arguments but ${foundArguments.length} found`,
|
|
250
|
-
})];
|
|
251
|
-
}
|
|
252
|
-
let errors: GraphQLError[] = [];
|
|
293
|
+
const errors: GraphQLError[] = [];
|
|
253
294
|
for (const { name, type, defaultValue } of expectedArguments) {
|
|
254
|
-
const actualArgument = actual.argument(name)
|
|
295
|
+
const actualArgument = actual.argument(name);
|
|
296
|
+
if (!actualArgument) {
|
|
297
|
+
// Not declaring an optional argument is ok: that means you won't be able to pass a non-default value in your schema, but we allow you that.
|
|
298
|
+
// But missing a required argument it not ok.
|
|
299
|
+
if (isNonNullType(type) && defaultValue === undefined) {
|
|
300
|
+
errors.push(ERRORS.DIRECTIVE_DEFINITION_INVALID.err({
|
|
301
|
+
message: `Invalid definition for ${what}: missing required argument "${name}"`,
|
|
302
|
+
nodes: containerSourceAST
|
|
303
|
+
}));
|
|
304
|
+
}
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
|
|
255
308
|
let actualType = actualArgument.type!;
|
|
256
309
|
if (isNonNullType(actualType) && !isNonNullType(type)) {
|
|
257
310
|
// It's ok to redefine an optional argument as mandatory. For instance, if you want to force people on your team to provide a "deprecation reason", you can
|
|
@@ -259,14 +312,23 @@ function ensureSameArguments(
|
|
|
259
312
|
// is optional if you so wish.
|
|
260
313
|
actualType = actualType.ofType;
|
|
261
314
|
}
|
|
262
|
-
if (!sameType(type, actualType)) {
|
|
263
|
-
errors
|
|
264
|
-
message: `Invalid definition
|
|
315
|
+
if (!sameType(type, actualType) && !isValidInputTypeRedefinition(type, actualType)) {
|
|
316
|
+
errors.push(ERRORS.DIRECTIVE_DEFINITION_INVALID.err({
|
|
317
|
+
message: `Invalid definition for ${what}: argument "${name}" should have type "${type}" but found type "${actualArgument.type!}"`,
|
|
318
|
+
nodes: actualArgument.sourceAST
|
|
319
|
+
}));
|
|
320
|
+
} else if (!isNonNullType(actualArgument.type!) && !valueEquals(defaultValue, actualArgument.defaultValue)) {
|
|
321
|
+
errors.push(ERRORS.DIRECTIVE_DEFINITION_INVALID.err({
|
|
322
|
+
message: `Invalid definition for ${what}: argument "${name}" should have default value ${valueToString(defaultValue)} but found default value ${valueToString(actualArgument.defaultValue)}`,
|
|
265
323
|
nodes: actualArgument.sourceAST
|
|
266
324
|
}));
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
for (const actualArgument of actual.arguments()) {
|
|
328
|
+
// If it's an expect argument, we already validated it. But we still need to reject unkown argument.
|
|
329
|
+
if (!expectedArguments.some((arg) => arg.name === actualArgument.name)) {
|
|
330
|
+
errors.push(ERRORS.DIRECTIVE_DEFINITION_INVALID.err({
|
|
331
|
+
message: `Invalid definition for ${what}: unknown/unsupported argument "${actualArgument.name}"`,
|
|
270
332
|
nodes: actualArgument.sourceAST
|
|
271
333
|
}));
|
|
272
334
|
}
|
|
@@ -274,3 +336,18 @@ function ensureSameArguments(
|
|
|
274
336
|
return errors;
|
|
275
337
|
}
|
|
276
338
|
|
|
339
|
+
function isValidInputTypeRedefinition(expectedType: InputType, actualType: InputType): boolean {
|
|
340
|
+
// If the expected type is a custom scalar, then we allow the redefinition to be another type (unless it's a custom scalar, in which
|
|
341
|
+
// case it has to be the same scalar). The rational being that since graphQL does no validation of values passed to a custom scalar,
|
|
342
|
+
// any code that gets some value as input for a custom scalar has to do validation manually, and so there is little harm in allowing
|
|
343
|
+
// a redefinition with another type since any truly invalid value would failed that "manual validation". In practice, this leeway
|
|
344
|
+
// make sense because many scalar will tend to accept only one kind of values (say, strings) and exists only to inform that said string
|
|
345
|
+
// needs to follow a specific format, and in such case, letting user redefine the type as String adds flexibility while doing little harm.
|
|
346
|
+
if (isListType(expectedType)) {
|
|
347
|
+
return isListType(actualType) && isValidInputTypeRedefinition(expectedType.ofType, actualType.ofType);
|
|
348
|
+
}
|
|
349
|
+
if (isNonNullType(expectedType)) {
|
|
350
|
+
return isNonNullType(actualType) && isValidInputTypeRedefinition(expectedType.ofType, actualType.ofType);
|
|
351
|
+
}
|
|
352
|
+
return isCustomScalarType(expectedType) && !isCustomScalarType(actualType);
|
|
353
|
+
}
|
package/src/error.ts
CHANGED
|
@@ -346,12 +346,62 @@ const LINK_IMPORT_NAME_MISMATCH = makeCodeDefinition(
|
|
|
346
346
|
|
|
347
347
|
const REFERENCED_INACCESSIBLE = makeCodeDefinition(
|
|
348
348
|
'REFERENCED_INACCESSIBLE',
|
|
349
|
-
'An element is marked as @inaccessible but is referenced by
|
|
349
|
+
'An element is marked as @inaccessible but is referenced by an element visible in the API schema.'
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
const DEFAULT_VALUE_USES_INACCESSIBLE = makeCodeDefinition(
|
|
353
|
+
'DEFAULT_VALUE_USES_INACCESSIBLE',
|
|
354
|
+
'An element is marked as @inaccessible but is used in the default value of an element visible in the API schema.'
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
const QUERY_ROOT_TYPE_INACCESSIBLE = makeCodeDefinition(
|
|
358
|
+
'QUERY_ROOT_TYPE_INACCESSIBLE',
|
|
359
|
+
'An element is marked as @inaccessible but is the query root type, which must be visible in the API schema.'
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
const REQUIRED_INACCESSIBLE = makeCodeDefinition(
|
|
363
|
+
'REQUIRED_INACCESSIBLE',
|
|
364
|
+
'An element is marked as @inaccessible but is required by an element visible in the API schema.'
|
|
365
|
+
);
|
|
366
|
+
|
|
367
|
+
const IMPLEMENTED_BY_INACCESSIBLE = makeCodeDefinition(
|
|
368
|
+
'IMPLEMENTED_BY_INACCESSIBLE',
|
|
369
|
+
'An element is marked as @inaccessible but implements an element visible in the API schema.'
|
|
370
|
+
);
|
|
371
|
+
|
|
372
|
+
const DISALLOWED_INACCESSIBLE = makeCodeDefinition(
|
|
373
|
+
'DISALLOWED_INACCESSIBLE',
|
|
374
|
+
'An element is marked as @inaccessible that is not allowed to be @inaccessible.'
|
|
375
|
+
);
|
|
376
|
+
|
|
377
|
+
const ONLY_INACCESSIBLE_CHILDREN = makeCodeDefinition(
|
|
378
|
+
'ONLY_INACCESSIBLE_CHILDREN',
|
|
379
|
+
'A type visible in the API schema has only @inaccessible children.'
|
|
380
|
+
);
|
|
381
|
+
|
|
382
|
+
const REQUIRED_INPUT_FIELD_MISSING_IN_SOME_SUBGRAPH = makeCodeDefinition(
|
|
383
|
+
'REQUIRED_INPUT_FIELD_MISSING_IN_SOME_SUBGRAPH',
|
|
384
|
+
'A field of an input object type is mandatory in some subgraphs, but the field is not defined in all the subgraphs that define the input object type.'
|
|
350
385
|
);
|
|
351
386
|
|
|
352
387
|
const REQUIRED_ARGUMENT_MISSING_IN_SOME_SUBGRAPH = makeCodeDefinition(
|
|
353
388
|
'REQUIRED_ARGUMENT_MISSING_IN_SOME_SUBGRAPH',
|
|
354
|
-
'An argument of a field or directive definition is mandatory in some subgraphs, but the argument is not defined in all subgraphs that define the field or directive definition.'
|
|
389
|
+
'An argument of a field or directive definition is mandatory in some subgraphs, but the argument is not defined in all the subgraphs that define the field or directive definition.'
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
const EMPTY_MERGED_INPUT_TYPE = makeCodeDefinition(
|
|
393
|
+
'EMPTY_MERGED_INPUT_TYPE',
|
|
394
|
+
'An input object type has no field common to all the subgraphs that define the type. Merging that type would result in an invalid empty input object type.'
|
|
395
|
+
);
|
|
396
|
+
|
|
397
|
+
const ENUM_VALUE_MISMATCH = makeCodeDefinition(
|
|
398
|
+
'ENUM_VALUE_MISMATCH',
|
|
399
|
+
'An enum type that is used as both an input and output type has a value that is not defined in all the subgraphs that define the enum type.'
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
const EMPTY_MERGED_ENUM_TYPE = makeCodeDefinition(
|
|
403
|
+
'EMPTY_MERGED_ENUM_TYPE',
|
|
404
|
+
'An enum type has no value common to all the subgraphs that define the type. Merging that type would result in an invalid empty enum type.'
|
|
355
405
|
);
|
|
356
406
|
|
|
357
407
|
const SATISFIABILITY_ERROR = makeCodeDefinition(
|
|
@@ -359,6 +409,21 @@ const SATISFIABILITY_ERROR = makeCodeDefinition(
|
|
|
359
409
|
'Subgraphs can be merged, but the resulting supergraph API would have queries that cannot be satisfied by those subgraphs.',
|
|
360
410
|
);
|
|
361
411
|
|
|
412
|
+
const OVERRIDE_FROM_SELF_ERROR = makeCodeDefinition(
|
|
413
|
+
'OVERRIDE_FROM_SELF_ERROR',
|
|
414
|
+
'Field with `@override` directive has "from" location that references its own subgraph.',
|
|
415
|
+
);
|
|
416
|
+
|
|
417
|
+
const OVERRIDE_SOURCE_HAS_OVERRIDE = makeCodeDefinition(
|
|
418
|
+
'OVERRIDE_SOURCE_HAS_OVERRIDE',
|
|
419
|
+
'Field which is overridden to another subgraph is also marked @override.',
|
|
420
|
+
);
|
|
421
|
+
|
|
422
|
+
const OVERRIDE_COLLISION_WITH_ANOTHER_DIRECTIVE = makeCodeDefinition(
|
|
423
|
+
'OVERRIDE_COLLISION_WITH_ANOTHER_DIRECTIVE',
|
|
424
|
+
'The @override directive cannot be used on external fields, nor to override fields with either @external, @provides, or @requires.',
|
|
425
|
+
);
|
|
426
|
+
|
|
362
427
|
export const ERROR_CATEGORIES = {
|
|
363
428
|
DIRECTIVE_FIELDS_MISSING_EXTERNAL,
|
|
364
429
|
DIRECTIVE_UNSUPPORTED_ON_INTERFACE,
|
|
@@ -416,8 +481,21 @@ export const ERRORS = {
|
|
|
416
481
|
INVALID_LINK_DIRECTIVE_USAGE,
|
|
417
482
|
LINK_IMPORT_NAME_MISMATCH,
|
|
418
483
|
REFERENCED_INACCESSIBLE,
|
|
484
|
+
DEFAULT_VALUE_USES_INACCESSIBLE,
|
|
485
|
+
QUERY_ROOT_TYPE_INACCESSIBLE,
|
|
486
|
+
REQUIRED_INACCESSIBLE,
|
|
487
|
+
DISALLOWED_INACCESSIBLE,
|
|
488
|
+
IMPLEMENTED_BY_INACCESSIBLE,
|
|
489
|
+
ONLY_INACCESSIBLE_CHILDREN,
|
|
419
490
|
REQUIRED_ARGUMENT_MISSING_IN_SOME_SUBGRAPH,
|
|
491
|
+
REQUIRED_INPUT_FIELD_MISSING_IN_SOME_SUBGRAPH,
|
|
492
|
+
EMPTY_MERGED_INPUT_TYPE,
|
|
493
|
+
ENUM_VALUE_MISMATCH,
|
|
494
|
+
EMPTY_MERGED_ENUM_TYPE,
|
|
420
495
|
SATISFIABILITY_ERROR,
|
|
496
|
+
OVERRIDE_COLLISION_WITH_ANOTHER_DIRECTIVE,
|
|
497
|
+
OVERRIDE_FROM_SELF_ERROR,
|
|
498
|
+
OVERRIDE_SOURCE_HAS_OVERRIDE,
|
|
421
499
|
};
|
|
422
500
|
|
|
423
501
|
const codeDefByCode = Object.values(ERRORS).reduce((obj: {[code: string]: ErrorCodeDefinition}, codeDef: ErrorCodeDefinition) => { obj[codeDef.code] = codeDef; return obj; }, {});
|
|
@@ -181,6 +181,12 @@ export function extractSubgraphsFromSupergraph(supergraph: Schema): Subgraphs {
|
|
|
181
181
|
if (args.external) {
|
|
182
182
|
subgraphField.applyDirective(subgraph.metadata().externalDirective());
|
|
183
183
|
}
|
|
184
|
+
if (args.usedOverridden) {
|
|
185
|
+
subgraphField.applyDirective(subgraph.metadata().externalDirective(), {'reason': '[overridden]'});
|
|
186
|
+
}
|
|
187
|
+
if (args.override) {
|
|
188
|
+
subgraphField.applyDirective(subgraph.metadata().overrideDirective(), {'from': args.override});
|
|
189
|
+
}
|
|
184
190
|
}
|
|
185
191
|
}
|
|
186
192
|
}
|
|
@@ -262,7 +268,7 @@ export function extractSubgraphsFromSupergraph(supergraph: Schema): Subgraphs {
|
|
|
262
268
|
// truly defined, so we've so far added them everywhere with all their fields, but some fields may have been part
|
|
263
269
|
// of an extension and be only in a few subgraphs), we remove the field or the subgraph would be invalid.
|
|
264
270
|
for (const subgraph of subgraphs) {
|
|
265
|
-
for (const itf of subgraph.schema.
|
|
271
|
+
for (const itf of subgraph.schema.interfaceTypes()) {
|
|
266
272
|
// We only look at objects because interfaces are handled by this own loop in practice.
|
|
267
273
|
const implementations = itf.possibleRuntimeTypes();
|
|
268
274
|
for (const field of itf.fields()) {
|