@apollo/federation-internals 2.0.0-preview.1 → 2.0.0-preview.10
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 -3
- package/dist/buildSchema.d.ts.map +1 -1
- package/dist/buildSchema.js +59 -45
- package/dist/buildSchema.js.map +1 -1
- package/dist/coreSpec.d.ts +16 -8
- package/dist/coreSpec.d.ts.map +1 -1
- package/dist/coreSpec.js +171 -42
- package/dist/coreSpec.js.map +1 -1
- package/dist/definitions.d.ts +24 -11
- package/dist/definitions.d.ts.map +1 -1
- package/dist/definitions.js +142 -31
- 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 +12 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +44 -2
- package/dist/error.js.map +1 -1
- package/dist/extractSubgraphsFromSupergraph.d.ts.map +1 -1
- package/dist/extractSubgraphsFromSupergraph.js +15 -5
- package/dist/extractSubgraphsFromSupergraph.js.map +1 -1
- package/dist/federation.d.ts +18 -4
- package/dist/federation.d.ts.map +1 -1
- package/dist/federation.js +117 -67
- package/dist/federation.js.map +1 -1
- package/dist/federationSpec.d.ts +6 -2
- package/dist/federationSpec.d.ts.map +1 -1
- package/dist/federationSpec.js +47 -21
- package/dist/federationSpec.js.map +1 -1
- package/dist/inaccessibleSpec.d.ts +5 -1
- package/dist/inaccessibleSpec.d.ts.map +1 -1
- package/dist/inaccessibleSpec.js +31 -3
- package/dist/inaccessibleSpec.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- 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 +5 -1
- package/dist/joinSpec.d.ts.map +1 -1
- package/dist/joinSpec.js +21 -0
- package/dist/joinSpec.js.map +1 -1
- package/dist/knownCoreFeatures.d.ts +4 -0
- package/dist/knownCoreFeatures.d.ts.map +1 -0
- package/dist/knownCoreFeatures.js +16 -0
- package/dist/knownCoreFeatures.js.map +1 -0
- 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/print.js +12 -12
- package/dist/print.js.map +1 -1
- package/dist/schemaUpgrader.d.ts.map +1 -1
- package/dist/schemaUpgrader.js +5 -6
- 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 +1 -0
- package/dist/supergraphs.js.map +1 -1
- package/dist/tagSpec.d.ts +7 -2
- package/dist/tagSpec.d.ts.map +1 -1
- package/dist/tagSpec.js +35 -13
- package/dist/tagSpec.js.map +1 -1
- package/dist/validate.js +10 -7
- package/dist/validate.js.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/coreSpec.test.ts +100 -0
- package/src/__tests__/definitions.test.ts +79 -0
- package/src/__tests__/extractSubgraphsFromSupergraph.test.ts +64 -0
- package/src/__tests__/removeInaccessibleElements.test.ts +59 -6
- package/src/__tests__/schemaUpgrader.test.ts +3 -2
- package/src/__tests__/subgraphValidation.test.ts +419 -4
- package/src/buildSchema.ts +104 -53
- package/src/coreSpec.ts +208 -50
- package/src/definitions.ts +185 -32
- package/src/directiveAndTypeSpecification.ts +98 -21
- package/src/error.ts +89 -1
- package/src/extractSubgraphsFromSupergraph.ts +23 -5
- package/src/federation.ts +154 -82
- package/src/federationSpec.ts +56 -23
- package/src/inaccessibleSpec.ts +39 -11
- package/src/index.ts +2 -0
- package/src/introspection.ts +8 -3
- package/src/joinSpec.ts +33 -3
- package/src/knownCoreFeatures.ts +13 -0
- package/src/operations.ts +15 -0
- package/src/{sharing.ts → precompute.ts} +3 -6
- package/src/print.ts +13 -11
- package/src/schemaUpgrader.ts +8 -12
- package/src/suggestions.ts +1 -1
- package/src/supergraphs.ts +1 -0
- package/src/tagSpec.ts +49 -15
- package/src/validate.ts +14 -9
- package/tsconfig.test.tsbuildinfo +1 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/sharing.d.ts.map +0 -1
- package/dist/sharing.js.map +0 -1
package/src/coreSpec.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { ASTNode, DirectiveLocation, GraphQLError, StringValueNode } from "graphql";
|
|
2
2
|
import { URL } from "url";
|
|
3
|
-
import { CoreFeature, Directive, DirectiveDefinition, EnumType, ListType, NamedType, NonNullType, ScalarType, Schema, SchemaDefinition } from "./definitions";
|
|
3
|
+
import { CoreFeature, Directive, DirectiveDefinition, EnumType, ErrGraphQLValidationFailed, InputType, ListType, NamedType, NonNullType, ScalarType, Schema, SchemaDefinition } from "./definitions";
|
|
4
4
|
import { sameType } from "./types";
|
|
5
5
|
import { err } from '@apollo/core-schema';
|
|
6
6
|
import { assert } from './utils';
|
|
7
7
|
import { ERRORS } from "./error";
|
|
8
|
+
import { valueToString } from "./values";
|
|
9
|
+
import { coreFeatureDefinitionIfKnown, registerKnownFeature } from "./knownCoreFeatures";
|
|
10
|
+
import { didYouMean, suggestionList } from "./suggestions";
|
|
11
|
+
import { ArgumentSpecification, createDirectiveSpecification, createEnumTypeSpecification, createScalarTypeSpecification, DirectiveSpecification, TypeSpecification } from "./directiveAndTypeSpecification";
|
|
8
12
|
|
|
9
13
|
export const coreIdentity = 'https://specs.apollo.dev/core';
|
|
10
14
|
export const linkIdentity = 'https://specs.apollo.dev/link';
|
|
@@ -61,7 +65,9 @@ export abstract class FeatureDefinition {
|
|
|
61
65
|
return nameInSchema != undefined && (directive.name === nameInSchema || directive.name.startsWith(`${nameInSchema}__`));
|
|
62
66
|
}
|
|
63
67
|
|
|
64
|
-
abstract addElementsToSchema(schema: Schema):
|
|
68
|
+
abstract addElementsToSchema(schema: Schema): GraphQLError[];
|
|
69
|
+
|
|
70
|
+
abstract allElementNames(): string[];
|
|
65
71
|
|
|
66
72
|
protected nameInSchema(schema: Schema): string | undefined {
|
|
67
73
|
const feature = this.featureInSchema(schema);
|
|
@@ -73,9 +79,9 @@ export abstract class FeatureDefinition {
|
|
|
73
79
|
return feature ? feature.directiveNameInSchema(directiveName) : undefined;
|
|
74
80
|
}
|
|
75
81
|
|
|
76
|
-
protected typeNameInSchema(schema: Schema,
|
|
82
|
+
protected typeNameInSchema(schema: Schema, typeName: string): string | undefined {
|
|
77
83
|
const feature = this.featureInSchema(schema);
|
|
78
|
-
return feature ? feature.typeNameInSchema(
|
|
84
|
+
return feature ? feature.typeNameInSchema(typeName) : undefined;
|
|
79
85
|
}
|
|
80
86
|
|
|
81
87
|
protected rootDirective<TApplicationArgs extends {[key: string]: any}>(schema: Schema): DirectiveDefinition<TApplicationArgs> | undefined {
|
|
@@ -101,6 +107,14 @@ export abstract class FeatureDefinition {
|
|
|
101
107
|
return schema.addDirectiveDefinition(this.directiveNameInSchema(schema, name)!);
|
|
102
108
|
}
|
|
103
109
|
|
|
110
|
+
protected addDirectiveSpec(schema: Schema, spec: DirectiveSpecification): GraphQLError[] {
|
|
111
|
+
return spec.checkOrAdd(schema, this.directiveNameInSchema(schema, spec.name));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
protected addTypeSpec(schema: Schema, spec: TypeSpecification): GraphQLError[] {
|
|
115
|
+
return spec.checkOrAdd(schema, this.typeNameInSchema(schema, spec.name));
|
|
116
|
+
}
|
|
117
|
+
|
|
104
118
|
protected addScalarType(schema: Schema, name: string): ScalarType {
|
|
105
119
|
return schema.addType(new ScalarType(this.typeNameInSchema(schema, name)!));
|
|
106
120
|
}
|
|
@@ -144,33 +158,115 @@ export type CoreImport = {
|
|
|
144
158
|
as?: string,
|
|
145
159
|
};
|
|
146
160
|
|
|
147
|
-
export function extractCoreFeatureImports(directive: Directive<SchemaDefinition, CoreOrLinkDirectiveArgs>): CoreImport[] {
|
|
161
|
+
export function extractCoreFeatureImports(url: FeatureUrl, directive: Directive<SchemaDefinition, CoreOrLinkDirectiveArgs>): CoreImport[] {
|
|
162
|
+
// Note: up to this point, we've kind of cheated with typing and force-casted the arguments to `CoreOrLinkDirectiveArgs`, and while this
|
|
163
|
+
// graphQL type validations ensure this is "mostly" true, the `import' arg is an exception becuse it uses the `link__Import` scalar,
|
|
164
|
+
// and so there is no fine-grained graphQL-side validation of the values. So we'll need to double-check that the values are indeed
|
|
165
|
+
// either a string or a valid `CoreImport` value.
|
|
148
166
|
const args = directive.arguments();
|
|
149
|
-
if (!('import' in args)) {
|
|
167
|
+
if (!('import' in args) || !args.import) {
|
|
150
168
|
return [];
|
|
151
169
|
}
|
|
152
|
-
const
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
170
|
+
const importArgValue = args.import;
|
|
171
|
+
const definition = coreFeatureDefinitionIfKnown(url);
|
|
172
|
+
const knownElements = definition?.allElementNames();
|
|
173
|
+
const errors: GraphQLError[] = [];
|
|
174
|
+
const imports: CoreImport[] = [];
|
|
175
|
+
|
|
176
|
+
importArgLoop:
|
|
177
|
+
for (const elt of importArgValue) {
|
|
178
|
+
if (typeof elt === 'string') {
|
|
179
|
+
imports.push({ name: elt });
|
|
180
|
+
validateImportedName(elt, knownElements, errors, directive);
|
|
156
181
|
continue;
|
|
157
182
|
}
|
|
158
|
-
if (
|
|
159
|
-
|
|
160
|
-
message: `Invalid @link
|
|
183
|
+
if (typeof elt !== 'object') {
|
|
184
|
+
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err({
|
|
185
|
+
message: `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>" }.`,
|
|
161
186
|
nodes: directive.sourceAST
|
|
162
|
-
});
|
|
187
|
+
}));
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
let name: string | undefined;
|
|
191
|
+
for (const [key, value] of Object.entries(elt)) {
|
|
192
|
+
switch (key) {
|
|
193
|
+
case 'name':
|
|
194
|
+
if (typeof value !== 'string') {
|
|
195
|
+
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err({
|
|
196
|
+
message: `Invalid value for the "name" field for sub-value ${valueToString(elt)} of @link(import:) argument: must be a string.`,
|
|
197
|
+
nodes: directive.sourceAST
|
|
198
|
+
}));
|
|
199
|
+
continue importArgLoop;
|
|
200
|
+
}
|
|
201
|
+
name = value;
|
|
202
|
+
break;
|
|
203
|
+
case 'as':
|
|
204
|
+
if (typeof value !== 'string') {
|
|
205
|
+
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err({
|
|
206
|
+
message: `Invalid value for the "as" field for sub-value ${valueToString(elt)} of @link(import:) argument: must be a string.`,
|
|
207
|
+
nodes: directive.sourceAST
|
|
208
|
+
}));
|
|
209
|
+
continue importArgLoop;
|
|
210
|
+
}
|
|
211
|
+
break;
|
|
212
|
+
default:
|
|
213
|
+
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err({
|
|
214
|
+
message: `Unknown field "${key}" for sub-value ${valueToString(elt)} of @link(import:) argument.`,
|
|
215
|
+
nodes: directive.sourceAST
|
|
216
|
+
}));
|
|
217
|
+
continue importArgLoop;
|
|
218
|
+
}
|
|
163
219
|
}
|
|
164
|
-
if (
|
|
165
|
-
|
|
166
|
-
|
|
220
|
+
if (name) {
|
|
221
|
+
const i = elt as CoreImport;
|
|
222
|
+
imports.push(i);
|
|
223
|
+
if (i.as) {
|
|
224
|
+
if (i.name.charAt(0) === '@' && i.as.charAt(0) !== '@') {
|
|
225
|
+
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err({
|
|
226
|
+
message: `Invalid @link import renaming: directive "${i.name}" imported name should start with a '@' character, but got "${i.as}".`,
|
|
227
|
+
nodes: directive.sourceAST
|
|
228
|
+
}));
|
|
229
|
+
}
|
|
230
|
+
else if (i.name.charAt(0) !== '@' && i.as.charAt(0) === '@') {
|
|
231
|
+
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err({
|
|
232
|
+
message: `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 '@').`,
|
|
233
|
+
nodes: directive.sourceAST
|
|
234
|
+
}));
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
validateImportedName(name, knownElements, errors, directive);
|
|
238
|
+
} else {
|
|
239
|
+
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err({
|
|
240
|
+
message: `Invalid sub-value ${valueToString(elt)} for @link(import:) argument: missing mandatory "name" field.`,
|
|
167
241
|
nodes: directive.sourceAST
|
|
168
|
-
});
|
|
242
|
+
}));
|
|
169
243
|
}
|
|
170
244
|
}
|
|
245
|
+
|
|
246
|
+
if (errors.length > 0) {
|
|
247
|
+
throw ErrGraphQLValidationFailed(errors);
|
|
248
|
+
}
|
|
171
249
|
return imports;
|
|
172
250
|
}
|
|
173
251
|
|
|
252
|
+
function validateImportedName(name: string, knownElements: string[] | undefined, errors: GraphQLError[], directive: Directive<SchemaDefinition>) {
|
|
253
|
+
if (knownElements && !knownElements.includes(name)) {
|
|
254
|
+
let details = '';
|
|
255
|
+
if (!name.startsWith('@') && knownElements.includes('@' + name)) {
|
|
256
|
+
details = ` Did you mean directive "@${name}"?`;
|
|
257
|
+
} else {
|
|
258
|
+
const suggestions = suggestionList(name, knownElements);
|
|
259
|
+
if (suggestions) {
|
|
260
|
+
details = didYouMean(suggestions);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
errors.push(ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err({
|
|
264
|
+
message: `Cannot import unknown element "${name}".${details}`,
|
|
265
|
+
nodes: directive.sourceAST
|
|
266
|
+
}));
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
174
270
|
export function isCoreSpecDirectiveApplication(directive: Directive<SchemaDefinition, any>): directive is Directive<SchemaDefinition, CoreOrLinkDirectiveArgs> {
|
|
175
271
|
const definition = directive.definition;
|
|
176
272
|
if (!definition) {
|
|
@@ -184,7 +280,7 @@ export function isCoreSpecDirectiveApplication(directive: Directive<SchemaDefini
|
|
|
184
280
|
return false;
|
|
185
281
|
}
|
|
186
282
|
const urlArg = definition.argument('url') ?? definition.argument('feature');
|
|
187
|
-
if (!urlArg || !
|
|
283
|
+
if (!urlArg || !isValidUrlArgumentType(urlArg.type!, directive.schema())) {
|
|
188
284
|
return false;
|
|
189
285
|
}
|
|
190
286
|
|
|
@@ -201,53 +297,112 @@ export function isCoreSpecDirectiveApplication(directive: Directive<SchemaDefini
|
|
|
201
297
|
}
|
|
202
298
|
}
|
|
203
299
|
|
|
300
|
+
function isValidUrlArgumentType(type: InputType, schema: Schema): boolean {
|
|
301
|
+
// Note that the 'url' arg is defined as nullable (mostly for future proofing reasons) but we allow use to provide a definition
|
|
302
|
+
// where it's non-nullable (and in practice, @core (which we never generate anymore, but recognize) definition technically uses
|
|
303
|
+
// with a non-nullable argument, and some fed2 previews did if for @link, so this ensure we handle reading schema generated
|
|
304
|
+
// by those versions just fine).
|
|
305
|
+
return sameType(type, schema.stringType())
|
|
306
|
+
|| sameType(type, new NonNullType(schema.stringType()));
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const linkPurposeTypeSpec = createEnumTypeSpecification({
|
|
310
|
+
name: 'Purpose',
|
|
311
|
+
values: corePurposes.map((name) => ({ name, description: purposesDescription(name)}))
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
const linkImportTypeSpec = createScalarTypeSpecification({ name: 'Import' });
|
|
315
|
+
|
|
204
316
|
export class CoreSpecDefinition extends FeatureDefinition {
|
|
317
|
+
private readonly directiveDefinitionSpec: DirectiveSpecification;
|
|
318
|
+
|
|
205
319
|
constructor(version: FeatureVersion, identity: string = linkIdentity, name: string = linkDirectiveDefaultName) {
|
|
206
320
|
super(new FeatureUrl(identity, name, version));
|
|
321
|
+
this.directiveDefinitionSpec = createDirectiveSpecification({
|
|
322
|
+
name,
|
|
323
|
+
locations: [DirectiveLocation.SCHEMA],
|
|
324
|
+
repeatable: true,
|
|
325
|
+
argumentFct: (schema, nameInSchema) => this.createDefinitionArgumentSpecifications(schema, nameInSchema),
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
private createDefinitionArgumentSpecifications(schema: Schema, nameInSchema?: string): { args: ArgumentSpecification[], errors: GraphQLError[] } {
|
|
330
|
+
const args: ArgumentSpecification[] = [
|
|
331
|
+
{ name: this.urlArgName(), type: schema.stringType() },
|
|
332
|
+
{ name: 'as', type: schema.stringType() },
|
|
333
|
+
];
|
|
334
|
+
if (this.supportPurposes()) {
|
|
335
|
+
const purposeName = `${nameInSchema ?? this.url.name}__${linkPurposeTypeSpec.name}`;
|
|
336
|
+
const errors = linkPurposeTypeSpec.checkOrAdd(schema, purposeName);
|
|
337
|
+
if (errors.length > 0) {
|
|
338
|
+
return { args, errors }
|
|
339
|
+
}
|
|
340
|
+
args.push({ name: 'for', type: schema.type(purposeName) as InputType });
|
|
341
|
+
}
|
|
342
|
+
if (this.supportImport()) {
|
|
343
|
+
const importName = `${nameInSchema ?? this.url.name}__${linkImportTypeSpec.name}`;
|
|
344
|
+
const errors = linkImportTypeSpec.checkOrAdd(schema, importName);
|
|
345
|
+
if (errors.length > 0) {
|
|
346
|
+
return { args, errors }
|
|
347
|
+
}
|
|
348
|
+
args.push({ name: 'import', type: new ListType(schema.type(importName)!) });
|
|
349
|
+
}
|
|
350
|
+
return { args, errors: [] };
|
|
207
351
|
}
|
|
208
352
|
|
|
209
|
-
addElementsToSchema(_: Schema):
|
|
353
|
+
addElementsToSchema(_: Schema): GraphQLError[] {
|
|
210
354
|
// Core is special and the @core directive is added in `addToSchema` below
|
|
355
|
+
return [];
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// TODO: we may want to allow some `import` as argument to this method. When we do, we need to watch for imports of
|
|
359
|
+
// `Purpose` and `Import` and add the types under their imported name.
|
|
360
|
+
addToSchema(schema: Schema, as?: string): GraphQLError[] {
|
|
361
|
+
const errors = this.addDefinitionsToSchema(schema, as);
|
|
362
|
+
if (errors.length > 0) {
|
|
363
|
+
return errors;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Note: we don't use `applyFeatureToSchema` because it would complain the schema is not a core schema, which it isn't
|
|
367
|
+
// until the next line.
|
|
368
|
+
const args = { [this.urlArgName()]: this.toString() } as unknown as CoreOrLinkDirectiveArgs;
|
|
369
|
+
if (as) {
|
|
370
|
+
args.as = as;
|
|
371
|
+
}
|
|
372
|
+
schema.schemaDefinition.applyDirective(as ?? this.url.name, args, true);
|
|
373
|
+
return [];
|
|
211
374
|
}
|
|
212
375
|
|
|
213
|
-
|
|
214
|
-
const
|
|
215
|
-
if (
|
|
216
|
-
if (
|
|
376
|
+
addDefinitionsToSchema(schema: Schema, as?: string): GraphQLError[] {
|
|
377
|
+
const existingCore = schema.coreFeatures;
|
|
378
|
+
if (existingCore) {
|
|
379
|
+
if (existingCore.coreItself.url.identity === this.identity) {
|
|
217
380
|
// Already exists with the same version, let it be.
|
|
218
|
-
return;
|
|
381
|
+
return [];
|
|
219
382
|
} else {
|
|
220
|
-
|
|
383
|
+
return [ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err({
|
|
384
|
+
message: `Cannot add feature ${this} to the schema, it already uses ${existingCore.coreItself.url}`
|
|
385
|
+
})];
|
|
221
386
|
}
|
|
222
387
|
}
|
|
223
388
|
|
|
224
389
|
const nameInSchema = as ?? this.url.name;
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
390
|
+
return this.directiveDefinitionSpec.checkOrAdd(schema, nameInSchema);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* The list of all the element names that can be "imported" from this feature. Importantly, directive names
|
|
395
|
+
* must start with a `@`.
|
|
396
|
+
*/
|
|
397
|
+
allElementNames(): string[] {
|
|
398
|
+
const names = [ `@${this.url.name}` ];
|
|
229
399
|
if (this.supportPurposes()) {
|
|
230
|
-
|
|
231
|
-
for (const purpose of corePurposes) {
|
|
232
|
-
purposeEnum.addValue(purpose).description = purposesDescription(purpose);
|
|
233
|
-
}
|
|
234
|
-
core.addArgument('for', purposeEnum);
|
|
400
|
+
names.push('Purpose');
|
|
235
401
|
}
|
|
236
402
|
if (this.supportImport()) {
|
|
237
|
-
|
|
238
|
-
console.trace();
|
|
239
|
-
}
|
|
240
|
-
const importType = schema.addType(new ScalarType(`${nameInSchema}__Import`));
|
|
241
|
-
core.addArgument('import', new ListType(importType));
|
|
403
|
+
names.push('Import');
|
|
242
404
|
}
|
|
243
|
-
|
|
244
|
-
// Note: we don't use `applyFeatureToSchema` because it would complain the schema is not a core schema, which it isn't
|
|
245
|
-
// until the next line.
|
|
246
|
-
const args = { [this.urlArgName()]: this.toString() } as unknown as CoreOrLinkDirectiveArgs;
|
|
247
|
-
if (as) {
|
|
248
|
-
args.as = as;
|
|
249
|
-
}
|
|
250
|
-
schema.schemaDefinition.applyDirective(nameInSchema, args);
|
|
405
|
+
return names;
|
|
251
406
|
}
|
|
252
407
|
|
|
253
408
|
private supportPurposes() {
|
|
@@ -280,7 +435,7 @@ export class CoreSpecDefinition extends FeatureDefinition {
|
|
|
280
435
|
return feature.url.version;
|
|
281
436
|
}
|
|
282
437
|
|
|
283
|
-
applyFeatureToSchema(schema: Schema, feature: FeatureDefinition, as?: string, purpose?: CorePurpose) {
|
|
438
|
+
applyFeatureToSchema(schema: Schema, feature: FeatureDefinition, as?: string, purpose?: CorePurpose): GraphQLError[] {
|
|
284
439
|
const coreDirective = this.coreDirective(schema);
|
|
285
440
|
const args = {
|
|
286
441
|
[this.urlArgName()]: feature.toString(),
|
|
@@ -290,7 +445,7 @@ export class CoreSpecDefinition extends FeatureDefinition {
|
|
|
290
445
|
args.for = purpose;
|
|
291
446
|
}
|
|
292
447
|
schema.schemaDefinition.applyDirective(coreDirective, args);
|
|
293
|
-
feature.addElementsToSchema(schema);
|
|
448
|
+
return feature.addElementsToSchema(schema);
|
|
294
449
|
}
|
|
295
450
|
|
|
296
451
|
extractFeatureUrl(args: CoreOrLinkDirectiveArgs): FeatureUrl {
|
|
@@ -548,6 +703,9 @@ export const CORE_VERSIONS = new FeatureDefinitions<CoreSpecDefinition>(coreIden
|
|
|
548
703
|
export const LINK_VERSIONS = new FeatureDefinitions<CoreSpecDefinition>(linkIdentity)
|
|
549
704
|
.add(new CoreSpecDefinition(new FeatureVersion(1, 0)));
|
|
550
705
|
|
|
706
|
+
registerKnownFeature(CORE_VERSIONS);
|
|
707
|
+
registerKnownFeature(LINK_VERSIONS);
|
|
708
|
+
|
|
551
709
|
export function removeFeatureElements(schema: Schema, feature: CoreFeature) {
|
|
552
710
|
// Removing directives first, so that when we remove types, the checks that there is no references don't fail due a directive of a the feature
|
|
553
711
|
// actually using the type.
|