@graphql-mesh/graphql 1.0.0-alpha-3fc47d119.0 → 1.0.0-alpha-20230420181317-a95037648
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/{index.js → cjs/index.js} +107 -64
- package/cjs/package.json +1 -0
- package/{index.mjs → esm/index.js} +81 -38
- package/package.json +31 -24
- package/typings/index.d.cts +23 -0
- package/{index.d.ts → typings/index.d.ts} +7 -4
|
@@ -1,38 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
const getResolverData = utils$1.memoize1(function getResolverData(params) {
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const lodash_get_1 = tslib_1.__importDefault(require("lodash.get"));
|
|
6
|
+
const cross_helpers_1 = require("@graphql-mesh/cross-helpers");
|
|
7
|
+
const store_1 = require("@graphql-mesh/store");
|
|
8
|
+
const string_interpolation_1 = require("@graphql-mesh/string-interpolation");
|
|
9
|
+
const utils_1 = require("@graphql-mesh/utils");
|
|
10
|
+
const url_loader_1 = require("@graphql-tools/url-loader");
|
|
11
|
+
const utils_2 = require("@graphql-tools/utils");
|
|
12
|
+
const wrap_1 = require("@graphql-tools/wrap");
|
|
13
|
+
const getResolverData = (0, utils_2.memoize1)(function getResolverData(params) {
|
|
16
14
|
return {
|
|
17
15
|
root: params.rootValue,
|
|
18
16
|
args: params.variables,
|
|
19
17
|
context: params.context,
|
|
20
|
-
env:
|
|
18
|
+
env: cross_helpers_1.process.env,
|
|
21
19
|
};
|
|
22
20
|
});
|
|
23
21
|
class GraphQLHandler {
|
|
24
|
-
constructor({ config, baseDir,
|
|
25
|
-
this.urlLoader = new
|
|
22
|
+
constructor({ name, config, baseDir, store, importFn, logger, }) {
|
|
23
|
+
this.urlLoader = new url_loader_1.UrlLoader();
|
|
26
24
|
this.interpolationStringSet = new Set();
|
|
25
|
+
this.name = name;
|
|
27
26
|
this.config = config;
|
|
28
27
|
this.baseDir = baseDir;
|
|
29
|
-
this.
|
|
30
|
-
this.nonExecutableSchema = store$1.proxy('introspectionSchema', store.PredefinedProxyOptions.GraphQLSchemaWithDiffing);
|
|
28
|
+
this.nonExecutableSchema = store.proxy('introspectionSchema', store_1.PredefinedProxyOptions.GraphQLSchemaWithDiffing);
|
|
31
29
|
this.importFn = importFn;
|
|
32
30
|
this.logger = logger;
|
|
33
31
|
}
|
|
34
32
|
getArgsAndContextVariables() {
|
|
35
|
-
return
|
|
33
|
+
return (0, string_interpolation_1.parseInterpolationStrings)(this.interpolationStringSet);
|
|
34
|
+
}
|
|
35
|
+
wrapExecutorToPassSourceNameAndDebug(executor) {
|
|
36
|
+
const sourceName = this.name;
|
|
37
|
+
const logger = this.logger;
|
|
38
|
+
return function executorWithSourceName(executionRequest) {
|
|
39
|
+
logger.debug(() => `Sending GraphQL Request: `, (0, graphql_1.print)(executionRequest.document));
|
|
40
|
+
executionRequest.info = executionRequest.info || {};
|
|
41
|
+
executionRequest.info.sourceName = sourceName;
|
|
42
|
+
return executor(executionRequest);
|
|
43
|
+
};
|
|
36
44
|
}
|
|
37
45
|
async getExecutorForHTTPSourceConfig(httpSourceConfig) {
|
|
38
46
|
const { endpoint, operationHeaders = {} } = httpSourceConfig;
|
|
@@ -40,8 +48,8 @@ class GraphQLHandler {
|
|
|
40
48
|
Object.keys(operationHeaders).forEach(headerName => {
|
|
41
49
|
this.interpolationStringSet.add(headerName.toString());
|
|
42
50
|
});
|
|
43
|
-
const endpointFactory =
|
|
44
|
-
const operationHeadersFactory =
|
|
51
|
+
const endpointFactory = (0, string_interpolation_1.getInterpolatedStringFactory)(endpoint);
|
|
52
|
+
const operationHeadersFactory = (0, string_interpolation_1.getInterpolatedHeadersFactory)(operationHeaders);
|
|
45
53
|
const executor = this.urlLoader.getExecutorAsync(endpoint, {
|
|
46
54
|
...httpSourceConfig,
|
|
47
55
|
subscriptionsProtocol: httpSourceConfig.subscriptionsProtocol,
|
|
@@ -59,43 +67,63 @@ class GraphQLHandler {
|
|
|
59
67
|
});
|
|
60
68
|
};
|
|
61
69
|
}
|
|
70
|
+
getSchemaFromContent(sdlOrIntrospection) {
|
|
71
|
+
if (typeof sdlOrIntrospection === 'string') {
|
|
72
|
+
return (0, graphql_1.buildSchema)(sdlOrIntrospection, {
|
|
73
|
+
assumeValid: true,
|
|
74
|
+
assumeValidSDL: true,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
else if ((0, utils_2.isDocumentNode)(sdlOrIntrospection)) {
|
|
78
|
+
return (0, graphql_1.buildASTSchema)(sdlOrIntrospection, {
|
|
79
|
+
assumeValid: true,
|
|
80
|
+
assumeValidSDL: true,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
else if (sdlOrIntrospection.__schema) {
|
|
84
|
+
return (0, graphql_1.buildClientSchema)(sdlOrIntrospection, {
|
|
85
|
+
assumeValid: true,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
throw new Error(`Invalid introspection data: ${cross_helpers_1.util.inspect(sdlOrIntrospection)}`);
|
|
89
|
+
}
|
|
62
90
|
async getNonExecutableSchemaForHTTPSource(httpSourceConfig) {
|
|
63
91
|
this.interpolationStringSet.add(httpSourceConfig.endpoint);
|
|
64
92
|
Object.keys(httpSourceConfig.schemaHeaders || {}).forEach(headerName => {
|
|
65
93
|
this.interpolationStringSet.add(headerName.toString());
|
|
66
94
|
});
|
|
67
|
-
const schemaHeadersFactory =
|
|
68
|
-
if (httpSourceConfig.
|
|
69
|
-
const
|
|
70
|
-
env: crossHelpers.process.env,
|
|
71
|
-
});
|
|
72
|
-
const sdlOrIntrospection = await utils.readFileOrUrl(httpSourceConfig.introspection, {
|
|
95
|
+
const schemaHeadersFactory = (0, string_interpolation_1.getInterpolatedHeadersFactory)(httpSourceConfig.schemaHeaders || {});
|
|
96
|
+
if (httpSourceConfig.source) {
|
|
97
|
+
const opts = {
|
|
73
98
|
cwd: this.baseDir,
|
|
74
99
|
allowUnknownExtensions: true,
|
|
75
100
|
importFn: this.importFn,
|
|
76
101
|
fetch: this.fetchFn,
|
|
77
102
|
logger: this.logger,
|
|
103
|
+
};
|
|
104
|
+
if (!(0, utils_1.isUrl)(httpSourceConfig.source)) {
|
|
105
|
+
return this.nonExecutableSchema.getWithSet(async () => {
|
|
106
|
+
const sdlOrIntrospection = await (0, utils_1.readFile)(httpSourceConfig.source, opts);
|
|
107
|
+
return this.getSchemaFromContent(sdlOrIntrospection);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
const headers = schemaHeadersFactory({
|
|
111
|
+
env: cross_helpers_1.process.env,
|
|
112
|
+
});
|
|
113
|
+
const sdlOrIntrospection = await (0, utils_1.readUrl)(httpSourceConfig.source, {
|
|
114
|
+
...opts,
|
|
78
115
|
headers,
|
|
79
116
|
});
|
|
80
|
-
|
|
81
|
-
return graphql.buildSchema(sdlOrIntrospection);
|
|
82
|
-
}
|
|
83
|
-
else if (utils$1.isDocumentNode(sdlOrIntrospection)) {
|
|
84
|
-
return graphql.buildASTSchema(sdlOrIntrospection);
|
|
85
|
-
}
|
|
86
|
-
else if (sdlOrIntrospection.__schema) {
|
|
87
|
-
return graphql.buildClientSchema(sdlOrIntrospection);
|
|
88
|
-
}
|
|
89
|
-
throw new Error(`Invalid introspection data: ${crossHelpers.util.inspect(sdlOrIntrospection)}`);
|
|
117
|
+
return this.getSchemaFromContent(sdlOrIntrospection);
|
|
90
118
|
}
|
|
91
119
|
return this.nonExecutableSchema.getWithSet(() => {
|
|
92
|
-
const endpointFactory =
|
|
120
|
+
const endpointFactory = (0, string_interpolation_1.getInterpolatedStringFactory)(httpSourceConfig.endpoint);
|
|
93
121
|
const executor = this.urlLoader.getExecutorAsync(httpSourceConfig.endpoint, {
|
|
94
122
|
...httpSourceConfig,
|
|
95
123
|
customFetch: this.fetchFn,
|
|
96
124
|
subscriptionsProtocol: httpSourceConfig.subscriptionsProtocol,
|
|
97
125
|
});
|
|
98
|
-
return
|
|
126
|
+
return (0, wrap_1.schemaFromExecutor)(function meshIntrospectionExecutor(params) {
|
|
99
127
|
const resolverData = getResolverData(params);
|
|
100
128
|
return executor({
|
|
101
129
|
...params,
|
|
@@ -108,16 +136,19 @@ class GraphQLHandler {
|
|
|
108
136
|
});
|
|
109
137
|
});
|
|
110
138
|
}
|
|
111
|
-
async getCodeFirstSource({
|
|
139
|
+
async getCodeFirstSource({ source: schemaConfig, }) {
|
|
112
140
|
if (schemaConfig.endsWith('.graphql')) {
|
|
113
|
-
const rawSDL = await
|
|
141
|
+
const rawSDL = await (0, utils_1.readFileOrUrl)(schemaConfig, {
|
|
114
142
|
cwd: this.baseDir,
|
|
115
143
|
allowUnknownExtensions: true,
|
|
116
144
|
importFn: this.importFn,
|
|
117
145
|
fetch: this.fetchFn,
|
|
118
146
|
logger: this.logger,
|
|
119
147
|
});
|
|
120
|
-
const schema =
|
|
148
|
+
const schema = (0, graphql_1.buildSchema)(rawSDL, {
|
|
149
|
+
assumeValid: true,
|
|
150
|
+
assumeValidSDL: true,
|
|
151
|
+
});
|
|
121
152
|
const { contextVariables } = this.getArgsAndContextVariables();
|
|
122
153
|
return {
|
|
123
154
|
schema,
|
|
@@ -126,20 +157,26 @@ class GraphQLHandler {
|
|
|
126
157
|
}
|
|
127
158
|
else {
|
|
128
159
|
// Loaders logic should be here somehow
|
|
129
|
-
const schemaOrStringOrDocumentNode = await
|
|
160
|
+
const schemaOrStringOrDocumentNode = await (0, utils_1.loadFromModuleExportExpression)(schemaConfig, { cwd: this.baseDir, defaultExportName: 'schema', importFn: this.importFn });
|
|
130
161
|
let schema;
|
|
131
|
-
if (schemaOrStringOrDocumentNode instanceof
|
|
162
|
+
if (schemaOrStringOrDocumentNode instanceof graphql_1.GraphQLSchema) {
|
|
132
163
|
schema = schemaOrStringOrDocumentNode;
|
|
133
164
|
}
|
|
134
165
|
else if (typeof schemaOrStringOrDocumentNode === 'string') {
|
|
135
|
-
schema =
|
|
166
|
+
schema = (0, graphql_1.buildSchema)(schemaOrStringOrDocumentNode, {
|
|
167
|
+
assumeValid: true,
|
|
168
|
+
assumeValidSDL: true,
|
|
169
|
+
});
|
|
136
170
|
}
|
|
137
171
|
else if (typeof schemaOrStringOrDocumentNode === 'object' &&
|
|
138
|
-
(schemaOrStringOrDocumentNode === null || schemaOrStringOrDocumentNode === void 0 ? void 0 : schemaOrStringOrDocumentNode.kind) ===
|
|
139
|
-
schema =
|
|
172
|
+
(schemaOrStringOrDocumentNode === null || schemaOrStringOrDocumentNode === void 0 ? void 0 : schemaOrStringOrDocumentNode.kind) === graphql_1.Kind.DOCUMENT) {
|
|
173
|
+
schema = (0, graphql_1.buildASTSchema)(schemaOrStringOrDocumentNode, {
|
|
174
|
+
assumeValid: true,
|
|
175
|
+
assumeValidSDL: true,
|
|
176
|
+
});
|
|
140
177
|
}
|
|
141
178
|
else {
|
|
142
|
-
throw new Error(`Provided file '${schemaConfig} exports an unknown type: ${
|
|
179
|
+
throw new Error(`Provided file '${schemaConfig} exports an unknown type: ${cross_helpers_1.util.inspect(schemaOrStringOrDocumentNode)}': expected GraphQLSchema, SDL or DocumentNode.`);
|
|
143
180
|
}
|
|
144
181
|
const { contextVariables } = this.getArgsAndContextVariables();
|
|
145
182
|
return {
|
|
@@ -179,7 +216,8 @@ class GraphQLHandler {
|
|
|
179
216
|
throw error;
|
|
180
217
|
};
|
|
181
218
|
}
|
|
182
|
-
async getMeshSource() {
|
|
219
|
+
async getMeshSource({ fetchFn }) {
|
|
220
|
+
this.fetchFn = fetchFn;
|
|
183
221
|
if ('sources' in this.config) {
|
|
184
222
|
if (this.config.strategy === 'race') {
|
|
185
223
|
const schemaPromises = [];
|
|
@@ -192,7 +230,10 @@ class GraphQLHandler {
|
|
|
192
230
|
schemaPromises.push(this.getNonExecutableSchemaForHTTPSource(httpSourceConfig));
|
|
193
231
|
executorPromises.push(this.getExecutorForHTTPSourceConfig(httpSourceConfig));
|
|
194
232
|
}
|
|
195
|
-
const [schema, ...executors] = await Promise.all([
|
|
233
|
+
const [schema, ...executors] = await Promise.all([
|
|
234
|
+
Promise.race(schemaPromises),
|
|
235
|
+
...executorPromises,
|
|
236
|
+
]);
|
|
196
237
|
const executor = this.getRaceExecutor(executors);
|
|
197
238
|
const { contextVariables } = this.getArgsAndContextVariables();
|
|
198
239
|
return {
|
|
@@ -224,21 +265,21 @@ class GraphQLHandler {
|
|
|
224
265
|
throw error;
|
|
225
266
|
}
|
|
226
267
|
const executors = await Promise.all(executorPromises);
|
|
227
|
-
const parsedSelectionSet =
|
|
268
|
+
const parsedSelectionSet = (0, utils_2.parseSelectionSet)(this.config.strategyConfig.selectionSet);
|
|
228
269
|
const valuePath = this.config.strategyConfig.value;
|
|
229
270
|
const highestValueExecutor = async function highestValueExecutor(executionRequest) {
|
|
230
|
-
const operationAST =
|
|
271
|
+
const operationAST = (0, utils_2.getOperationASTFromRequest)(executionRequest);
|
|
231
272
|
operationAST.selectionSet.selections.push(...parsedSelectionSet.selections);
|
|
232
273
|
const results = await Promise.all(executors.map(executor => executor(executionRequest)));
|
|
233
274
|
let highestValue = -Infinity;
|
|
234
275
|
let resultWithHighestResult = results[0];
|
|
235
276
|
for (const result of results) {
|
|
236
|
-
if (
|
|
277
|
+
if ((0, utils_2.isAsyncIterable)(result)) {
|
|
237
278
|
console.warn('Incremental delivery is not supported currently');
|
|
238
279
|
return result;
|
|
239
280
|
}
|
|
240
281
|
else if (result.data != null) {
|
|
241
|
-
const currentValue =
|
|
282
|
+
const currentValue = (0, lodash_get_1.default)(result.data, valuePath);
|
|
242
283
|
if (currentValue > highestValue) {
|
|
243
284
|
resultWithHighestResult = result;
|
|
244
285
|
highestValue = currentValue;
|
|
@@ -250,7 +291,7 @@ class GraphQLHandler {
|
|
|
250
291
|
const { contextVariables } = this.getArgsAndContextVariables();
|
|
251
292
|
return {
|
|
252
293
|
schema,
|
|
253
|
-
executor: highestValueExecutor,
|
|
294
|
+
executor: this.wrapExecutorToPassSourceNameAndDebug(highestValueExecutor),
|
|
254
295
|
// Batching doesn't make sense with fallback strategy
|
|
255
296
|
batch: false,
|
|
256
297
|
contextVariables,
|
|
@@ -292,24 +333,26 @@ class GraphQLHandler {
|
|
|
292
333
|
this.getExecutorForHTTPSourceConfig(this.config),
|
|
293
334
|
]);
|
|
294
335
|
if (schemaResult.status === 'rejected') {
|
|
295
|
-
|
|
336
|
+
if (schemaResult.reason instanceof store_1.ValidationError) {
|
|
337
|
+
throw schemaResult.reason;
|
|
338
|
+
}
|
|
339
|
+
throw new Error(`Failed to fetch introspection from ${this.config.endpoint}: ${cross_helpers_1.util.inspect(schemaResult.reason)}`);
|
|
296
340
|
}
|
|
297
341
|
if (executorResult.status === 'rejected') {
|
|
298
|
-
throw new Error(`Failed to create executor for ${this.config.endpoint}: ${
|
|
342
|
+
throw new Error(`Failed to create executor for ${this.config.endpoint}: ${cross_helpers_1.util.inspect(executorResult.reason)}`);
|
|
299
343
|
}
|
|
300
344
|
const { contextVariables } = this.getArgsAndContextVariables();
|
|
301
345
|
return {
|
|
302
346
|
schema: schemaResult.value,
|
|
303
|
-
executor: executorResult.value,
|
|
347
|
+
executor: this.wrapExecutorToPassSourceNameAndDebug(executorResult.value),
|
|
304
348
|
batch: this.config.batch != null ? this.config.batch : true,
|
|
305
349
|
contextVariables,
|
|
306
350
|
};
|
|
307
351
|
}
|
|
308
|
-
else if ('
|
|
352
|
+
else if ('source' in this.config) {
|
|
309
353
|
return this.getCodeFirstSource(this.config);
|
|
310
354
|
}
|
|
311
|
-
throw new Error(`Unexpected config: ${
|
|
355
|
+
throw new Error(`Unexpected config: ${cross_helpers_1.util.inspect(this.config)}`);
|
|
312
356
|
}
|
|
313
357
|
}
|
|
314
|
-
|
|
315
|
-
module.exports = GraphQLHandler;
|
|
358
|
+
exports.default = GraphQLHandler;
|
package/cjs/package.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { buildSchema, buildASTSchema, buildClientSchema, GraphQLSchema, Kind } from 'graphql';
|
|
3
|
-
import { introspectSchema } from '@graphql-tools/wrap';
|
|
4
|
-
import { readFileOrUrl, loadFromModuleExportExpression } from '@graphql-mesh/utils';
|
|
5
|
-
import { isDocumentNode, parseSelectionSet, memoize1, getOperationASTFromRequest, isAsyncIterable } from '@graphql-tools/utils';
|
|
6
|
-
import { PredefinedProxyOptions } from '@graphql-mesh/store';
|
|
1
|
+
import { buildASTSchema, buildClientSchema, buildSchema, GraphQLSchema, Kind, print, } from 'graphql';
|
|
7
2
|
import lodashGet from 'lodash.get';
|
|
8
|
-
import { parseInterpolationStrings, getInterpolatedStringFactory, getInterpolatedHeadersFactory } from '@graphql-mesh/string-interpolation';
|
|
9
3
|
import { process, util } from '@graphql-mesh/cross-helpers';
|
|
10
|
-
|
|
4
|
+
import { PredefinedProxyOptions, ValidationError } from '@graphql-mesh/store';
|
|
5
|
+
import { getInterpolatedHeadersFactory, getInterpolatedStringFactory, parseInterpolationStrings, } from '@graphql-mesh/string-interpolation';
|
|
6
|
+
import { isUrl, loadFromModuleExportExpression, readFile, readFileOrUrl, readUrl, } from '@graphql-mesh/utils';
|
|
7
|
+
import { UrlLoader } from '@graphql-tools/url-loader';
|
|
8
|
+
import { getOperationASTFromRequest, isAsyncIterable, isDocumentNode, memoize1, parseSelectionSet, } from '@graphql-tools/utils';
|
|
9
|
+
import { schemaFromExecutor } from '@graphql-tools/wrap';
|
|
11
10
|
const getResolverData = memoize1(function getResolverData(params) {
|
|
12
11
|
return {
|
|
13
12
|
root: params.rootValue,
|
|
@@ -16,13 +15,13 @@ const getResolverData = memoize1(function getResolverData(params) {
|
|
|
16
15
|
env: process.env,
|
|
17
16
|
};
|
|
18
17
|
});
|
|
19
|
-
class GraphQLHandler {
|
|
20
|
-
constructor({ config, baseDir,
|
|
18
|
+
export default class GraphQLHandler {
|
|
19
|
+
constructor({ name, config, baseDir, store, importFn, logger, }) {
|
|
21
20
|
this.urlLoader = new UrlLoader();
|
|
22
21
|
this.interpolationStringSet = new Set();
|
|
22
|
+
this.name = name;
|
|
23
23
|
this.config = config;
|
|
24
24
|
this.baseDir = baseDir;
|
|
25
|
-
this.fetchFn = fetchFn;
|
|
26
25
|
this.nonExecutableSchema = store.proxy('introspectionSchema', PredefinedProxyOptions.GraphQLSchemaWithDiffing);
|
|
27
26
|
this.importFn = importFn;
|
|
28
27
|
this.logger = logger;
|
|
@@ -30,6 +29,16 @@ class GraphQLHandler {
|
|
|
30
29
|
getArgsAndContextVariables() {
|
|
31
30
|
return parseInterpolationStrings(this.interpolationStringSet);
|
|
32
31
|
}
|
|
32
|
+
wrapExecutorToPassSourceNameAndDebug(executor) {
|
|
33
|
+
const sourceName = this.name;
|
|
34
|
+
const logger = this.logger;
|
|
35
|
+
return function executorWithSourceName(executionRequest) {
|
|
36
|
+
logger.debug(() => `Sending GraphQL Request: `, print(executionRequest.document));
|
|
37
|
+
executionRequest.info = executionRequest.info || {};
|
|
38
|
+
executionRequest.info.sourceName = sourceName;
|
|
39
|
+
return executor(executionRequest);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
33
42
|
async getExecutorForHTTPSourceConfig(httpSourceConfig) {
|
|
34
43
|
const { endpoint, operationHeaders = {} } = httpSourceConfig;
|
|
35
44
|
this.interpolationStringSet.add(endpoint);
|
|
@@ -55,34 +64,54 @@ class GraphQLHandler {
|
|
|
55
64
|
});
|
|
56
65
|
};
|
|
57
66
|
}
|
|
67
|
+
getSchemaFromContent(sdlOrIntrospection) {
|
|
68
|
+
if (typeof sdlOrIntrospection === 'string') {
|
|
69
|
+
return buildSchema(sdlOrIntrospection, {
|
|
70
|
+
assumeValid: true,
|
|
71
|
+
assumeValidSDL: true,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
else if (isDocumentNode(sdlOrIntrospection)) {
|
|
75
|
+
return buildASTSchema(sdlOrIntrospection, {
|
|
76
|
+
assumeValid: true,
|
|
77
|
+
assumeValidSDL: true,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
else if (sdlOrIntrospection.__schema) {
|
|
81
|
+
return buildClientSchema(sdlOrIntrospection, {
|
|
82
|
+
assumeValid: true,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
throw new Error(`Invalid introspection data: ${util.inspect(sdlOrIntrospection)}`);
|
|
86
|
+
}
|
|
58
87
|
async getNonExecutableSchemaForHTTPSource(httpSourceConfig) {
|
|
59
88
|
this.interpolationStringSet.add(httpSourceConfig.endpoint);
|
|
60
89
|
Object.keys(httpSourceConfig.schemaHeaders || {}).forEach(headerName => {
|
|
61
90
|
this.interpolationStringSet.add(headerName.toString());
|
|
62
91
|
});
|
|
63
92
|
const schemaHeadersFactory = getInterpolatedHeadersFactory(httpSourceConfig.schemaHeaders || {});
|
|
64
|
-
if (httpSourceConfig.
|
|
65
|
-
const
|
|
66
|
-
env: process.env,
|
|
67
|
-
});
|
|
68
|
-
const sdlOrIntrospection = await readFileOrUrl(httpSourceConfig.introspection, {
|
|
93
|
+
if (httpSourceConfig.source) {
|
|
94
|
+
const opts = {
|
|
69
95
|
cwd: this.baseDir,
|
|
70
96
|
allowUnknownExtensions: true,
|
|
71
97
|
importFn: this.importFn,
|
|
72
98
|
fetch: this.fetchFn,
|
|
73
99
|
logger: this.logger,
|
|
100
|
+
};
|
|
101
|
+
if (!isUrl(httpSourceConfig.source)) {
|
|
102
|
+
return this.nonExecutableSchema.getWithSet(async () => {
|
|
103
|
+
const sdlOrIntrospection = await readFile(httpSourceConfig.source, opts);
|
|
104
|
+
return this.getSchemaFromContent(sdlOrIntrospection);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
const headers = schemaHeadersFactory({
|
|
108
|
+
env: process.env,
|
|
109
|
+
});
|
|
110
|
+
const sdlOrIntrospection = await readUrl(httpSourceConfig.source, {
|
|
111
|
+
...opts,
|
|
74
112
|
headers,
|
|
75
113
|
});
|
|
76
|
-
|
|
77
|
-
return buildSchema(sdlOrIntrospection);
|
|
78
|
-
}
|
|
79
|
-
else if (isDocumentNode(sdlOrIntrospection)) {
|
|
80
|
-
return buildASTSchema(sdlOrIntrospection);
|
|
81
|
-
}
|
|
82
|
-
else if (sdlOrIntrospection.__schema) {
|
|
83
|
-
return buildClientSchema(sdlOrIntrospection);
|
|
84
|
-
}
|
|
85
|
-
throw new Error(`Invalid introspection data: ${util.inspect(sdlOrIntrospection)}`);
|
|
114
|
+
return this.getSchemaFromContent(sdlOrIntrospection);
|
|
86
115
|
}
|
|
87
116
|
return this.nonExecutableSchema.getWithSet(() => {
|
|
88
117
|
const endpointFactory = getInterpolatedStringFactory(httpSourceConfig.endpoint);
|
|
@@ -91,7 +120,7 @@ class GraphQLHandler {
|
|
|
91
120
|
customFetch: this.fetchFn,
|
|
92
121
|
subscriptionsProtocol: httpSourceConfig.subscriptionsProtocol,
|
|
93
122
|
});
|
|
94
|
-
return
|
|
123
|
+
return schemaFromExecutor(function meshIntrospectionExecutor(params) {
|
|
95
124
|
const resolverData = getResolverData(params);
|
|
96
125
|
return executor({
|
|
97
126
|
...params,
|
|
@@ -104,7 +133,7 @@ class GraphQLHandler {
|
|
|
104
133
|
});
|
|
105
134
|
});
|
|
106
135
|
}
|
|
107
|
-
async getCodeFirstSource({
|
|
136
|
+
async getCodeFirstSource({ source: schemaConfig, }) {
|
|
108
137
|
if (schemaConfig.endsWith('.graphql')) {
|
|
109
138
|
const rawSDL = await readFileOrUrl(schemaConfig, {
|
|
110
139
|
cwd: this.baseDir,
|
|
@@ -113,7 +142,10 @@ class GraphQLHandler {
|
|
|
113
142
|
fetch: this.fetchFn,
|
|
114
143
|
logger: this.logger,
|
|
115
144
|
});
|
|
116
|
-
const schema = buildSchema(rawSDL
|
|
145
|
+
const schema = buildSchema(rawSDL, {
|
|
146
|
+
assumeValid: true,
|
|
147
|
+
assumeValidSDL: true,
|
|
148
|
+
});
|
|
117
149
|
const { contextVariables } = this.getArgsAndContextVariables();
|
|
118
150
|
return {
|
|
119
151
|
schema,
|
|
@@ -128,11 +160,17 @@ class GraphQLHandler {
|
|
|
128
160
|
schema = schemaOrStringOrDocumentNode;
|
|
129
161
|
}
|
|
130
162
|
else if (typeof schemaOrStringOrDocumentNode === 'string') {
|
|
131
|
-
schema = buildSchema(schemaOrStringOrDocumentNode
|
|
163
|
+
schema = buildSchema(schemaOrStringOrDocumentNode, {
|
|
164
|
+
assumeValid: true,
|
|
165
|
+
assumeValidSDL: true,
|
|
166
|
+
});
|
|
132
167
|
}
|
|
133
168
|
else if (typeof schemaOrStringOrDocumentNode === 'object' &&
|
|
134
169
|
(schemaOrStringOrDocumentNode === null || schemaOrStringOrDocumentNode === void 0 ? void 0 : schemaOrStringOrDocumentNode.kind) === Kind.DOCUMENT) {
|
|
135
|
-
schema = buildASTSchema(schemaOrStringOrDocumentNode
|
|
170
|
+
schema = buildASTSchema(schemaOrStringOrDocumentNode, {
|
|
171
|
+
assumeValid: true,
|
|
172
|
+
assumeValidSDL: true,
|
|
173
|
+
});
|
|
136
174
|
}
|
|
137
175
|
else {
|
|
138
176
|
throw new Error(`Provided file '${schemaConfig} exports an unknown type: ${util.inspect(schemaOrStringOrDocumentNode)}': expected GraphQLSchema, SDL or DocumentNode.`);
|
|
@@ -175,7 +213,8 @@ class GraphQLHandler {
|
|
|
175
213
|
throw error;
|
|
176
214
|
};
|
|
177
215
|
}
|
|
178
|
-
async getMeshSource() {
|
|
216
|
+
async getMeshSource({ fetchFn }) {
|
|
217
|
+
this.fetchFn = fetchFn;
|
|
179
218
|
if ('sources' in this.config) {
|
|
180
219
|
if (this.config.strategy === 'race') {
|
|
181
220
|
const schemaPromises = [];
|
|
@@ -188,7 +227,10 @@ class GraphQLHandler {
|
|
|
188
227
|
schemaPromises.push(this.getNonExecutableSchemaForHTTPSource(httpSourceConfig));
|
|
189
228
|
executorPromises.push(this.getExecutorForHTTPSourceConfig(httpSourceConfig));
|
|
190
229
|
}
|
|
191
|
-
const [schema, ...executors] = await Promise.all([
|
|
230
|
+
const [schema, ...executors] = await Promise.all([
|
|
231
|
+
Promise.race(schemaPromises),
|
|
232
|
+
...executorPromises,
|
|
233
|
+
]);
|
|
192
234
|
const executor = this.getRaceExecutor(executors);
|
|
193
235
|
const { contextVariables } = this.getArgsAndContextVariables();
|
|
194
236
|
return {
|
|
@@ -246,7 +288,7 @@ class GraphQLHandler {
|
|
|
246
288
|
const { contextVariables } = this.getArgsAndContextVariables();
|
|
247
289
|
return {
|
|
248
290
|
schema,
|
|
249
|
-
executor: highestValueExecutor,
|
|
291
|
+
executor: this.wrapExecutorToPassSourceNameAndDebug(highestValueExecutor),
|
|
250
292
|
// Batching doesn't make sense with fallback strategy
|
|
251
293
|
batch: false,
|
|
252
294
|
contextVariables,
|
|
@@ -288,6 +330,9 @@ class GraphQLHandler {
|
|
|
288
330
|
this.getExecutorForHTTPSourceConfig(this.config),
|
|
289
331
|
]);
|
|
290
332
|
if (schemaResult.status === 'rejected') {
|
|
333
|
+
if (schemaResult.reason instanceof ValidationError) {
|
|
334
|
+
throw schemaResult.reason;
|
|
335
|
+
}
|
|
291
336
|
throw new Error(`Failed to fetch introspection from ${this.config.endpoint}: ${util.inspect(schemaResult.reason)}`);
|
|
292
337
|
}
|
|
293
338
|
if (executorResult.status === 'rejected') {
|
|
@@ -296,16 +341,14 @@ class GraphQLHandler {
|
|
|
296
341
|
const { contextVariables } = this.getArgsAndContextVariables();
|
|
297
342
|
return {
|
|
298
343
|
schema: schemaResult.value,
|
|
299
|
-
executor: executorResult.value,
|
|
344
|
+
executor: this.wrapExecutorToPassSourceNameAndDebug(executorResult.value),
|
|
300
345
|
batch: this.config.batch != null ? this.config.batch : true,
|
|
301
346
|
contextVariables,
|
|
302
347
|
};
|
|
303
348
|
}
|
|
304
|
-
else if ('
|
|
349
|
+
else if ('source' in this.config) {
|
|
305
350
|
return this.getCodeFirstSource(this.config);
|
|
306
351
|
}
|
|
307
352
|
throw new Error(`Unexpected config: ${util.inspect(this.config)}`);
|
|
308
353
|
}
|
|
309
354
|
}
|
|
310
|
-
|
|
311
|
-
export default GraphQLHandler;
|
package/package.json
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphql-mesh/graphql",
|
|
3
|
-
"version": "1.0.0-alpha-
|
|
3
|
+
"version": "1.0.0-alpha-20230420181317-a95037648",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"peerDependencies": {
|
|
6
|
-
"@graphql-mesh/
|
|
7
|
-
"@graphql-mesh/
|
|
8
|
-
"graphql": "
|
|
6
|
+
"@graphql-mesh/cross-helpers": "^0.3.4",
|
|
7
|
+
"@graphql-mesh/store": "1.0.0-alpha-20230420181317-a95037648",
|
|
8
|
+
"@graphql-mesh/types": "1.0.0-alpha-20230420181317-a95037648",
|
|
9
|
+
"@graphql-mesh/utils": "1.0.0-alpha-20230420181317-a95037648",
|
|
10
|
+
"@graphql-tools/utils": "^9.2.1",
|
|
11
|
+
"graphql": "*",
|
|
12
|
+
"tslib": "^2.4.0"
|
|
9
13
|
},
|
|
10
14
|
"dependencies": {
|
|
11
|
-
"@graphql-mesh/
|
|
12
|
-
"@graphql-
|
|
13
|
-
"@graphql-
|
|
14
|
-
"@graphql-tools/
|
|
15
|
-
"
|
|
16
|
-
"@graphql-tools/utils": "8.8.0",
|
|
17
|
-
"@graphql-tools/wrap": "8.5.0",
|
|
18
|
-
"lodash.get": "4.4.2",
|
|
19
|
-
"tslib": "^2.4.0"
|
|
15
|
+
"@graphql-mesh/string-interpolation": "0.4.4",
|
|
16
|
+
"@graphql-tools/delegate": "9.0.32",
|
|
17
|
+
"@graphql-tools/url-loader": "7.17.18",
|
|
18
|
+
"@graphql-tools/wrap": "9.4.2",
|
|
19
|
+
"lodash.get": "4.4.2"
|
|
20
20
|
},
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|
|
@@ -24,21 +24,28 @@
|
|
|
24
24
|
"directory": "packages/handlers/graphql"
|
|
25
25
|
},
|
|
26
26
|
"license": "MIT",
|
|
27
|
-
"main": "index.js",
|
|
28
|
-
"module": "index.
|
|
29
|
-
"typings": "index.d.ts",
|
|
27
|
+
"main": "cjs/index.js",
|
|
28
|
+
"module": "esm/index.js",
|
|
29
|
+
"typings": "typings/index.d.ts",
|
|
30
30
|
"typescript": {
|
|
31
|
-
"definition": "index.d.ts"
|
|
31
|
+
"definition": "typings/index.d.ts"
|
|
32
32
|
},
|
|
33
|
+
"type": "module",
|
|
33
34
|
"exports": {
|
|
34
35
|
".": {
|
|
35
|
-
"require":
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"
|
|
40
|
-
|
|
36
|
+
"require": {
|
|
37
|
+
"types": "./typings/index.d.cts",
|
|
38
|
+
"default": "./cjs/index.js"
|
|
39
|
+
},
|
|
40
|
+
"import": {
|
|
41
|
+
"types": "./typings/index.d.ts",
|
|
42
|
+
"default": "./esm/index.js"
|
|
43
|
+
},
|
|
44
|
+
"default": {
|
|
45
|
+
"types": "./typings/index.d.ts",
|
|
46
|
+
"default": "./esm/index.js"
|
|
47
|
+
}
|
|
41
48
|
},
|
|
42
49
|
"./package.json": "./package.json"
|
|
43
50
|
}
|
|
44
|
-
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { GraphQLSchema } from 'graphql';
|
|
2
|
+
import { GetMeshSourcePayload, MeshHandler, MeshHandlerOptions, MeshSource, YamlConfig } from '@graphql-mesh/types';
|
|
3
|
+
export default class GraphQLHandler implements MeshHandler {
|
|
4
|
+
private name;
|
|
5
|
+
private config;
|
|
6
|
+
private baseDir;
|
|
7
|
+
private nonExecutableSchema;
|
|
8
|
+
private importFn;
|
|
9
|
+
private fetchFn;
|
|
10
|
+
private logger;
|
|
11
|
+
private urlLoader;
|
|
12
|
+
constructor({ name, config, baseDir, store, importFn, logger, }: MeshHandlerOptions<YamlConfig.Handler['graphql']>);
|
|
13
|
+
private interpolationStringSet;
|
|
14
|
+
private getArgsAndContextVariables;
|
|
15
|
+
private wrapExecutorToPassSourceNameAndDebug;
|
|
16
|
+
getExecutorForHTTPSourceConfig(httpSourceConfig: YamlConfig.GraphQLHandlerHTTPConfiguration): Promise<MeshSource['executor']>;
|
|
17
|
+
private getSchemaFromContent;
|
|
18
|
+
getNonExecutableSchemaForHTTPSource(httpSourceConfig: YamlConfig.GraphQLHandlerHTTPConfiguration): Promise<GraphQLSchema>;
|
|
19
|
+
getCodeFirstSource({ source: schemaConfig, }: YamlConfig.GraphQLHandlerCodeFirstConfiguration): Promise<MeshSource>;
|
|
20
|
+
getRaceExecutor(executors: MeshSource['executor'][]): MeshSource['executor'];
|
|
21
|
+
getFallbackExecutor(executors: MeshSource['executor'][]): MeshSource['executor'];
|
|
22
|
+
getMeshSource({ fetchFn }: GetMeshSourcePayload): Promise<MeshSource>;
|
|
23
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { GetMeshSourceOptions, MeshHandler, MeshSource, YamlConfig } from '@graphql-mesh/types';
|
|
2
1
|
import { GraphQLSchema } from 'graphql';
|
|
2
|
+
import { GetMeshSourcePayload, MeshHandler, MeshHandlerOptions, MeshSource, YamlConfig } from '@graphql-mesh/types';
|
|
3
3
|
export default class GraphQLHandler implements MeshHandler {
|
|
4
|
+
private name;
|
|
4
5
|
private config;
|
|
5
6
|
private baseDir;
|
|
6
7
|
private nonExecutableSchema;
|
|
@@ -8,13 +9,15 @@ export default class GraphQLHandler implements MeshHandler {
|
|
|
8
9
|
private fetchFn;
|
|
9
10
|
private logger;
|
|
10
11
|
private urlLoader;
|
|
11
|
-
constructor({ config, baseDir,
|
|
12
|
+
constructor({ name, config, baseDir, store, importFn, logger, }: MeshHandlerOptions<YamlConfig.Handler['graphql']>);
|
|
12
13
|
private interpolationStringSet;
|
|
13
14
|
private getArgsAndContextVariables;
|
|
15
|
+
private wrapExecutorToPassSourceNameAndDebug;
|
|
14
16
|
getExecutorForHTTPSourceConfig(httpSourceConfig: YamlConfig.GraphQLHandlerHTTPConfiguration): Promise<MeshSource['executor']>;
|
|
17
|
+
private getSchemaFromContent;
|
|
15
18
|
getNonExecutableSchemaForHTTPSource(httpSourceConfig: YamlConfig.GraphQLHandlerHTTPConfiguration): Promise<GraphQLSchema>;
|
|
16
|
-
getCodeFirstSource({
|
|
19
|
+
getCodeFirstSource({ source: schemaConfig, }: YamlConfig.GraphQLHandlerCodeFirstConfiguration): Promise<MeshSource>;
|
|
17
20
|
getRaceExecutor(executors: MeshSource['executor'][]): MeshSource['executor'];
|
|
18
21
|
getFallbackExecutor(executors: MeshSource['executor'][]): MeshSource['executor'];
|
|
19
|
-
getMeshSource(): Promise<MeshSource>;
|
|
22
|
+
getMeshSource({ fetchFn }: GetMeshSourcePayload): Promise<MeshSource>;
|
|
20
23
|
}
|