@apollo/federation-internals 2.1.0-alpha.0 → 2.1.0-alpha.3
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 +9 -0
- package/dist/buildSchema.d.ts.map +1 -1
- package/dist/buildSchema.js +24 -13
- package/dist/buildSchema.js.map +1 -1
- package/dist/coreSpec.d.ts.map +1 -1
- package/dist/coreSpec.js +15 -42
- package/dist/coreSpec.js.map +1 -1
- package/dist/definitions.d.ts +47 -8
- package/dist/definitions.d.ts.map +1 -1
- package/dist/definitions.js +186 -121
- package/dist/definitions.js.map +1 -1
- package/dist/directiveAndTypeSpecification.js +14 -48
- package/dist/directiveAndTypeSpecification.js.map +1 -1
- package/dist/error.d.ts +20 -17
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +42 -7
- package/dist/error.js.map +1 -1
- package/dist/extractSubgraphsFromSupergraph.d.ts.map +1 -1
- package/dist/extractSubgraphsFromSupergraph.js +9 -0
- package/dist/extractSubgraphsFromSupergraph.js.map +1 -1
- package/dist/federation.d.ts +5 -1
- package/dist/federation.d.ts.map +1 -1
- package/dist/federation.js +83 -128
- package/dist/federation.js.map +1 -1
- package/dist/federationSpec.d.ts +13 -9
- package/dist/federationSpec.d.ts.map +1 -1
- package/dist/federationSpec.js +27 -5
- package/dist/federationSpec.js.map +1 -1
- package/dist/inaccessibleSpec.js +44 -67
- package/dist/inaccessibleSpec.js.map +1 -1
- package/dist/operations.d.ts +48 -21
- package/dist/operations.d.ts.map +1 -1
- package/dist/operations.js +334 -52
- package/dist/operations.js.map +1 -1
- package/dist/print.d.ts +1 -1
- package/dist/print.d.ts.map +1 -1
- package/dist/print.js +1 -1
- package/dist/print.js.map +1 -1
- package/dist/schemaUpgrader.js +2 -8
- package/dist/schemaUpgrader.js.map +1 -1
- package/dist/supergraphs.d.ts.map +1 -1
- package/dist/supergraphs.js +4 -4
- package/dist/supergraphs.js.map +1 -1
- package/dist/tagSpec.d.ts.map +1 -1
- package/dist/tagSpec.js +1 -3
- package/dist/tagSpec.js.map +1 -1
- package/dist/utils.d.ts +9 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +31 -1
- package/dist/utils.js.map +1 -1
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +26 -22
- package/dist/validate.js.map +1 -1
- package/dist/validation/KnownTypeNamesInFederationRule.js +1 -1
- package/dist/validation/KnownTypeNamesInFederationRule.js.map +1 -1
- package/dist/values.d.ts.map +1 -1
- package/dist/values.js +19 -18
- package/dist/values.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/definitions.test.ts +18 -0
- package/src/__tests__/operations.test.ts +217 -99
- package/src/__tests__/subgraphValidation.test.ts +77 -0
- package/src/buildSchema.ts +30 -23
- package/src/coreSpec.ts +47 -43
- package/src/definitions.ts +281 -125
- package/src/directiveAndTypeSpecification.ts +50 -48
- package/src/error.ts +94 -41
- package/src/extractSubgraphsFromSupergraph.ts +20 -0
- package/src/federation.ts +158 -136
- package/src/federationSpec.ts +32 -5
- package/src/inaccessibleSpec.ts +209 -196
- package/src/operations.ts +525 -76
- package/src/print.ts +1 -1
- package/src/schemaUpgrader.ts +8 -8
- package/src/supergraphs.ts +5 -4
- package/src/tagSpec.ts +2 -3
- package/src/utils.ts +40 -0
- package/src/validate.ts +60 -52
- package/src/validation/KnownTypeNamesInFederationRule.ts +1 -1
- package/src/values.ts +19 -18
- package/tsconfig.test.tsbuildinfo +1 -1
- package/tsconfig.tsbuildinfo +1 -1
package/src/coreSpec.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ASTNode, DirectiveLocation, GraphQLError, StringValueNode } from "graphql";
|
|
2
2
|
import { URL } from "url";
|
|
3
|
-
import { CoreFeature, Directive, DirectiveDefinition, EnumType, ErrGraphQLAPISchemaValidationFailed, ErrGraphQLValidationFailed, InputType, ListType, NamedType, NonNullType, ScalarType, Schema, SchemaDefinition, SchemaElement } from "./definitions";
|
|
3
|
+
import { CoreFeature, Directive, DirectiveDefinition, EnumType, ErrGraphQLAPISchemaValidationFailed, ErrGraphQLValidationFailed, InputType, ListType, NamedType, NonNullType, ScalarType, Schema, SchemaDefinition, SchemaElement, sourceASTs } from "./definitions";
|
|
4
4
|
import { sameType } from "./types";
|
|
5
5
|
import { err } from '@apollo/core-schema';
|
|
6
6
|
import { assert, firstOf } from './utils';
|
|
@@ -185,10 +185,10 @@ export function extractCoreFeatureImports(url: FeatureUrl, directive: Directive<
|
|
|
185
185
|
continue;
|
|
186
186
|
}
|
|
187
187
|
if (typeof elt !== 'object') {
|
|
188
|
-
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(
|
|
189
|
-
|
|
190
|
-
nodes: directive.sourceAST
|
|
191
|
-
|
|
188
|
+
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(
|
|
189
|
+
`Invalid sub-value ${valueToString(elt)} for @link(import:) argument: values should be either strings or input object values of the form { name: "<importedElement>", as: "<alias>" }.`,
|
|
190
|
+
{ nodes: directive.sourceAST },
|
|
191
|
+
));
|
|
192
192
|
continue;
|
|
193
193
|
}
|
|
194
194
|
let name: string | undefined;
|
|
@@ -196,28 +196,28 @@ export function extractCoreFeatureImports(url: FeatureUrl, directive: Directive<
|
|
|
196
196
|
switch (key) {
|
|
197
197
|
case 'name':
|
|
198
198
|
if (typeof value !== 'string') {
|
|
199
|
-
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(
|
|
200
|
-
|
|
201
|
-
nodes: directive.sourceAST
|
|
202
|
-
|
|
199
|
+
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(
|
|
200
|
+
`Invalid value for the "name" field for sub-value ${valueToString(elt)} of @link(import:) argument: must be a string.`,
|
|
201
|
+
{ nodes: directive.sourceAST },
|
|
202
|
+
));
|
|
203
203
|
continue importArgLoop;
|
|
204
204
|
}
|
|
205
205
|
name = value;
|
|
206
206
|
break;
|
|
207
207
|
case 'as':
|
|
208
208
|
if (typeof value !== 'string') {
|
|
209
|
-
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(
|
|
210
|
-
|
|
211
|
-
nodes: directive.sourceAST
|
|
212
|
-
|
|
209
|
+
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(
|
|
210
|
+
`Invalid value for the "as" field for sub-value ${valueToString(elt)} of @link(import:) argument: must be a string.`,
|
|
211
|
+
{ nodes: directive.sourceAST },
|
|
212
|
+
));
|
|
213
213
|
continue importArgLoop;
|
|
214
214
|
}
|
|
215
215
|
break;
|
|
216
216
|
default:
|
|
217
|
-
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(
|
|
218
|
-
|
|
219
|
-
nodes: directive.sourceAST
|
|
220
|
-
|
|
217
|
+
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(
|
|
218
|
+
`Unknown field "${key}" for sub-value ${valueToString(elt)} of @link(import:) argument.`,
|
|
219
|
+
{ nodes: directive.sourceAST },
|
|
220
|
+
));
|
|
221
221
|
continue importArgLoop;
|
|
222
222
|
}
|
|
223
223
|
}
|
|
@@ -226,24 +226,24 @@ export function extractCoreFeatureImports(url: FeatureUrl, directive: Directive<
|
|
|
226
226
|
imports.push(i);
|
|
227
227
|
if (i.as) {
|
|
228
228
|
if (i.name.charAt(0) === '@' && i.as.charAt(0) !== '@') {
|
|
229
|
-
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(
|
|
230
|
-
|
|
231
|
-
nodes: directive.sourceAST
|
|
232
|
-
|
|
229
|
+
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(
|
|
230
|
+
`Invalid @link import renaming: directive "${i.name}" imported name should start with a '@' character, but got "${i.as}".`,
|
|
231
|
+
{ nodes: directive.sourceAST },
|
|
232
|
+
));
|
|
233
233
|
}
|
|
234
234
|
else if (i.name.charAt(0) !== '@' && i.as.charAt(0) === '@') {
|
|
235
|
-
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(
|
|
236
|
-
|
|
237
|
-
nodes: directive.sourceAST
|
|
238
|
-
|
|
235
|
+
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(
|
|
236
|
+
`Invalid @link import renaming: type "${i.name}" imported name should not start with a '@' character, but got "${i.as}" (or, if @${i.name} is a directive, then it should be referred to with a '@').`,
|
|
237
|
+
{ nodes: directive.sourceAST },
|
|
238
|
+
));
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
241
|
validateImportedName(name, knownElements, errors, directive);
|
|
242
242
|
} else {
|
|
243
|
-
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(
|
|
244
|
-
|
|
245
|
-
nodes: directive.sourceAST
|
|
246
|
-
|
|
243
|
+
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(
|
|
244
|
+
`Invalid sub-value ${valueToString(elt)} for @link(import:) argument: missing mandatory "name" field.`,
|
|
245
|
+
{ nodes: directive.sourceAST },
|
|
246
|
+
));
|
|
247
247
|
}
|
|
248
248
|
}
|
|
249
249
|
|
|
@@ -264,10 +264,10 @@ function validateImportedName(name: string, knownElements: string[] | undefined,
|
|
|
264
264
|
details = didYouMean(suggestions);
|
|
265
265
|
}
|
|
266
266
|
}
|
|
267
|
-
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(
|
|
268
|
-
|
|
269
|
-
nodes: directive.sourceAST
|
|
270
|
-
|
|
267
|
+
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(
|
|
268
|
+
`Cannot import unknown element "${name}".${details}`,
|
|
269
|
+
{ nodes: directive.sourceAST },
|
|
270
|
+
));
|
|
271
271
|
}
|
|
272
272
|
}
|
|
273
273
|
|
|
@@ -419,9 +419,9 @@ export class CoreSpecDefinition extends FeatureDefinition {
|
|
|
419
419
|
// Already exists with the same version, let it be.
|
|
420
420
|
return [];
|
|
421
421
|
} else {
|
|
422
|
-
return [ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(
|
|
423
|
-
|
|
424
|
-
|
|
422
|
+
return [ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(
|
|
423
|
+
`Cannot add feature ${this} to the schema, it already uses ${existingCore.coreItself.url}`
|
|
424
|
+
)];
|
|
425
425
|
}
|
|
426
426
|
}
|
|
427
427
|
|
|
@@ -555,7 +555,7 @@ export class FeatureVersion {
|
|
|
555
555
|
public static parse(input: string): FeatureVersion {
|
|
556
556
|
const match = input.match(this.VERSION_RE)
|
|
557
557
|
if (!match) {
|
|
558
|
-
throw
|
|
558
|
+
throw ERRORS.INVALID_LINK_IDENTIFIER.err(`Expected a version string (of the form v1.2), got ${input}`);
|
|
559
559
|
}
|
|
560
560
|
return new this(+match[1], +match[2])
|
|
561
561
|
}
|
|
@@ -663,17 +663,17 @@ export class FeatureUrl {
|
|
|
663
663
|
public static parse(input: string, node?: ASTNode): FeatureUrl {
|
|
664
664
|
const url = new URL(input)
|
|
665
665
|
if (!url.pathname || url.pathname === '/') {
|
|
666
|
-
throw
|
|
666
|
+
throw ERRORS.INVALID_LINK_IDENTIFIER.err(`Missing path in feature url '${url}'`, { nodes: node })
|
|
667
667
|
}
|
|
668
668
|
const path = url.pathname.split('/')
|
|
669
669
|
const verStr = path.pop()
|
|
670
670
|
if (!verStr) {
|
|
671
|
-
throw
|
|
671
|
+
throw ERRORS.INVALID_LINK_IDENTIFIER.err(`Missing version component in feature url '${url}'`, { nodes: node })
|
|
672
672
|
}
|
|
673
673
|
const version = FeatureVersion.parse(verStr)
|
|
674
674
|
const name = path[path.length - 1]
|
|
675
675
|
if (!name) {
|
|
676
|
-
throw
|
|
676
|
+
throw ERRORS.INVALID_LINK_IDENTIFIER.err(`Missing feature name component in feature url '${url}'`, { nodes: node })
|
|
677
677
|
}
|
|
678
678
|
const element = url.hash ? url.hash.slice(1): undefined
|
|
679
679
|
url.hash = ''
|
|
@@ -804,11 +804,15 @@ export function removeAllCoreFeatures(schema: Schema) {
|
|
|
804
804
|
for (const { feature, type, references } of typeReferences) {
|
|
805
805
|
const referencesInSchema = references.filter(r => r.isAttached());
|
|
806
806
|
if (referencesInSchema.length > 0) {
|
|
807
|
-
|
|
807
|
+
// Note: using REFERENCED_INACCESSIBLE is slightly abusive because the reference element is not marked
|
|
808
|
+
// @inacessible exactly. Instead, it is inacessible due to core elements being removed, but that's very
|
|
809
|
+
// very close semantically. Overall, adding a publicly documented error code just to minor difference
|
|
810
|
+
// doesn't feel worth it, especially since that case is super unlikely in the first place (and, as
|
|
811
|
+
// the prior comment says, may one day be removed too).
|
|
812
|
+
errors.push(ERRORS.REFERENCED_INACCESSIBLE.err(
|
|
808
813
|
`Cannot remove elements of feature ${feature} as feature type ${type}` +
|
|
809
814
|
` is referenced by elements: ${referencesInSchema.join(', ')}`,
|
|
810
|
-
|
|
811
|
-
.filter(n => n !== undefined) as ASTNode[]
|
|
815
|
+
{ nodes: sourceASTs(...references) },
|
|
812
816
|
));
|
|
813
817
|
}
|
|
814
818
|
}
|