@envelop/core 2.4.0-alpha-aca44e1.0 → 2.4.0-alpha-e9434aa.0
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/cjs/create.js +28 -0
- package/cjs/enable-if.js +24 -0
- package/cjs/index.js +16 -0
- package/cjs/orchestrator.js +451 -0
- package/cjs/package.json +1 -0
- package/cjs/plugins/use-envelop.js +13 -0
- package/cjs/plugins/use-error-handler.js +21 -0
- package/cjs/plugins/use-extend-context.js +9 -0
- package/cjs/plugins/use-immediate-introspection.js +50 -0
- package/cjs/plugins/use-logger.js +45 -0
- package/cjs/plugins/use-masked-errors.js +90 -0
- package/cjs/plugins/use-payload-formatter.js +21 -0
- package/cjs/plugins/use-schema.js +29 -0
- package/cjs/plugins/use-timing.js +138 -0
- package/cjs/traced-orchestrator.js +134 -0
- package/cjs/traced-schema.js +68 -0
- package/cjs/utils.js +221 -0
- package/esm/create.js +28 -0
- package/esm/enable-if.js +24 -0
- package/esm/index.js +29 -0
- package/esm/orchestrator.js +451 -0
- package/esm/plugins/use-envelop.js +13 -0
- package/esm/plugins/use-error-handler.js +21 -0
- package/esm/plugins/use-extend-context.js +9 -0
- package/esm/plugins/use-immediate-introspection.js +50 -0
- package/esm/plugins/use-logger.js +45 -0
- package/esm/plugins/use-masked-errors.js +90 -0
- package/esm/plugins/use-payload-formatter.js +21 -0
- package/esm/plugins/use-schema.js +29 -0
- package/esm/plugins/use-timing.js +138 -0
- package/esm/traced-orchestrator.js +134 -0
- package/esm/traced-schema.js +68 -0
- package/esm/utils.js +221 -0
- package/package.json +33 -12
- package/{create.d.ts → typings/create.d.ts} +1 -1
- package/{enable-if.d.ts → typings/enable-if.d.ts} +0 -0
- package/typings/index.d.ts +13 -0
- package/{orchestrator.d.ts → typings/orchestrator.d.ts} +0 -0
- package/{plugins → typings/plugins}/use-envelop.d.ts +0 -0
- package/{plugins → typings/plugins}/use-error-handler.d.ts +0 -0
- package/{plugins → typings/plugins}/use-extend-context.d.ts +0 -0
- package/{plugins → typings/plugins}/use-immediate-introspection.d.ts +0 -0
- package/{plugins → typings/plugins}/use-logger.d.ts +1 -1
- package/{plugins → typings/plugins}/use-masked-errors.d.ts +3 -3
- package/{plugins → typings/plugins}/use-payload-formatter.d.ts +0 -0
- package/{plugins → typings/plugins}/use-schema.d.ts +0 -0
- package/{plugins → typings/plugins}/use-timing.d.ts +2 -2
- package/{traced-orchestrator.d.ts → typings/traced-orchestrator.d.ts} +1 -1
- package/{traced-schema.d.ts → typings/traced-schema.d.ts} +0 -0
- package/{utils.d.ts → typings/utils.d.ts} +0 -13
- package/README.md +0 -15
- package/index.d.ts +0 -13
- package/index.js +0 -1359
- package/index.mjs +0 -1317
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createEnvelopOrchestrator = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const traced_schema_js_1 = require("./traced-schema.js");
|
|
6
|
+
const utils_js_1 = require("./utils.js");
|
|
7
|
+
function createEnvelopOrchestrator(plugins) {
|
|
8
|
+
let schema = null;
|
|
9
|
+
let initDone = false;
|
|
10
|
+
const onResolversHandlers = [];
|
|
11
|
+
for (const plugin of plugins) {
|
|
12
|
+
if (plugin.onResolverCalled) {
|
|
13
|
+
onResolversHandlers.push(plugin.onResolverCalled);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
// Define the initial method for replacing the GraphQL schema, this is needed in order
|
|
17
|
+
// to allow setting the schema from the onPluginInit callback. We also need to make sure
|
|
18
|
+
// here not to call the same plugin that initiated the schema switch.
|
|
19
|
+
const replaceSchema = (newSchema, ignorePluginIndex = -1) => {
|
|
20
|
+
if (onResolversHandlers.length) {
|
|
21
|
+
(0, traced_schema_js_1.prepareTracedSchema)(newSchema);
|
|
22
|
+
}
|
|
23
|
+
schema = newSchema;
|
|
24
|
+
if (initDone) {
|
|
25
|
+
for (const [i, plugin] of plugins.entries()) {
|
|
26
|
+
if (i !== ignorePluginIndex) {
|
|
27
|
+
plugin.onSchemaChange &&
|
|
28
|
+
plugin.onSchemaChange({
|
|
29
|
+
schema,
|
|
30
|
+
replaceSchema: schemaToSet => {
|
|
31
|
+
replaceSchema(schemaToSet, i);
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const contextErrorHandlers = [];
|
|
39
|
+
// Iterate all plugins and trigger onPluginInit
|
|
40
|
+
for (const [i, plugin] of plugins.entries()) {
|
|
41
|
+
plugin.onPluginInit &&
|
|
42
|
+
plugin.onPluginInit({
|
|
43
|
+
plugins,
|
|
44
|
+
addPlugin: newPlugin => {
|
|
45
|
+
plugins.push(newPlugin);
|
|
46
|
+
},
|
|
47
|
+
setSchema: modifiedSchema => replaceSchema(modifiedSchema, i),
|
|
48
|
+
registerContextErrorHandler: handler => contextErrorHandlers.push(handler),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
// A set of before callbacks defined here in order to allow it to be used later
|
|
52
|
+
const beforeCallbacks = {
|
|
53
|
+
init: [],
|
|
54
|
+
parse: [],
|
|
55
|
+
validate: [],
|
|
56
|
+
subscribe: [],
|
|
57
|
+
execute: [],
|
|
58
|
+
context: [],
|
|
59
|
+
};
|
|
60
|
+
for (const { onContextBuilding, onExecute, onParse, onSubscribe, onValidate, onEnveloped } of plugins) {
|
|
61
|
+
onEnveloped && beforeCallbacks.init.push(onEnveloped);
|
|
62
|
+
onContextBuilding && beforeCallbacks.context.push(onContextBuilding);
|
|
63
|
+
onExecute && beforeCallbacks.execute.push(onExecute);
|
|
64
|
+
onParse && beforeCallbacks.parse.push(onParse);
|
|
65
|
+
onSubscribe && beforeCallbacks.subscribe.push(onSubscribe);
|
|
66
|
+
onValidate && beforeCallbacks.validate.push(onValidate);
|
|
67
|
+
}
|
|
68
|
+
const init = initialContext => {
|
|
69
|
+
for (const [i, onEnveloped] of beforeCallbacks.init.entries()) {
|
|
70
|
+
onEnveloped({
|
|
71
|
+
context: initialContext,
|
|
72
|
+
extendContext: extension => {
|
|
73
|
+
if (!initialContext) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
Object.assign(initialContext, extension);
|
|
77
|
+
},
|
|
78
|
+
setSchema: modifiedSchema => replaceSchema(modifiedSchema, i),
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
const customParse = beforeCallbacks.parse.length
|
|
83
|
+
? initialContext => (source, parseOptions) => {
|
|
84
|
+
let result = null;
|
|
85
|
+
let parseFn = graphql_1.parse;
|
|
86
|
+
const context = initialContext;
|
|
87
|
+
const afterCalls = [];
|
|
88
|
+
for (const onParse of beforeCallbacks.parse) {
|
|
89
|
+
const afterFn = onParse({
|
|
90
|
+
context,
|
|
91
|
+
extendContext: extension => {
|
|
92
|
+
Object.assign(context, extension);
|
|
93
|
+
},
|
|
94
|
+
params: { source, options: parseOptions },
|
|
95
|
+
parseFn,
|
|
96
|
+
setParseFn: newFn => {
|
|
97
|
+
parseFn = newFn;
|
|
98
|
+
},
|
|
99
|
+
setParsedDocument: newDoc => {
|
|
100
|
+
result = newDoc;
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
afterFn && afterCalls.push(afterFn);
|
|
104
|
+
}
|
|
105
|
+
if (result === null) {
|
|
106
|
+
try {
|
|
107
|
+
result = parseFn(source, parseOptions);
|
|
108
|
+
}
|
|
109
|
+
catch (e) {
|
|
110
|
+
result = e;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
for (const afterCb of afterCalls) {
|
|
114
|
+
afterCb({
|
|
115
|
+
context,
|
|
116
|
+
extendContext: extension => {
|
|
117
|
+
Object.assign(context, extension);
|
|
118
|
+
},
|
|
119
|
+
replaceParseResult: newResult => {
|
|
120
|
+
result = newResult;
|
|
121
|
+
},
|
|
122
|
+
result,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
if (result === null) {
|
|
126
|
+
throw new Error(`Failed to parse document.`);
|
|
127
|
+
}
|
|
128
|
+
if (result instanceof Error) {
|
|
129
|
+
throw result;
|
|
130
|
+
}
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
: () => graphql_1.parse;
|
|
134
|
+
const customValidate = beforeCallbacks.validate.length
|
|
135
|
+
? initialContext => (schema, documentAST, rules, typeInfo, validationOptions) => {
|
|
136
|
+
let actualRules = rules ? [...rules] : undefined;
|
|
137
|
+
let validateFn = graphql_1.validate;
|
|
138
|
+
let result = null;
|
|
139
|
+
const context = initialContext;
|
|
140
|
+
const afterCalls = [];
|
|
141
|
+
for (const onValidate of beforeCallbacks.validate) {
|
|
142
|
+
const afterFn = onValidate({
|
|
143
|
+
context,
|
|
144
|
+
extendContext: extension => {
|
|
145
|
+
Object.assign(context, extension);
|
|
146
|
+
},
|
|
147
|
+
params: {
|
|
148
|
+
schema,
|
|
149
|
+
documentAST,
|
|
150
|
+
rules: actualRules,
|
|
151
|
+
typeInfo,
|
|
152
|
+
options: validationOptions,
|
|
153
|
+
},
|
|
154
|
+
validateFn,
|
|
155
|
+
addValidationRule: rule => {
|
|
156
|
+
if (!actualRules) {
|
|
157
|
+
actualRules = [...graphql_1.specifiedRules];
|
|
158
|
+
}
|
|
159
|
+
actualRules.push(rule);
|
|
160
|
+
},
|
|
161
|
+
setValidationFn: newFn => {
|
|
162
|
+
validateFn = newFn;
|
|
163
|
+
},
|
|
164
|
+
setResult: newResults => {
|
|
165
|
+
result = newResults;
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
afterFn && afterCalls.push(afterFn);
|
|
169
|
+
}
|
|
170
|
+
if (!result) {
|
|
171
|
+
result = validateFn(schema, documentAST, actualRules, typeInfo, validationOptions);
|
|
172
|
+
}
|
|
173
|
+
const valid = result.length === 0;
|
|
174
|
+
for (const afterCb of afterCalls) {
|
|
175
|
+
afterCb({
|
|
176
|
+
valid,
|
|
177
|
+
result,
|
|
178
|
+
context,
|
|
179
|
+
extendContext: extension => {
|
|
180
|
+
Object.assign(context, extension);
|
|
181
|
+
},
|
|
182
|
+
setResult: newResult => {
|
|
183
|
+
result = newResult;
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
return result;
|
|
188
|
+
}
|
|
189
|
+
: () => graphql_1.validate;
|
|
190
|
+
const customContextFactory = beforeCallbacks.context.length
|
|
191
|
+
? initialContext => async (orchestratorCtx) => {
|
|
192
|
+
const afterCalls = [];
|
|
193
|
+
// In order to have access to the "last working" context object we keep this outside of the try block:
|
|
194
|
+
let context = orchestratorCtx ? { ...initialContext, ...orchestratorCtx } : initialContext;
|
|
195
|
+
try {
|
|
196
|
+
let isBreakingContextBuilding = false;
|
|
197
|
+
for (const onContext of beforeCallbacks.context) {
|
|
198
|
+
const afterHookResult = await onContext({
|
|
199
|
+
context,
|
|
200
|
+
extendContext: extension => {
|
|
201
|
+
context = { ...context, ...extension };
|
|
202
|
+
},
|
|
203
|
+
breakContextBuilding: () => {
|
|
204
|
+
isBreakingContextBuilding = true;
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
if (typeof afterHookResult === 'function') {
|
|
208
|
+
afterCalls.push(afterHookResult);
|
|
209
|
+
}
|
|
210
|
+
if (isBreakingContextBuilding === true) {
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
for (const afterCb of afterCalls) {
|
|
215
|
+
afterCb({
|
|
216
|
+
context,
|
|
217
|
+
extendContext: extension => {
|
|
218
|
+
context = { ...context, ...extension };
|
|
219
|
+
},
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
return context;
|
|
223
|
+
}
|
|
224
|
+
catch (err) {
|
|
225
|
+
let error = err;
|
|
226
|
+
for (const errorCb of contextErrorHandlers) {
|
|
227
|
+
errorCb({
|
|
228
|
+
context,
|
|
229
|
+
error,
|
|
230
|
+
setError: err => {
|
|
231
|
+
error = err;
|
|
232
|
+
},
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
: initialContext => orchestratorCtx => orchestratorCtx ? { ...initialContext, ...orchestratorCtx } : initialContext;
|
|
239
|
+
const useCustomSubscribe = beforeCallbacks.subscribe.length || onResolversHandlers.length;
|
|
240
|
+
const customSubscribe = useCustomSubscribe
|
|
241
|
+
? (0, utils_js_1.makeSubscribe)(async (args) => {
|
|
242
|
+
let subscribeFn = graphql_1.subscribe;
|
|
243
|
+
const afterCalls = [];
|
|
244
|
+
const subscribeErrorHandlers = [];
|
|
245
|
+
let context = args.contextValue || {};
|
|
246
|
+
let result;
|
|
247
|
+
for (const onSubscribe of beforeCallbacks.subscribe) {
|
|
248
|
+
const after = await onSubscribe({
|
|
249
|
+
subscribeFn,
|
|
250
|
+
setSubscribeFn: newSubscribeFn => {
|
|
251
|
+
subscribeFn = newSubscribeFn;
|
|
252
|
+
},
|
|
253
|
+
extendContext: extension => {
|
|
254
|
+
context = { ...context, ...extension };
|
|
255
|
+
},
|
|
256
|
+
args: args,
|
|
257
|
+
setResultAndStopExecution: stopResult => {
|
|
258
|
+
result = stopResult;
|
|
259
|
+
},
|
|
260
|
+
});
|
|
261
|
+
if (after) {
|
|
262
|
+
if (after.onSubscribeResult) {
|
|
263
|
+
afterCalls.push(after.onSubscribeResult);
|
|
264
|
+
}
|
|
265
|
+
if (after.onSubscribeError) {
|
|
266
|
+
subscribeErrorHandlers.push(after.onSubscribeError);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (result !== undefined) {
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (onResolversHandlers.length) {
|
|
274
|
+
context[traced_schema_js_1.resolversHooksSymbol] = onResolversHandlers;
|
|
275
|
+
}
|
|
276
|
+
if (result === undefined) {
|
|
277
|
+
result = await subscribeFn({
|
|
278
|
+
...args,
|
|
279
|
+
contextValue: context,
|
|
280
|
+
// Casted for GraphQL.js 15 compatibility
|
|
281
|
+
// Can be removed once we drop support for GraphQL.js 15
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
const onNextHandler = [];
|
|
285
|
+
const onEndHandler = [];
|
|
286
|
+
for (const afterCb of afterCalls) {
|
|
287
|
+
const hookResult = afterCb({
|
|
288
|
+
args: args,
|
|
289
|
+
result,
|
|
290
|
+
setResult: newResult => {
|
|
291
|
+
result = newResult;
|
|
292
|
+
},
|
|
293
|
+
});
|
|
294
|
+
if (hookResult) {
|
|
295
|
+
if (hookResult.onNext) {
|
|
296
|
+
onNextHandler.push(hookResult.onNext);
|
|
297
|
+
}
|
|
298
|
+
if (hookResult.onEnd) {
|
|
299
|
+
onEndHandler.push(hookResult.onEnd);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
if (onNextHandler.length && (0, utils_js_1.isAsyncIterable)(result)) {
|
|
304
|
+
result = (0, utils_js_1.mapAsyncIterator)(result, async (result) => {
|
|
305
|
+
for (const onNext of onNextHandler) {
|
|
306
|
+
await onNext({
|
|
307
|
+
args: args,
|
|
308
|
+
result,
|
|
309
|
+
setResult: newResult => (result = newResult),
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
return result;
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
if (onEndHandler.length && (0, utils_js_1.isAsyncIterable)(result)) {
|
|
316
|
+
result = (0, utils_js_1.finalAsyncIterator)(result, () => {
|
|
317
|
+
for (const onEnd of onEndHandler) {
|
|
318
|
+
onEnd();
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
if (subscribeErrorHandlers.length && (0, utils_js_1.isAsyncIterable)(result)) {
|
|
323
|
+
result = (0, utils_js_1.errorAsyncIterator)(result, err => {
|
|
324
|
+
let error = err;
|
|
325
|
+
for (const handler of subscribeErrorHandlers) {
|
|
326
|
+
handler({
|
|
327
|
+
error,
|
|
328
|
+
setError: err => {
|
|
329
|
+
error = err;
|
|
330
|
+
},
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
throw error;
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
return result;
|
|
337
|
+
})
|
|
338
|
+
: (0, utils_js_1.makeSubscribe)(graphql_1.subscribe);
|
|
339
|
+
const useCustomExecute = beforeCallbacks.execute.length || onResolversHandlers.length;
|
|
340
|
+
const customExecute = useCustomExecute
|
|
341
|
+
? (0, utils_js_1.makeExecute)(async (args) => {
|
|
342
|
+
let executeFn = graphql_1.execute;
|
|
343
|
+
let result;
|
|
344
|
+
const afterCalls = [];
|
|
345
|
+
let context = args.contextValue || {};
|
|
346
|
+
for (const onExecute of beforeCallbacks.execute) {
|
|
347
|
+
const after = await onExecute({
|
|
348
|
+
executeFn,
|
|
349
|
+
setExecuteFn: newExecuteFn => {
|
|
350
|
+
executeFn = newExecuteFn;
|
|
351
|
+
},
|
|
352
|
+
setResultAndStopExecution: stopResult => {
|
|
353
|
+
result = stopResult;
|
|
354
|
+
},
|
|
355
|
+
extendContext: extension => {
|
|
356
|
+
if (typeof extension === 'object') {
|
|
357
|
+
context = {
|
|
358
|
+
...(context || {}),
|
|
359
|
+
...extension,
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
throw new Error(`Invalid context extension provided! Expected "object", got: "${JSON.stringify(extension)}" (${typeof extension})`);
|
|
364
|
+
}
|
|
365
|
+
},
|
|
366
|
+
args: args,
|
|
367
|
+
});
|
|
368
|
+
if (after === null || after === void 0 ? void 0 : after.onExecuteDone) {
|
|
369
|
+
afterCalls.push(after.onExecuteDone);
|
|
370
|
+
}
|
|
371
|
+
if (result !== undefined) {
|
|
372
|
+
break;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
if (onResolversHandlers.length) {
|
|
376
|
+
context[traced_schema_js_1.resolversHooksSymbol] = onResolversHandlers;
|
|
377
|
+
}
|
|
378
|
+
if (result === undefined) {
|
|
379
|
+
result = (await executeFn({
|
|
380
|
+
...args,
|
|
381
|
+
contextValue: context,
|
|
382
|
+
}));
|
|
383
|
+
}
|
|
384
|
+
const onNextHandler = [];
|
|
385
|
+
const onEndHandler = [];
|
|
386
|
+
for (const afterCb of afterCalls) {
|
|
387
|
+
const hookResult = await afterCb({
|
|
388
|
+
args: args,
|
|
389
|
+
result,
|
|
390
|
+
setResult: newResult => {
|
|
391
|
+
result = newResult;
|
|
392
|
+
},
|
|
393
|
+
});
|
|
394
|
+
if (hookResult) {
|
|
395
|
+
if (hookResult.onNext) {
|
|
396
|
+
onNextHandler.push(hookResult.onNext);
|
|
397
|
+
}
|
|
398
|
+
if (hookResult.onEnd) {
|
|
399
|
+
onEndHandler.push(hookResult.onEnd);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (onNextHandler.length && (0, utils_js_1.isAsyncIterable)(result)) {
|
|
404
|
+
result = (0, utils_js_1.mapAsyncIterator)(result, async (result) => {
|
|
405
|
+
for (const onNext of onNextHandler) {
|
|
406
|
+
await onNext({
|
|
407
|
+
args: args,
|
|
408
|
+
result,
|
|
409
|
+
setResult: newResult => {
|
|
410
|
+
result = newResult;
|
|
411
|
+
},
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
return result;
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
if (onEndHandler.length && (0, utils_js_1.isAsyncIterable)(result)) {
|
|
418
|
+
result = (0, utils_js_1.finalAsyncIterator)(result, () => {
|
|
419
|
+
for (const onEnd of onEndHandler) {
|
|
420
|
+
onEnd();
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
return result;
|
|
425
|
+
})
|
|
426
|
+
: (0, utils_js_1.makeExecute)(graphql_1.execute);
|
|
427
|
+
initDone = true;
|
|
428
|
+
// This is done in order to trigger the first schema available, to allow plugins that needs the schema
|
|
429
|
+
// eagerly to have it.
|
|
430
|
+
if (schema) {
|
|
431
|
+
for (const [i, plugin] of plugins.entries()) {
|
|
432
|
+
plugin.onSchemaChange &&
|
|
433
|
+
plugin.onSchemaChange({
|
|
434
|
+
schema,
|
|
435
|
+
replaceSchema: modifiedSchema => replaceSchema(modifiedSchema, i),
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
return {
|
|
440
|
+
getCurrentSchema() {
|
|
441
|
+
return schema;
|
|
442
|
+
},
|
|
443
|
+
init,
|
|
444
|
+
parse: customParse,
|
|
445
|
+
validate: customValidate,
|
|
446
|
+
execute: customExecute,
|
|
447
|
+
subscribe: customSubscribe,
|
|
448
|
+
contextFactory: customContextFactory,
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
exports.createEnvelopOrchestrator = createEnvelopOrchestrator;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useEnvelop = void 0;
|
|
4
|
+
const useEnvelop = (envelop) => {
|
|
5
|
+
return {
|
|
6
|
+
onPluginInit({ addPlugin }) {
|
|
7
|
+
for (const plugin of envelop._plugins) {
|
|
8
|
+
addPlugin(plugin);
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
exports.useEnvelop = useEnvelop;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useErrorHandler = void 0;
|
|
4
|
+
const utils_js_1 = require("../utils.js");
|
|
5
|
+
const makeHandleResult = (errorHandler) => ({ result, args }) => {
|
|
6
|
+
var _a;
|
|
7
|
+
if ((_a = result.errors) === null || _a === void 0 ? void 0 : _a.length) {
|
|
8
|
+
errorHandler(result.errors, args);
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
const useErrorHandler = (errorHandler) => ({
|
|
12
|
+
onExecute() {
|
|
13
|
+
const handleResult = makeHandleResult(errorHandler);
|
|
14
|
+
return {
|
|
15
|
+
onExecuteDone(payload) {
|
|
16
|
+
return (0, utils_js_1.handleStreamOrSingleExecutionResult)(payload, handleResult);
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
exports.useErrorHandler = useErrorHandler;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useExtendContext = void 0;
|
|
4
|
+
const useExtendContext = (contextFactory) => ({
|
|
5
|
+
async onContextBuilding({ context, extendContext }) {
|
|
6
|
+
extendContext((await contextFactory(context)));
|
|
7
|
+
},
|
|
8
|
+
});
|
|
9
|
+
exports.useExtendContext = useExtendContext;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useImmediateIntrospection = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const OnNonIntrospectionFieldReachedValidationRule = (onNonIntrospectionField) => ctx => {
|
|
6
|
+
const rootQueryType = ctx.getSchema().getQueryType();
|
|
7
|
+
const rootMutationType = ctx.getSchema().getMutationType();
|
|
8
|
+
const rootSubscriptionType = ctx.getSchema().getSubscriptionType();
|
|
9
|
+
return {
|
|
10
|
+
Field(field) {
|
|
11
|
+
const parentType = ctx.getParentType();
|
|
12
|
+
const isQuery = parentType === rootQueryType;
|
|
13
|
+
const isMutation = parentType === rootMutationType;
|
|
14
|
+
const isSubscription = parentType === rootSubscriptionType;
|
|
15
|
+
if ((isQuery && !field.name.value.startsWith('__')) || isMutation || isSubscription) {
|
|
16
|
+
onNonIntrospectionField();
|
|
17
|
+
return graphql_1.BREAK;
|
|
18
|
+
}
|
|
19
|
+
return undefined;
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
const fastIntroSpectionSymbol = Symbol('fastIntrospection');
|
|
24
|
+
/**
|
|
25
|
+
* In case a GraphQL operation only contains introspection fields the context building can be skipped completely.
|
|
26
|
+
* With this plugin any further context extensions will be skipped.
|
|
27
|
+
*/
|
|
28
|
+
const useImmediateIntrospection = () => {
|
|
29
|
+
return {
|
|
30
|
+
onValidate({ addValidationRule }) {
|
|
31
|
+
let isIntrospectionOnly = true;
|
|
32
|
+
addValidationRule(OnNonIntrospectionFieldReachedValidationRule(() => {
|
|
33
|
+
isIntrospectionOnly = false;
|
|
34
|
+
}));
|
|
35
|
+
return function afterValidate({ extendContext }) {
|
|
36
|
+
if (isIntrospectionOnly) {
|
|
37
|
+
extendContext({ [fastIntroSpectionSymbol]: true });
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
onContextBuilding({ context, breakContextBuilding }) {
|
|
42
|
+
if (context[fastIntroSpectionSymbol]) {
|
|
43
|
+
// hijack and skip all other context related stuff.
|
|
44
|
+
// We dont need a context!
|
|
45
|
+
breakContextBuilding();
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
exports.useImmediateIntrospection = useImmediateIntrospection;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useLogger = void 0;
|
|
4
|
+
const utils_js_1 = require("../utils.js");
|
|
5
|
+
const DEFAULT_OPTIONS = {
|
|
6
|
+
logFn: console.log,
|
|
7
|
+
};
|
|
8
|
+
const useLogger = (rawOptions = DEFAULT_OPTIONS) => {
|
|
9
|
+
const options = {
|
|
10
|
+
DEFAULT_OPTIONS,
|
|
11
|
+
...rawOptions,
|
|
12
|
+
};
|
|
13
|
+
return {
|
|
14
|
+
onParse({ extendContext, params }) {
|
|
15
|
+
if (options.skipIntrospection && (0, utils_js_1.isIntrospectionOperationString)(params.source)) {
|
|
16
|
+
extendContext({
|
|
17
|
+
[utils_js_1.envelopIsIntrospectionSymbol]: true,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
onExecute({ args }) {
|
|
22
|
+
if (args.contextValue[utils_js_1.envelopIsIntrospectionSymbol]) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
options.logFn('execute-start', { args });
|
|
26
|
+
return {
|
|
27
|
+
onExecuteDone: ({ result }) => {
|
|
28
|
+
options.logFn('execute-end', { args, result });
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
onSubscribe({ args }) {
|
|
33
|
+
if (args.contextValue[utils_js_1.envelopIsIntrospectionSymbol]) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
options.logFn('subscribe-start', { args });
|
|
37
|
+
return {
|
|
38
|
+
onSubscribeResult: ({ result }) => {
|
|
39
|
+
options.logFn('subscribe-end', { args, result });
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
exports.useLogger = useLogger;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useMaskedErrors = exports.formatError = exports.EnvelopError = exports.DEFAULT_ERROR_MESSAGE = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const utils_js_1 = require("../utils.js");
|
|
6
|
+
exports.DEFAULT_ERROR_MESSAGE = 'Unexpected error.';
|
|
7
|
+
class EnvelopError extends graphql_1.GraphQLError {
|
|
8
|
+
constructor(message, extensions) {
|
|
9
|
+
super(message, undefined, undefined, undefined, undefined, undefined, extensions);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.EnvelopError = EnvelopError;
|
|
13
|
+
const formatError = (err, message, isDev) => {
|
|
14
|
+
var _a, _b, _c, _d;
|
|
15
|
+
if (err instanceof graphql_1.GraphQLError) {
|
|
16
|
+
if (
|
|
17
|
+
/** execution error */
|
|
18
|
+
(err.originalError && err.originalError instanceof EnvelopError === false) ||
|
|
19
|
+
/** validate and parse errors */
|
|
20
|
+
(err.originalError === undefined && err instanceof EnvelopError === false)) {
|
|
21
|
+
return new graphql_1.GraphQLError(message, err.nodes, err.source, err.positions, err.path, undefined, isDev
|
|
22
|
+
? {
|
|
23
|
+
originalError: {
|
|
24
|
+
message: (_b = (_a = err.originalError) === null || _a === void 0 ? void 0 : _a.message) !== null && _b !== void 0 ? _b : err.message,
|
|
25
|
+
stack: (_d = (_c = err.originalError) === null || _c === void 0 ? void 0 : _c.stack) !== null && _d !== void 0 ? _d : err.stack,
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
: undefined);
|
|
29
|
+
}
|
|
30
|
+
return err;
|
|
31
|
+
}
|
|
32
|
+
return new graphql_1.GraphQLError(message);
|
|
33
|
+
};
|
|
34
|
+
exports.formatError = formatError;
|
|
35
|
+
const makeHandleResult = (format, message, isDev) => ({ result, setResult }) => {
|
|
36
|
+
if (result.errors != null) {
|
|
37
|
+
setResult({ ...result, errors: result.errors.map(error => format(error, message, isDev)) });
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const useMaskedErrors = (opts) => {
|
|
41
|
+
var _a, _b;
|
|
42
|
+
const format = (_a = opts === null || opts === void 0 ? void 0 : opts.formatError) !== null && _a !== void 0 ? _a : exports.formatError;
|
|
43
|
+
const message = (opts === null || opts === void 0 ? void 0 : opts.errorMessage) || exports.DEFAULT_ERROR_MESSAGE;
|
|
44
|
+
// eslint-disable-next-line dot-notation
|
|
45
|
+
const isDev = (_b = opts === null || opts === void 0 ? void 0 : opts.isDev) !== null && _b !== void 0 ? _b : (typeof process !== 'undefined' ? process.env['NODE_ENV'] === 'development' : false);
|
|
46
|
+
const handleResult = makeHandleResult(format, message, isDev);
|
|
47
|
+
return {
|
|
48
|
+
onParse: (opts === null || opts === void 0 ? void 0 : opts.handleParseErrors) === true
|
|
49
|
+
? function onParse() {
|
|
50
|
+
return function onParseEnd({ result, replaceParseResult }) {
|
|
51
|
+
if (result instanceof Error) {
|
|
52
|
+
replaceParseResult(format(result, message, isDev));
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
: undefined,
|
|
57
|
+
onValidate: (opts === null || opts === void 0 ? void 0 : opts.handleValidationErrors) === true
|
|
58
|
+
? function onValidate() {
|
|
59
|
+
return function onValidateEnd({ valid, result, setResult }) {
|
|
60
|
+
if (valid === false) {
|
|
61
|
+
setResult(result.map(error => format(error, message, isDev)));
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
: undefined,
|
|
66
|
+
onPluginInit(context) {
|
|
67
|
+
context.registerContextErrorHandler(({ error, setError }) => {
|
|
68
|
+
setError((0, exports.formatError)(error, message, isDev));
|
|
69
|
+
});
|
|
70
|
+
},
|
|
71
|
+
onExecute() {
|
|
72
|
+
return {
|
|
73
|
+
onExecuteDone(payload) {
|
|
74
|
+
return (0, utils_js_1.handleStreamOrSingleExecutionResult)(payload, handleResult);
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
},
|
|
78
|
+
onSubscribe() {
|
|
79
|
+
return {
|
|
80
|
+
onSubscribeResult(payload) {
|
|
81
|
+
return (0, utils_js_1.handleStreamOrSingleExecutionResult)(payload, handleResult);
|
|
82
|
+
},
|
|
83
|
+
onSubscribeError({ error, setError }) {
|
|
84
|
+
setError((0, exports.formatError)(error, message, isDev));
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
exports.useMaskedErrors = useMaskedErrors;
|