@apollo/federation-internals 2.0.0-alpha.2 → 2.0.0-alpha.6
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 +15 -0
- package/dist/buildSchema.d.ts.map +1 -1
- package/dist/buildSchema.js +3 -3
- package/dist/buildSchema.js.map +1 -1
- package/dist/debug.d.ts.map +1 -1
- package/dist/debug.js +2 -18
- package/dist/debug.js.map +1 -1
- package/dist/definitions.d.ts +18 -7
- package/dist/definitions.d.ts.map +1 -1
- package/dist/definitions.js +80 -26
- package/dist/definitions.js.map +1 -1
- package/dist/error.d.ts +88 -3
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +145 -5
- package/dist/error.js.map +1 -1
- package/dist/extractSubgraphsFromSupergraph.d.ts.map +1 -1
- package/dist/extractSubgraphsFromSupergraph.js +41 -4
- package/dist/extractSubgraphsFromSupergraph.js.map +1 -1
- package/dist/federation.d.ts +4 -1
- package/dist/federation.d.ts.map +1 -1
- package/dist/federation.js +231 -58
- package/dist/federation.js.map +1 -1
- package/dist/genErrorCodeDoc.d.ts +2 -0
- package/dist/genErrorCodeDoc.d.ts.map +1 -0
- package/dist/genErrorCodeDoc.js +55 -0
- package/dist/genErrorCodeDoc.js.map +1 -0
- package/dist/inaccessibleSpec.d.ts.map +1 -1
- package/dist/inaccessibleSpec.js +1 -1
- package/dist/inaccessibleSpec.js.map +1 -1
- package/dist/joinSpec.d.ts.map +1 -1
- package/dist/joinSpec.js +6 -5
- package/dist/joinSpec.js.map +1 -1
- package/dist/operations.d.ts.map +1 -1
- package/dist/operations.js +15 -15
- package/dist/operations.js.map +1 -1
- package/dist/tagSpec.d.ts +2 -2
- package/dist/tagSpec.d.ts.map +1 -1
- package/dist/tagSpec.js +10 -2
- package/dist/tagSpec.js.map +1 -1
- package/dist/utils.d.ts +2 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +34 -1
- package/dist/utils.js.map +1 -1
- package/dist/values.d.ts +2 -1
- package/dist/values.d.ts.map +1 -1
- package/dist/values.js +27 -1
- package/dist/values.js.map +1 -1
- package/jest.config.js +5 -1
- package/package.json +3 -6
- package/src/__tests__/extractSubgraphsFromSupergraph.test.ts +535 -0
- package/src/__tests__/subgraphValidation.test.ts +480 -0
- package/src/buildSchema.ts +7 -6
- package/src/debug.ts +2 -19
- package/src/definitions.ts +151 -40
- package/src/error.ts +340 -7
- package/src/extractSubgraphsFromSupergraph.ts +50 -5
- package/src/federation.ts +297 -92
- package/src/genErrorCodeDoc.ts +69 -0
- package/src/inaccessibleSpec.ts +7 -2
- package/src/joinSpec.ts +11 -5
- package/src/operations.ts +20 -18
- package/src/tagSpec.ts +11 -6
- package/src/utils.ts +49 -0
- package/src/values.ts +47 -5
- package/tsconfig.test.tsbuildinfo +1 -1
- package/tsconfig.tsbuildinfo +1 -1
package/src/definitions.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
ConstArgumentNode,
|
|
3
3
|
ASTNode,
|
|
4
4
|
buildASTSchema as buildGraphqlSchemaFromAST,
|
|
5
5
|
DirectiveLocation,
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
ConstDirectiveNode,
|
|
7
|
+
ConstValueNode,
|
|
8
8
|
DocumentNode,
|
|
9
9
|
GraphQLError,
|
|
10
10
|
GraphQLSchema,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
} from "graphql";
|
|
20
20
|
import { CoreDirectiveArgs, CoreSpecDefinition, CORE_VERSIONS, FeatureUrl, isCoreSpecDirectiveApplication, removeFeatureElements } from "./coreSpec";
|
|
21
21
|
import { arrayEquals, assert, mapValues, MapWithCachedArrays, setValues } from "./utils";
|
|
22
|
-
import { withDefaultValues, valueEquals, valueToString, valueToAST, variablesInValue, valueFromAST } from "./values";
|
|
22
|
+
import { withDefaultValues, valueEquals, valueToString, valueToAST, variablesInValue, valueFromAST, valueNodeToConstValueNode } from "./values";
|
|
23
23
|
import { removeInaccessibleElements } from "./inaccessibleSpec";
|
|
24
24
|
import { printSchema, Options, defaultPrintOptions } from './print';
|
|
25
25
|
import { sameType } from './types';
|
|
@@ -233,15 +233,15 @@ export function runtimeTypesIntersects(t1: CompositeType, t2: CompositeType): bo
|
|
|
233
233
|
return false;
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
-
export const executableDirectiveLocations:
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
236
|
+
export const executableDirectiveLocations: DirectiveLocation[] = [
|
|
237
|
+
DirectiveLocation.QUERY,
|
|
238
|
+
DirectiveLocation.MUTATION,
|
|
239
|
+
DirectiveLocation.SUBSCRIPTION,
|
|
240
|
+
DirectiveLocation.FIELD,
|
|
241
|
+
DirectiveLocation.FRAGMENT_DEFINITION,
|
|
242
|
+
DirectiveLocation.FRAGMENT_SPREAD,
|
|
243
|
+
DirectiveLocation.INLINE_FRAGMENT,
|
|
244
|
+
DirectiveLocation.VARIABLE_DEFINITION,
|
|
245
245
|
];
|
|
246
246
|
|
|
247
247
|
/**
|
|
@@ -253,27 +253,27 @@ export function typeToAST(type: Type): TypeNode {
|
|
|
253
253
|
switch (type.kind) {
|
|
254
254
|
case 'ListType':
|
|
255
255
|
return {
|
|
256
|
-
kind:
|
|
256
|
+
kind: Kind.LIST_TYPE,
|
|
257
257
|
type: typeToAST(type.ofType)
|
|
258
258
|
};
|
|
259
259
|
case 'NonNullType':
|
|
260
260
|
return {
|
|
261
|
-
kind:
|
|
261
|
+
kind: Kind.NON_NULL_TYPE,
|
|
262
262
|
type: typeToAST(type.ofType) as NamedTypeNode | ListTypeNode
|
|
263
263
|
};
|
|
264
264
|
default:
|
|
265
265
|
return {
|
|
266
|
-
kind:
|
|
267
|
-
name: { kind:
|
|
266
|
+
kind: Kind.NAMED_TYPE,
|
|
267
|
+
name: { kind: Kind.NAME, value: type.name }
|
|
268
268
|
};
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
271
|
|
|
272
272
|
export function typeFromAST(schema: Schema, node: TypeNode): Type {
|
|
273
273
|
switch (node.kind) {
|
|
274
|
-
case
|
|
274
|
+
case Kind.LIST_TYPE:
|
|
275
275
|
return new ListType(typeFromAST(schema, node.type));
|
|
276
|
-
case
|
|
276
|
+
case Kind.NON_NULL_TYPE:
|
|
277
277
|
return new NonNullType(typeFromAST(schema, node.type) as NullableType);
|
|
278
278
|
default:
|
|
279
279
|
const type = schema.type(node.name.value);
|
|
@@ -339,14 +339,14 @@ export class DirectiveTargetElement<T extends DirectiveTargetElement<T>> {
|
|
|
339
339
|
return toAdd;
|
|
340
340
|
}
|
|
341
341
|
|
|
342
|
-
appliedDirectivesToDirectiveNodes() :
|
|
342
|
+
appliedDirectivesToDirectiveNodes() : ConstDirectiveNode[] | undefined {
|
|
343
343
|
if (this.appliedDirectives.length == 0) {
|
|
344
344
|
return undefined;
|
|
345
345
|
}
|
|
346
346
|
|
|
347
347
|
return this.appliedDirectives.map(directive => {
|
|
348
348
|
return {
|
|
349
|
-
kind:
|
|
349
|
+
kind: Kind.DIRECTIVE,
|
|
350
350
|
name: {
|
|
351
351
|
kind: Kind.NAME,
|
|
352
352
|
value: directive.name,
|
|
@@ -697,6 +697,26 @@ abstract class BaseNamedType<TReferencer, TOwnType extends NamedType & NamedSche
|
|
|
697
697
|
return toReturn;
|
|
698
698
|
}
|
|
699
699
|
|
|
700
|
+
/**
|
|
701
|
+
* Removes this this definition _and_, recursively, any other elements that references this type and would be invalid
|
|
702
|
+
* after the removal.
|
|
703
|
+
*
|
|
704
|
+
* Note that contrarily to `remove()` (which this method essentially call recursively), this method leaves the schema
|
|
705
|
+
* valid (assuming it was valid beforehand) _unless_ all the schema ends up being removed through recursion (in which
|
|
706
|
+
* case this leaves an empty schema, and that is not technically valid).
|
|
707
|
+
*
|
|
708
|
+
* Also note that this method does _not_ necessarily remove all the elements that reference this type: for instance,
|
|
709
|
+
* if this type is an interface, objects implementing it will _not_ be removed, they will simply stop implementing
|
|
710
|
+
* the interface. In practice, this method mainly remove fields that were using the removed type (in either argument or
|
|
711
|
+
* return type), but it can also remove object/input object/interface if through such field removal some type ends up
|
|
712
|
+
* empty, and it can remove unions if through that removal process and union becomes empty.
|
|
713
|
+
*/
|
|
714
|
+
removeRecursive(): void {
|
|
715
|
+
this.remove().forEach(ref => this.removeReferenceRecursive(ref));
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
protected abstract removeReferenceRecursive(ref: TReferencer): void;
|
|
719
|
+
|
|
700
720
|
referencers(): readonly TReferencer[] {
|
|
701
721
|
return setValues(this._referencers);
|
|
702
722
|
}
|
|
@@ -787,14 +807,18 @@ export class BuiltIns {
|
|
|
787
807
|
addBuiltInDirectives(schema: Schema) {
|
|
788
808
|
for (const name of ['include', 'skip']) {
|
|
789
809
|
this.addBuiltInDirective(schema, name)
|
|
790
|
-
.addLocations(
|
|
810
|
+
.addLocations(DirectiveLocation.FIELD, DirectiveLocation.FRAGMENT_SPREAD, DirectiveLocation.INLINE_FRAGMENT)
|
|
791
811
|
.addArgument('if', new NonNullType(schema.booleanType()));
|
|
792
812
|
}
|
|
793
813
|
this.addBuiltInDirective(schema, 'deprecated')
|
|
794
|
-
.addLocations(
|
|
795
|
-
|
|
814
|
+
.addLocations(
|
|
815
|
+
DirectiveLocation.FIELD_DEFINITION,
|
|
816
|
+
DirectiveLocation.ENUM_VALUE,
|
|
817
|
+
DirectiveLocation.ARGUMENT_DEFINITION,
|
|
818
|
+
DirectiveLocation.INPUT_FIELD_DEFINITION,
|
|
819
|
+
).addArgument('reason', schema.stringType(), 'No longer supported');
|
|
796
820
|
this.addBuiltInDirective(schema, 'specifiedBy')
|
|
797
|
-
.addLocations(
|
|
821
|
+
.addLocations(DirectiveLocation.SCALAR)
|
|
798
822
|
.addArgument('url', new NonNullType(schema.stringType()));
|
|
799
823
|
}
|
|
800
824
|
|
|
@@ -1365,7 +1389,7 @@ export class Schema {
|
|
|
1365
1389
|
|
|
1366
1390
|
// TODO: we should ensure first that there is no undefined types (or maybe throw properly when printing the AST
|
|
1367
1391
|
// and catching that properly).
|
|
1368
|
-
let errors
|
|
1392
|
+
let errors = validateSDL(this.toAST(), undefined, this.builtIns.validationRules());
|
|
1369
1393
|
errors = errors.concat(validateSchema(this));
|
|
1370
1394
|
|
|
1371
1395
|
// We avoid adding federation-specific validations if the base schema is not proper graphQL as the later can easily trigger
|
|
@@ -1377,7 +1401,7 @@ export class Schema {
|
|
|
1377
1401
|
}
|
|
1378
1402
|
|
|
1379
1403
|
if (errors.length > 0) {
|
|
1380
|
-
throw ErrGraphQLValidationFailed(errors);
|
|
1404
|
+
throw ErrGraphQLValidationFailed(errors as GraphQLError[]);
|
|
1381
1405
|
}
|
|
1382
1406
|
|
|
1383
1407
|
this.isValidated = true;
|
|
@@ -1530,6 +1554,10 @@ export class ScalarType extends BaseNamedType<OutputTypeReferencer | InputTypeRe
|
|
|
1530
1554
|
protected removeInnerElements(): void {
|
|
1531
1555
|
// No inner elements
|
|
1532
1556
|
}
|
|
1557
|
+
|
|
1558
|
+
protected removeReferenceRecursive(ref: OutputTypeReferencer | InputTypeReferencer): void {
|
|
1559
|
+
ref.remove();
|
|
1560
|
+
}
|
|
1533
1561
|
}
|
|
1534
1562
|
|
|
1535
1563
|
export class InterfaceImplementation<T extends ObjectType | InterfaceType> extends BaseExtensionMember<T> {
|
|
@@ -1753,6 +1781,20 @@ export class ObjectType extends FieldBasedType<ObjectType, ObjectTypeReferencer>
|
|
|
1753
1781
|
const schema = this.schema();
|
|
1754
1782
|
return schema.schemaDefinition.root('query')?.type === this;
|
|
1755
1783
|
}
|
|
1784
|
+
|
|
1785
|
+
protected removeReferenceRecursive(ref: ObjectTypeReferencer): void {
|
|
1786
|
+
// Note that the ref can also be a`SchemaDefinition`, but don't have anything to do then.
|
|
1787
|
+
switch (ref.kind) {
|
|
1788
|
+
case 'FieldDefinition':
|
|
1789
|
+
ref.removeRecursive();
|
|
1790
|
+
break;
|
|
1791
|
+
case 'UnionType':
|
|
1792
|
+
if (ref.membersCount() === 0) {
|
|
1793
|
+
ref.removeRecursive();
|
|
1794
|
+
}
|
|
1795
|
+
break;
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1756
1798
|
}
|
|
1757
1799
|
|
|
1758
1800
|
export class InterfaceType extends FieldBasedType<InterfaceType, InterfaceTypeReferencer> {
|
|
@@ -1771,6 +1813,14 @@ export class InterfaceType extends FieldBasedType<InterfaceType, InterfaceTypeRe
|
|
|
1771
1813
|
const typeName = typeof type === 'string' ? type : type.name;
|
|
1772
1814
|
return this.possibleRuntimeTypes().some(t => t.name == typeName);
|
|
1773
1815
|
}
|
|
1816
|
+
|
|
1817
|
+
protected removeReferenceRecursive(ref: InterfaceTypeReferencer): void {
|
|
1818
|
+
// Note that an interface can be referenced by an object/interface that implements it, but after remove(), said object/interface
|
|
1819
|
+
// will simply not implement "this" anymore and we have nothing more to do.
|
|
1820
|
+
if (ref.kind === 'FieldDefinition') {
|
|
1821
|
+
ref.removeRecursive();
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1774
1824
|
}
|
|
1775
1825
|
|
|
1776
1826
|
export class UnionMember extends BaseExtensionMember<UnionType> {
|
|
@@ -1895,6 +1945,10 @@ export class UnionType extends BaseNamedType<OutputTypeReferencer, UnionType> {
|
|
|
1895
1945
|
protected hasNonExtensionInnerElements(): boolean {
|
|
1896
1946
|
return this.members().some(m => m.ofExtension() === undefined);
|
|
1897
1947
|
}
|
|
1948
|
+
|
|
1949
|
+
protected removeReferenceRecursive(ref: OutputTypeReferencer): void {
|
|
1950
|
+
ref.removeRecursive();
|
|
1951
|
+
}
|
|
1898
1952
|
}
|
|
1899
1953
|
|
|
1900
1954
|
export class EnumType extends BaseNamedType<OutputTypeReferencer, EnumType> {
|
|
@@ -1949,6 +2003,10 @@ export class EnumType extends BaseNamedType<OutputTypeReferencer, EnumType> {
|
|
|
1949
2003
|
protected hasNonExtensionInnerElements(): boolean {
|
|
1950
2004
|
return this._values.some(v => v.ofExtension() === undefined);
|
|
1951
2005
|
}
|
|
2006
|
+
|
|
2007
|
+
protected removeReferenceRecursive(ref: OutputTypeReferencer): void {
|
|
2008
|
+
ref.removeRecursive();
|
|
2009
|
+
}
|
|
1952
2010
|
}
|
|
1953
2011
|
|
|
1954
2012
|
export class InputObjectType extends BaseNamedType<InputTypeReferencer, InputObjectType> {
|
|
@@ -2019,6 +2077,19 @@ export class InputObjectType extends BaseNamedType<InputTypeReferencer, InputObj
|
|
|
2019
2077
|
protected hasNonExtensionInnerElements(): boolean {
|
|
2020
2078
|
return this.fields().some(f => f.ofExtension() === undefined);
|
|
2021
2079
|
}
|
|
2080
|
+
|
|
2081
|
+
protected removeReferenceRecursive(ref: InputTypeReferencer): void {
|
|
2082
|
+
if (ref.kind === 'ArgumentDefinition') {
|
|
2083
|
+
// Not only do we want to remove the argument, but we want to remove its parent. Technically, only removing the argument would
|
|
2084
|
+
// leave the schema in a valid state so it would be an option, but this feel a bit too weird of a behaviour in practice for a
|
|
2085
|
+
// method calling `removeRecursive`. And in particular, it would mean that if the argument is a directive definition one,
|
|
2086
|
+
// we'd also have to update each of the directive application to remove the correspond argument. Removing the full directive
|
|
2087
|
+
// definition (and all its applications) feels a bit more predictable.
|
|
2088
|
+
ref.parent().removeRecursive();
|
|
2089
|
+
} else {
|
|
2090
|
+
ref.removeRecursive();
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2022
2093
|
}
|
|
2023
2094
|
|
|
2024
2095
|
class BaseWrapperType<T extends Type> {
|
|
@@ -2192,6 +2263,19 @@ export class FieldDefinition<TParent extends CompositeType> extends NamedSchemaE
|
|
|
2192
2263
|
return [];
|
|
2193
2264
|
}
|
|
2194
2265
|
|
|
2266
|
+
/**
|
|
2267
|
+
* Like `remove()`, but if this field was the last field of its parent type, the parent type is removed through its `removeRecursive` method.
|
|
2268
|
+
*/
|
|
2269
|
+
removeRecursive(): void {
|
|
2270
|
+
const parent = this._parent;
|
|
2271
|
+
this.remove();
|
|
2272
|
+
// Note that we exclude the union type here because it doesn't have the `fields()` method, but the only field unions can have is the __typename
|
|
2273
|
+
// one and it cannot be removed, so remove() above will actually throw in practice before reaching this.
|
|
2274
|
+
if (parent && !isUnionType(parent) && parent.fields().length === 0) {
|
|
2275
|
+
parent.removeRecursive();
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
|
|
2195
2279
|
toString(): string {
|
|
2196
2280
|
const args = this._args.size == 0
|
|
2197
2281
|
? ""
|
|
@@ -2251,6 +2335,17 @@ export class InputFieldDefinition extends NamedSchemaElementWithType<InputType,
|
|
|
2251
2335
|
return [];
|
|
2252
2336
|
}
|
|
2253
2337
|
|
|
2338
|
+
/**
|
|
2339
|
+
* Like `remove()`, but if this field was the last field of its parent type, the parent type is removed through its `removeRecursive` method.
|
|
2340
|
+
*/
|
|
2341
|
+
removeRecursive(): void {
|
|
2342
|
+
const parent = this._parent;
|
|
2343
|
+
this.remove();
|
|
2344
|
+
if (parent && parent.fields().length === 0) {
|
|
2345
|
+
parent.removeRecursive();
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2348
|
+
|
|
2254
2349
|
toString(): string {
|
|
2255
2350
|
const defaultStr = this.defaultValue === undefined ? "" : ` = ${valueToString(this.defaultValue, this.type)}`;
|
|
2256
2351
|
return `${this.name}: ${this.type}${defaultStr}`;
|
|
@@ -2367,7 +2462,7 @@ export class DirectiveDefinition<TApplicationArgs extends {[key: string]: any} =
|
|
|
2367
2462
|
|
|
2368
2463
|
private readonly _args: MapWithCachedArrays<string, ArgumentDefinition<DirectiveDefinition>> = new MapWithCachedArrays();
|
|
2369
2464
|
repeatable: boolean = false;
|
|
2370
|
-
private readonly _locations:
|
|
2465
|
+
private readonly _locations: DirectiveLocation[] = [];
|
|
2371
2466
|
private readonly _referencers: Set<Directive<SchemaElement<any, any>, TApplicationArgs>> = new Set();
|
|
2372
2467
|
|
|
2373
2468
|
constructor(name: string, readonly isBuiltIn: boolean = false) {
|
|
@@ -2414,11 +2509,11 @@ export class DirectiveDefinition<TApplicationArgs extends {[key: string]: any} =
|
|
|
2414
2509
|
this._args.delete(name);
|
|
2415
2510
|
}
|
|
2416
2511
|
|
|
2417
|
-
get locations(): readonly
|
|
2512
|
+
get locations(): readonly DirectiveLocation[] {
|
|
2418
2513
|
return this._locations;
|
|
2419
2514
|
}
|
|
2420
2515
|
|
|
2421
|
-
addLocations(...locations:
|
|
2516
|
+
addLocations(...locations: DirectiveLocation[]): DirectiveDefinition {
|
|
2422
2517
|
let modified = false;
|
|
2423
2518
|
for (const location of locations) {
|
|
2424
2519
|
if (!this._locations.includes(location)) {
|
|
@@ -2437,10 +2532,17 @@ export class DirectiveDefinition<TApplicationArgs extends {[key: string]: any} =
|
|
|
2437
2532
|
}
|
|
2438
2533
|
|
|
2439
2534
|
addAllTypeLocations(): DirectiveDefinition {
|
|
2440
|
-
return this.addLocations(
|
|
2535
|
+
return this.addLocations(
|
|
2536
|
+
DirectiveLocation.SCALAR,
|
|
2537
|
+
DirectiveLocation.OBJECT,
|
|
2538
|
+
DirectiveLocation.INTERFACE,
|
|
2539
|
+
DirectiveLocation.UNION,
|
|
2540
|
+
DirectiveLocation.ENUM,
|
|
2541
|
+
DirectiveLocation.INPUT_OBJECT,
|
|
2542
|
+
);
|
|
2441
2543
|
}
|
|
2442
2544
|
|
|
2443
|
-
removeLocations(...locations:
|
|
2545
|
+
removeLocations(...locations: DirectiveLocation[]): DirectiveDefinition {
|
|
2444
2546
|
let modified = false;
|
|
2445
2547
|
for (const location of locations) {
|
|
2446
2548
|
const index = this._locations.indexOf(location);
|
|
@@ -2491,6 +2593,13 @@ export class DirectiveDefinition<TApplicationArgs extends {[key: string]: any} =
|
|
|
2491
2593
|
return toReturn;
|
|
2492
2594
|
}
|
|
2493
2595
|
|
|
2596
|
+
/**
|
|
2597
|
+
* Removes this this directive definition _and_ all its applications.
|
|
2598
|
+
*/
|
|
2599
|
+
removeRecursive(): void {
|
|
2600
|
+
this.remove().forEach(ref => ref.remove());
|
|
2601
|
+
}
|
|
2602
|
+
|
|
2494
2603
|
toString(): string {
|
|
2495
2604
|
return `@${this.name}`;
|
|
2496
2605
|
}
|
|
@@ -2588,7 +2697,7 @@ export class Directive<
|
|
|
2588
2697
|
this.onModification();
|
|
2589
2698
|
}
|
|
2590
2699
|
|
|
2591
|
-
argumentsToAST():
|
|
2700
|
+
argumentsToAST(): ConstArgumentNode[] | undefined {
|
|
2592
2701
|
const entries = Object.entries(this._args);
|
|
2593
2702
|
if (entries.length === 0) {
|
|
2594
2703
|
return undefined;
|
|
@@ -2598,9 +2707,9 @@ export class Directive<
|
|
|
2598
2707
|
assert(definition, () => `Cannot convert arguments of detached directive ${this}`);
|
|
2599
2708
|
return entries.map(([n, v]) => {
|
|
2600
2709
|
return {
|
|
2601
|
-
kind:
|
|
2710
|
+
kind: Kind.ARGUMENT,
|
|
2602
2711
|
name: { kind: Kind.NAME, value: n },
|
|
2603
|
-
value: valueToAST(v, definition.argument(n)!.type!)
|
|
2712
|
+
value: valueToAST(v, definition.argument(n)!.type!)! as ConstValueNode,
|
|
2604
2713
|
};
|
|
2605
2714
|
});
|
|
2606
2715
|
}
|
|
@@ -2664,8 +2773,8 @@ export class Variable {
|
|
|
2664
2773
|
|
|
2665
2774
|
toVariableNode(): VariableNode {
|
|
2666
2775
|
return {
|
|
2667
|
-
kind:
|
|
2668
|
-
name: { kind:
|
|
2776
|
+
kind: Kind.VARIABLE,
|
|
2777
|
+
name: { kind: Kind.NAME, value: this.name },
|
|
2669
2778
|
}
|
|
2670
2779
|
}
|
|
2671
2780
|
|
|
@@ -2719,12 +2828,14 @@ export class VariableDefinition extends DirectiveTargetElement<VariableDefinitio
|
|
|
2719
2828
|
}
|
|
2720
2829
|
|
|
2721
2830
|
toVariableDefinitionNode(): VariableDefinitionNode {
|
|
2831
|
+
const ast = valueToAST(this.defaultValue, this.type);
|
|
2832
|
+
|
|
2722
2833
|
return {
|
|
2723
|
-
kind:
|
|
2834
|
+
kind: Kind.VARIABLE_DEFINITION,
|
|
2724
2835
|
variable: this.variable.toVariableNode(),
|
|
2725
2836
|
type: typeToAST(this.type),
|
|
2726
|
-
defaultValue:
|
|
2727
|
-
directives: this.appliedDirectivesToDirectiveNodes()
|
|
2837
|
+
defaultValue: (ast !== undefined) ? valueNodeToConstValueNode(ast) : undefined,
|
|
2838
|
+
directives: this.appliedDirectivesToDirectiveNodes(),
|
|
2728
2839
|
}
|
|
2729
2840
|
}
|
|
2730
2841
|
|