@apollo/federation-internals 2.7.3 → 2.7.4-testing.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/dist/error.d.ts +2 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +4 -0
- package/dist/error.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/operations.d.ts +2 -8
- package/dist/operations.d.ts.map +1 -1
- package/dist/operations.js +8 -9
- package/dist/operations.js.map +1 -1
- package/dist/specs/connectSpec.d.ts +47 -0
- package/dist/specs/connectSpec.d.ts.map +1 -0
- package/dist/specs/connectSpec.js +133 -0
- package/dist/specs/connectSpec.js.map +1 -0
- package/package.json +1 -1
- package/src/error.ts +14 -0
- package/src/index.ts +1 -0
- package/src/operations.ts +12 -11
- package/src/specs/connectSpec.ts +255 -0
- package/wasm/node/federation_internals_wasm.d.ts +7 -0
- package/wasm/node/federation_internals_wasm.js +278 -0
- package/wasm/node/federation_internals_wasm_bg.wasm +0 -0
- package/wasm/node/federation_internals_wasm_bg.wasm.d.ts +9 -0
- package/wasm/node/package.json +14 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CONNECT_VERSIONS = exports.ConnectSpecDefinition = exports.connectIdentity = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const coreSpec_1 = require("./coreSpec");
|
|
6
|
+
const definitions_1 = require("../definitions");
|
|
7
|
+
const knownCoreFeatures_1 = require("../knownCoreFeatures");
|
|
8
|
+
const directiveAndTypeSpecification_1 = require("../directiveAndTypeSpecification");
|
|
9
|
+
const error_1 = require("../error");
|
|
10
|
+
exports.connectIdentity = 'https://specs.apollo.dev/connect';
|
|
11
|
+
const CONNECT = "connect";
|
|
12
|
+
const SOURCE = "source";
|
|
13
|
+
const URL_PATH_TEMPLATE = "URLPathTemplate";
|
|
14
|
+
const JSON_SELECTION = "JSONSelection";
|
|
15
|
+
const CONNECT_HTTP = "ConnectHTTP";
|
|
16
|
+
const SOURCE_HTTP = "SourceHTTP";
|
|
17
|
+
const HTTP_HEADER_MAPPING = "HTTPHeaderMapping";
|
|
18
|
+
class ConnectSpecDefinition extends coreSpec_1.FeatureDefinition {
|
|
19
|
+
constructor(version, minimumFederationVersion) {
|
|
20
|
+
super(new coreSpec_1.FeatureUrl(exports.connectIdentity, CONNECT, version), minimumFederationVersion);
|
|
21
|
+
this.minimumFederationVersion = minimumFederationVersion;
|
|
22
|
+
this.registerDirective((0, directiveAndTypeSpecification_1.createDirectiveSpecification)({
|
|
23
|
+
name: CONNECT,
|
|
24
|
+
locations: [graphql_1.DirectiveLocation.FIELD_DEFINITION],
|
|
25
|
+
repeatable: true,
|
|
26
|
+
composes: false,
|
|
27
|
+
}));
|
|
28
|
+
this.registerDirective((0, directiveAndTypeSpecification_1.createDirectiveSpecification)({
|
|
29
|
+
name: SOURCE,
|
|
30
|
+
locations: [graphql_1.DirectiveLocation.SCHEMA],
|
|
31
|
+
repeatable: true,
|
|
32
|
+
composes: false,
|
|
33
|
+
}));
|
|
34
|
+
this.registerType({ name: URL_PATH_TEMPLATE, checkOrAdd: () => [] });
|
|
35
|
+
this.registerType({ name: JSON_SELECTION, checkOrAdd: () => [] });
|
|
36
|
+
this.registerType({ name: CONNECT_HTTP, checkOrAdd: () => [] });
|
|
37
|
+
this.registerType({ name: SOURCE_HTTP, checkOrAdd: () => [] });
|
|
38
|
+
this.registerType({ name: HTTP_HEADER_MAPPING, checkOrAdd: () => [] });
|
|
39
|
+
}
|
|
40
|
+
addElementsToSchema(schema) {
|
|
41
|
+
const URLPathTemplate = this.addScalarType(schema, URL_PATH_TEMPLATE);
|
|
42
|
+
const JSONSelection = this.addScalarType(schema, JSON_SELECTION);
|
|
43
|
+
const connect = this.addDirective(schema, CONNECT).addLocations(graphql_1.DirectiveLocation.FIELD_DEFINITION);
|
|
44
|
+
connect.repeatable = true;
|
|
45
|
+
connect.addArgument(SOURCE, schema.stringType());
|
|
46
|
+
const HTTPHeaderMapping = schema.addType(new definitions_1.InputObjectType(this.typeNameInSchema(schema, HTTP_HEADER_MAPPING)));
|
|
47
|
+
HTTPHeaderMapping.addField(new definitions_1.InputFieldDefinition('name')).type =
|
|
48
|
+
new definitions_1.NonNullType(schema.stringType());
|
|
49
|
+
HTTPHeaderMapping.addField(new definitions_1.InputFieldDefinition('as')).type =
|
|
50
|
+
schema.stringType();
|
|
51
|
+
HTTPHeaderMapping.addField(new definitions_1.InputFieldDefinition('value')).type =
|
|
52
|
+
schema.stringType();
|
|
53
|
+
const ConnectHTTP = schema.addType(new definitions_1.InputObjectType(this.typeNameInSchema(schema, CONNECT_HTTP)));
|
|
54
|
+
ConnectHTTP.addField(new definitions_1.InputFieldDefinition('GET')).type = URLPathTemplate;
|
|
55
|
+
ConnectHTTP.addField(new definitions_1.InputFieldDefinition('POST')).type = URLPathTemplate;
|
|
56
|
+
ConnectHTTP.addField(new definitions_1.InputFieldDefinition('PUT')).type = URLPathTemplate;
|
|
57
|
+
ConnectHTTP.addField(new definitions_1.InputFieldDefinition('PATCH')).type = URLPathTemplate;
|
|
58
|
+
ConnectHTTP.addField(new definitions_1.InputFieldDefinition('DELETE')).type = URLPathTemplate;
|
|
59
|
+
ConnectHTTP.addField(new definitions_1.InputFieldDefinition('body')).type = JSONSelection;
|
|
60
|
+
ConnectHTTP.addField(new definitions_1.InputFieldDefinition('headers')).type =
|
|
61
|
+
new definitions_1.ListType(new definitions_1.NonNullType(HTTPHeaderMapping));
|
|
62
|
+
connect.addArgument('http', ConnectHTTP);
|
|
63
|
+
connect.addArgument('selection', JSONSelection);
|
|
64
|
+
const source = this.addDirective(schema, SOURCE).addLocations(graphql_1.DirectiveLocation.SCHEMA);
|
|
65
|
+
source.repeatable = true;
|
|
66
|
+
source.addArgument('name', new definitions_1.NonNullType(schema.stringType()));
|
|
67
|
+
const SourceHTTP = schema.addType(new definitions_1.InputObjectType(this.typeNameInSchema(schema, SOURCE_HTTP)));
|
|
68
|
+
SourceHTTP.addField(new definitions_1.InputFieldDefinition('baseURL')).type =
|
|
69
|
+
new definitions_1.NonNullType(schema.stringType());
|
|
70
|
+
SourceHTTP.addField(new definitions_1.InputFieldDefinition('headers')).type =
|
|
71
|
+
new definitions_1.ListType(new definitions_1.NonNullType(HTTPHeaderMapping));
|
|
72
|
+
source.addArgument('http', SourceHTTP);
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
get defaultCorePurpose() {
|
|
76
|
+
return 'EXECUTION';
|
|
77
|
+
}
|
|
78
|
+
sourceDirective(schema) {
|
|
79
|
+
return this.directive(schema, 'source');
|
|
80
|
+
}
|
|
81
|
+
connectDirective(schema) {
|
|
82
|
+
return this.directive(schema, 'connect');
|
|
83
|
+
}
|
|
84
|
+
getConnectDirectives(schema) {
|
|
85
|
+
const result = {};
|
|
86
|
+
schema.schemaDefinition.appliedDirectivesOf('link')
|
|
87
|
+
.forEach(linkDirective => {
|
|
88
|
+
const { url, import: imports } = linkDirective.arguments();
|
|
89
|
+
const featureUrl = coreSpec_1.FeatureUrl.maybeParse(url);
|
|
90
|
+
if (imports && featureUrl && featureUrl.identity === exports.connectIdentity) {
|
|
91
|
+
imports.forEach(nameOrRename => {
|
|
92
|
+
const originalName = typeof nameOrRename === 'string' ? nameOrRename : nameOrRename.name;
|
|
93
|
+
const importedName = typeof nameOrRename === 'string' ? nameOrRename : nameOrRename.as || originalName;
|
|
94
|
+
const importedNameWithoutAt = importedName.replace(/^@/, '');
|
|
95
|
+
if (originalName === '@source') {
|
|
96
|
+
result.source = schema.directive(importedNameWithoutAt);
|
|
97
|
+
}
|
|
98
|
+
else if (originalName === '@connect') {
|
|
99
|
+
result.connect = schema.directive(importedNameWithoutAt);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
validateSubgraphSchema(schema) {
|
|
107
|
+
const errors = super.validateSubgraphSchema(schema);
|
|
108
|
+
const { source: sourceAPI, connect: sourceField, } = this.getConnectDirectives(schema);
|
|
109
|
+
if (!(sourceAPI || sourceField)) {
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
errors.push(...this.validateConnectDirectives(schema));
|
|
113
|
+
return errors;
|
|
114
|
+
}
|
|
115
|
+
validateConnectDirectives(schema) {
|
|
116
|
+
try {
|
|
117
|
+
const { validate_connect_directives } = require('../../wasm/node');
|
|
118
|
+
const source = (0, graphql_1.print)(schema.toAST());
|
|
119
|
+
return validate_connect_directives(source).map(raw => error_1.ERRORS.WASM_VALIDATION_ERROR.err(raw.message, {
|
|
120
|
+
source: new graphql_1.Source(source),
|
|
121
|
+
positions: [raw.index],
|
|
122
|
+
}));
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
return [error_1.ERRORS.WASM_LOAD_ERROR.err(`Error loading WASM module: ${e.message || e}`)];
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
exports.ConnectSpecDefinition = ConnectSpecDefinition;
|
|
130
|
+
exports.CONNECT_VERSIONS = new coreSpec_1.FeatureDefinitions(exports.connectIdentity)
|
|
131
|
+
.add(new ConnectSpecDefinition(new coreSpec_1.FeatureVersion(0, 1), new coreSpec_1.FeatureVersion(2, 8)));
|
|
132
|
+
(0, knownCoreFeatures_1.registerKnownFeature)(exports.CONNECT_VERSIONS);
|
|
133
|
+
//# sourceMappingURL=connectSpec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connectSpec.js","sourceRoot":"","sources":["../../src/specs/connectSpec.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/error.ts
CHANGED
|
@@ -674,6 +674,18 @@ const SOURCE_FIELD_NOT_ON_ROOT_OR_ENTITY_FIELD = makeCodeDefinition(
|
|
|
674
674
|
{ addedIn: '2.7.0' },
|
|
675
675
|
);
|
|
676
676
|
|
|
677
|
+
const WASM_VALIDATION_ERROR = makeCodeDefinition(
|
|
678
|
+
'WASM_VALIDATION_ERROR',
|
|
679
|
+
'Subgraph validation error generated by WASM code',
|
|
680
|
+
{ addedIn: '2.8.0' },
|
|
681
|
+
);
|
|
682
|
+
|
|
683
|
+
const WASM_LOAD_ERROR = makeCodeDefinition(
|
|
684
|
+
'WASM_LOAD_ERROR',
|
|
685
|
+
'Error loading a WebAssembly module',
|
|
686
|
+
{ addedIn: '2.8.0' },
|
|
687
|
+
);
|
|
688
|
+
|
|
677
689
|
export const ERROR_CATEGORIES = {
|
|
678
690
|
DIRECTIVE_FIELDS_MISSING_EXTERNAL,
|
|
679
691
|
DIRECTIVE_UNSUPPORTED_ON_INTERFACE,
|
|
@@ -782,6 +794,8 @@ export const ERRORS = {
|
|
|
782
794
|
SOURCE_FIELD_HTTP_BODY_INVALID,
|
|
783
795
|
SOURCE_FIELD_SELECTION_INVALID,
|
|
784
796
|
SOURCE_FIELD_NOT_ON_ROOT_OR_ENTITY_FIELD,
|
|
797
|
+
WASM_VALIDATION_ERROR,
|
|
798
|
+
WASM_LOAD_ERROR,
|
|
785
799
|
};
|
|
786
800
|
|
|
787
801
|
const codeDefByCode = Object.values(ERRORS).reduce((obj: {[code: string]: ErrorCodeDefinition}, codeDef: ErrorCodeDefinition) => { obj[codeDef.code] = codeDef; return obj; }, {});
|
package/src/index.ts
CHANGED
package/src/operations.ts
CHANGED
|
@@ -879,15 +879,16 @@ function computeFragmentsToKeep(
|
|
|
879
879
|
return toExpand.size === 0 ? fragments : fragments.filter((f) => !toExpand.has(f.name));
|
|
880
880
|
}
|
|
881
881
|
|
|
882
|
-
export class Operation {
|
|
882
|
+
export class Operation extends DirectiveTargetElement<Operation> {
|
|
883
883
|
constructor(
|
|
884
|
-
|
|
884
|
+
schema: Schema,
|
|
885
885
|
readonly rootKind: SchemaRootKind,
|
|
886
886
|
readonly selectionSet: SelectionSet,
|
|
887
887
|
readonly variableDefinitions: VariableDefinitions,
|
|
888
888
|
readonly fragments?: NamedFragments,
|
|
889
889
|
readonly name?: string,
|
|
890
|
-
|
|
890
|
+
directives: readonly Directive<any>[] = []) {
|
|
891
|
+
super(schema, directives);
|
|
891
892
|
}
|
|
892
893
|
|
|
893
894
|
// Returns a copy of this operation with the provided updated selection set.
|
|
@@ -898,13 +899,13 @@ export class Operation {
|
|
|
898
899
|
}
|
|
899
900
|
|
|
900
901
|
return new Operation(
|
|
901
|
-
this.schema,
|
|
902
|
+
this.schema(),
|
|
902
903
|
this.rootKind,
|
|
903
904
|
newSelectionSet,
|
|
904
905
|
this.variableDefinitions,
|
|
905
906
|
this.fragments,
|
|
906
907
|
this.name,
|
|
907
|
-
this.
|
|
908
|
+
this.appliedDirectives,
|
|
908
909
|
);
|
|
909
910
|
}
|
|
910
911
|
|
|
@@ -915,13 +916,13 @@ export class Operation {
|
|
|
915
916
|
}
|
|
916
917
|
|
|
917
918
|
return new Operation(
|
|
918
|
-
this.schema,
|
|
919
|
+
this.schema(),
|
|
919
920
|
this.rootKind,
|
|
920
921
|
newSelectionSet,
|
|
921
922
|
this.variableDefinitions,
|
|
922
923
|
newFragments,
|
|
923
924
|
this.name,
|
|
924
|
-
this.
|
|
925
|
+
this.appliedDirectives,
|
|
925
926
|
);
|
|
926
927
|
}
|
|
927
928
|
|
|
@@ -980,13 +981,13 @@ export class Operation {
|
|
|
980
981
|
generateQueryFragments(): Operation {
|
|
981
982
|
const [minimizedSelectionSet, fragments] = this.selectionSet.minimizeSelectionSet();
|
|
982
983
|
return new Operation(
|
|
983
|
-
this.schema,
|
|
984
|
+
this.schema(),
|
|
984
985
|
this.rootKind,
|
|
985
986
|
minimizedSelectionSet,
|
|
986
987
|
this.variableDefinitions,
|
|
987
988
|
fragments,
|
|
988
989
|
this.name,
|
|
989
|
-
this.
|
|
990
|
+
this.appliedDirectives,
|
|
990
991
|
);
|
|
991
992
|
}
|
|
992
993
|
|
|
@@ -1058,7 +1059,7 @@ export class Operation {
|
|
|
1058
1059
|
}
|
|
1059
1060
|
|
|
1060
1061
|
toString(expandFragments: boolean = false, prettyPrint: boolean = true): string {
|
|
1061
|
-
return this.selectionSet.toOperationString(this.rootKind, this.variableDefinitions, this.fragments, this.name, this.
|
|
1062
|
+
return this.selectionSet.toOperationString(this.rootKind, this.variableDefinitions, this.fragments, this.name, this.appliedDirectives, expandFragments, prettyPrint);
|
|
1062
1063
|
}
|
|
1063
1064
|
}
|
|
1064
1065
|
|
|
@@ -3968,7 +3969,7 @@ export function operationToDocument(operation: Operation): DocumentNode {
|
|
|
3968
3969
|
name: operation.name ? { kind: Kind.NAME, value: operation.name } : undefined,
|
|
3969
3970
|
selectionSet: operation.selectionSet.toSelectionSetNode(),
|
|
3970
3971
|
variableDefinitions: operation.variableDefinitions.toVariableDefinitionNodes(),
|
|
3971
|
-
directives: directivesToDirectiveNodes(operation.
|
|
3972
|
+
directives: directivesToDirectiveNodes(operation.appliedDirectives),
|
|
3972
3973
|
};
|
|
3973
3974
|
const fragmentASTs: DefinitionNode[] = operation.fragments
|
|
3974
3975
|
? operation.fragments?.toFragmentDefinitionNodes()
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { DirectiveLocation, GraphQLError, Source, print } from 'graphql';
|
|
2
|
+
import { CorePurpose, FeatureDefinition, FeatureDefinitions, FeatureUrl, FeatureVersion, LinkDirectiveArgs } from "./coreSpec";
|
|
3
|
+
import {
|
|
4
|
+
Schema,
|
|
5
|
+
NonNullType,
|
|
6
|
+
InputObjectType,
|
|
7
|
+
InputFieldDefinition,
|
|
8
|
+
ListType,
|
|
9
|
+
DirectiveDefinition,
|
|
10
|
+
} from '../definitions';
|
|
11
|
+
import { registerKnownFeature } from '../knownCoreFeatures';
|
|
12
|
+
import { createDirectiveSpecification } from '../directiveAndTypeSpecification';
|
|
13
|
+
import { ERRORS } from '../error';
|
|
14
|
+
|
|
15
|
+
export const connectIdentity = 'https://specs.apollo.dev/connect';
|
|
16
|
+
|
|
17
|
+
const CONNECT = "connect";
|
|
18
|
+
const SOURCE = "source";
|
|
19
|
+
const URL_PATH_TEMPLATE = "URLPathTemplate";
|
|
20
|
+
const JSON_SELECTION = "JSONSelection";
|
|
21
|
+
const CONNECT_HTTP = "ConnectHTTP";
|
|
22
|
+
const SOURCE_HTTP = "SourceHTTP";
|
|
23
|
+
const HTTP_HEADER_MAPPING = "HTTPHeaderMapping";
|
|
24
|
+
|
|
25
|
+
export class ConnectSpecDefinition extends FeatureDefinition {
|
|
26
|
+
constructor(version: FeatureVersion, readonly minimumFederationVersion: FeatureVersion) {
|
|
27
|
+
super(new FeatureUrl(connectIdentity, CONNECT, version), minimumFederationVersion);
|
|
28
|
+
|
|
29
|
+
this.registerDirective(createDirectiveSpecification({
|
|
30
|
+
name: CONNECT,
|
|
31
|
+
locations: [DirectiveLocation.FIELD_DEFINITION],
|
|
32
|
+
repeatable: true,
|
|
33
|
+
// We "compose" these directives using the `@join__directive` mechanism,
|
|
34
|
+
// so they do not need to be composed in the way passing `composes: true`
|
|
35
|
+
// here implies.
|
|
36
|
+
composes: false,
|
|
37
|
+
}));
|
|
38
|
+
|
|
39
|
+
this.registerDirective(createDirectiveSpecification({
|
|
40
|
+
name: SOURCE,
|
|
41
|
+
locations: [DirectiveLocation.SCHEMA],
|
|
42
|
+
repeatable: true,
|
|
43
|
+
composes: false,
|
|
44
|
+
}));
|
|
45
|
+
|
|
46
|
+
this.registerType({ name: URL_PATH_TEMPLATE, checkOrAdd: () => [] });
|
|
47
|
+
this.registerType({ name: JSON_SELECTION, checkOrAdd: () => [] });
|
|
48
|
+
this.registerType({ name: CONNECT_HTTP, checkOrAdd: () => [] });
|
|
49
|
+
this.registerType({ name: SOURCE_HTTP, checkOrAdd: () => [] });
|
|
50
|
+
this.registerType({ name: HTTP_HEADER_MAPPING, checkOrAdd: () => [] });
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
addElementsToSchema(schema: Schema): GraphQLError[] {
|
|
54
|
+
/* scalar URLPathTemplate */
|
|
55
|
+
const URLPathTemplate = this.addScalarType(schema, URL_PATH_TEMPLATE);
|
|
56
|
+
|
|
57
|
+
/* scalar JSONSelection */
|
|
58
|
+
const JSONSelection = this.addScalarType(schema, JSON_SELECTION);
|
|
59
|
+
|
|
60
|
+
/*
|
|
61
|
+
directive @connect(
|
|
62
|
+
source: String
|
|
63
|
+
http: ConnectHTTP
|
|
64
|
+
selection: JSONSelection!
|
|
65
|
+
) repeatable on FIELD_DEFINITION
|
|
66
|
+
*/
|
|
67
|
+
const connect = this.addDirective(schema, CONNECT).addLocations(DirectiveLocation.FIELD_DEFINITION);
|
|
68
|
+
connect.repeatable = true;
|
|
69
|
+
|
|
70
|
+
connect.addArgument(SOURCE, schema.stringType());
|
|
71
|
+
|
|
72
|
+
/*
|
|
73
|
+
input HTTPHeaderMapping {
|
|
74
|
+
name: String!
|
|
75
|
+
as: String
|
|
76
|
+
value: String
|
|
77
|
+
}
|
|
78
|
+
*/
|
|
79
|
+
const HTTPHeaderMapping = schema.addType(new InputObjectType(this.typeNameInSchema(schema, HTTP_HEADER_MAPPING)!));
|
|
80
|
+
HTTPHeaderMapping.addField(new InputFieldDefinition('name')).type =
|
|
81
|
+
new NonNullType(schema.stringType());
|
|
82
|
+
HTTPHeaderMapping.addField(new InputFieldDefinition('as')).type =
|
|
83
|
+
schema.stringType();
|
|
84
|
+
HTTPHeaderMapping.addField(new InputFieldDefinition('value')).type =
|
|
85
|
+
schema.stringType();
|
|
86
|
+
|
|
87
|
+
/*
|
|
88
|
+
input ConnectHTTP {
|
|
89
|
+
GET: URLPathTemplate
|
|
90
|
+
POST: URLPathTemplate
|
|
91
|
+
PUT: URLPathTemplate
|
|
92
|
+
PATCH: URLPathTemplate
|
|
93
|
+
DELETE: URLPathTemplate
|
|
94
|
+
body: JSONSelection
|
|
95
|
+
headers: [HTTPHeaderMapping!]
|
|
96
|
+
}
|
|
97
|
+
*/
|
|
98
|
+
const ConnectHTTP = schema.addType(new InputObjectType(this.typeNameInSchema(schema, CONNECT_HTTP)!));
|
|
99
|
+
ConnectHTTP.addField(new InputFieldDefinition('GET')).type = URLPathTemplate;
|
|
100
|
+
ConnectHTTP.addField(new InputFieldDefinition('POST')).type = URLPathTemplate;
|
|
101
|
+
ConnectHTTP.addField(new InputFieldDefinition('PUT')).type = URLPathTemplate;
|
|
102
|
+
ConnectHTTP.addField(new InputFieldDefinition('PATCH')).type = URLPathTemplate;
|
|
103
|
+
ConnectHTTP.addField(new InputFieldDefinition('DELETE')).type = URLPathTemplate;
|
|
104
|
+
ConnectHTTP.addField(new InputFieldDefinition('body')).type = JSONSelection;
|
|
105
|
+
ConnectHTTP.addField(new InputFieldDefinition('headers')).type =
|
|
106
|
+
new ListType(new NonNullType(HTTPHeaderMapping));
|
|
107
|
+
connect.addArgument('http', ConnectHTTP);
|
|
108
|
+
|
|
109
|
+
connect.addArgument('selection', JSONSelection);
|
|
110
|
+
|
|
111
|
+
/*
|
|
112
|
+
directive @source(
|
|
113
|
+
name: String!
|
|
114
|
+
http: ConnectHTTP
|
|
115
|
+
) repeatable on SCHEMA
|
|
116
|
+
*/
|
|
117
|
+
const source = this.addDirective(schema, SOURCE).addLocations(
|
|
118
|
+
DirectiveLocation.SCHEMA,
|
|
119
|
+
);
|
|
120
|
+
source.repeatable = true;
|
|
121
|
+
source.addArgument('name', new NonNullType(schema.stringType()));
|
|
122
|
+
|
|
123
|
+
/*
|
|
124
|
+
input SourceHTTP {
|
|
125
|
+
baseURL: String!
|
|
126
|
+
headers: [HTTPHeaderMapping!]
|
|
127
|
+
}
|
|
128
|
+
*/
|
|
129
|
+
const SourceHTTP = schema.addType(new InputObjectType(this.typeNameInSchema(schema, SOURCE_HTTP)!));
|
|
130
|
+
SourceHTTP.addField(new InputFieldDefinition('baseURL')).type =
|
|
131
|
+
new NonNullType(schema.stringType());
|
|
132
|
+
SourceHTTP.addField(new InputFieldDefinition('headers')).type =
|
|
133
|
+
new ListType(new NonNullType(HTTPHeaderMapping));
|
|
134
|
+
|
|
135
|
+
source.addArgument('http', SourceHTTP);
|
|
136
|
+
|
|
137
|
+
return [];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
get defaultCorePurpose(): CorePurpose {
|
|
141
|
+
return 'EXECUTION';
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
sourceDirective(schema: Schema) {
|
|
145
|
+
return this.directive<SourceDirectiveArgs>(schema, 'source')!;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
connectDirective(schema: Schema) {
|
|
149
|
+
return this.directive<ConnectDirectiveArgs>(schema, 'connect')!;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private getConnectDirectives(schema: Schema) {
|
|
153
|
+
const result: {
|
|
154
|
+
source?: DirectiveDefinition<SourceDirectiveArgs>;
|
|
155
|
+
connect?: DirectiveDefinition<ConnectDirectiveArgs>;
|
|
156
|
+
} = {};
|
|
157
|
+
|
|
158
|
+
schema.schemaDefinition.appliedDirectivesOf<LinkDirectiveArgs>('link')
|
|
159
|
+
.forEach(linkDirective => {
|
|
160
|
+
const { url, import: imports } = linkDirective.arguments();
|
|
161
|
+
const featureUrl = FeatureUrl.maybeParse(url);
|
|
162
|
+
if (imports && featureUrl && featureUrl.identity === connectIdentity) {
|
|
163
|
+
imports.forEach(nameOrRename => {
|
|
164
|
+
const originalName = typeof nameOrRename === 'string' ? nameOrRename : nameOrRename.name;
|
|
165
|
+
const importedName = typeof nameOrRename === 'string' ? nameOrRename : nameOrRename.as || originalName;
|
|
166
|
+
const importedNameWithoutAt = importedName.replace(/^@/, '');
|
|
167
|
+
|
|
168
|
+
if (originalName === '@source') {
|
|
169
|
+
result.source = schema.directive(importedNameWithoutAt) as DirectiveDefinition<SourceDirectiveArgs>;
|
|
170
|
+
} else if (originalName === '@connect') {
|
|
171
|
+
result.connect = schema.directive(importedNameWithoutAt) as DirectiveDefinition<ConnectDirectiveArgs>;
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
override validateSubgraphSchema(schema: Schema): GraphQLError[] {
|
|
181
|
+
const errors = super.validateSubgraphSchema(schema);
|
|
182
|
+
const {
|
|
183
|
+
source: sourceAPI,
|
|
184
|
+
connect: sourceField,
|
|
185
|
+
} = this.getConnectDirectives(schema);
|
|
186
|
+
|
|
187
|
+
if (!(sourceAPI || sourceField)) {
|
|
188
|
+
// If none of the @source* directives are present, nothing needs
|
|
189
|
+
// validating.
|
|
190
|
+
return [];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
errors.push(...this.validateConnectDirectives(schema));
|
|
194
|
+
|
|
195
|
+
return errors;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
private validateConnectDirectives(schema: Schema): GraphQLError[] {
|
|
199
|
+
try {
|
|
200
|
+
const { validate_connect_directives } =
|
|
201
|
+
require('../../wasm/node') as typeof import('../../wasm/node');
|
|
202
|
+
const source = print(schema.toAST());
|
|
203
|
+
return validate_connect_directives(source).map(
|
|
204
|
+
raw => ERRORS.WASM_VALIDATION_ERROR.err(raw.message, {
|
|
205
|
+
source: new Source(source),
|
|
206
|
+
positions: [raw.index],
|
|
207
|
+
}),
|
|
208
|
+
);
|
|
209
|
+
} catch (e: any) {
|
|
210
|
+
return [ERRORS.WASM_LOAD_ERROR.err(
|
|
211
|
+
`Error loading WASM module: ${e.message || e}`,
|
|
212
|
+
)];
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export type SourceDirectiveArgs = {
|
|
218
|
+
name: string;
|
|
219
|
+
http?: SourceDirectiveHTTP;
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
export type SourceDirectiveHTTP = {
|
|
223
|
+
baseURL: string;
|
|
224
|
+
headers?: HTTPHeaderMapping[];
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
type HTTPHeaderMapping = {
|
|
228
|
+
name: string;
|
|
229
|
+
as?: string;
|
|
230
|
+
value?: string;
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
type URLPathTemplate = string;
|
|
234
|
+
type JSONSelection = string;
|
|
235
|
+
|
|
236
|
+
export type ConnectDirectiveArgs = {
|
|
237
|
+
source: string;
|
|
238
|
+
http?: ConnectDirectiveHTTP;
|
|
239
|
+
selection?: JSONSelection;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
export type ConnectDirectiveHTTP = {
|
|
243
|
+
GET?: URLPathTemplate;
|
|
244
|
+
POST?: URLPathTemplate;
|
|
245
|
+
PUT?: URLPathTemplate;
|
|
246
|
+
PATCH?: URLPathTemplate;
|
|
247
|
+
DELETE?: URLPathTemplate;
|
|
248
|
+
body?: JSONSelection;
|
|
249
|
+
headers?: HTTPHeaderMapping[];
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
export const CONNECT_VERSIONS = new FeatureDefinitions<ConnectSpecDefinition>(connectIdentity)
|
|
253
|
+
.add(new ConnectSpecDefinition(new FeatureVersion(0, 1), new FeatureVersion(2, 8)));
|
|
254
|
+
|
|
255
|
+
registerKnownFeature(CONNECT_VERSIONS);
|