@envelop/core 2.0.0-alpha-dc1e98d.0 → 2.0.1-alpha-ea62296.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/index.d.ts +1 -0
- package/index.js +55 -12
- package/index.mjs +55 -13
- package/package.json +2 -2
- package/plugins/use-immediate-introspection.d.ts +6 -0
package/index.d.ts
CHANGED
|
@@ -9,4 +9,5 @@ export * from './plugins/use-error-handler';
|
|
|
9
9
|
export * from './plugins/use-extend-context';
|
|
10
10
|
export * from './plugins/use-payload-formatter';
|
|
11
11
|
export * from './plugins/use-masked-errors';
|
|
12
|
+
export * from './plugins/use-immediate-introspection';
|
|
12
13
|
export * from './enable-if';
|
package/index.js
CHANGED
|
@@ -485,16 +485,23 @@ function createEnvelopOrchestrator(plugins) {
|
|
|
485
485
|
const afterCalls = [];
|
|
486
486
|
try {
|
|
487
487
|
let context = orchestratorCtx ? { ...initialContext, ...orchestratorCtx } : initialContext;
|
|
488
|
+
let isBreakingContextBuilding = false;
|
|
488
489
|
for (const onContext of beforeCallbacks.context) {
|
|
489
490
|
const afterHookResult = await onContext({
|
|
490
491
|
context,
|
|
491
492
|
extendContext: extension => {
|
|
492
493
|
context = { ...context, ...extension };
|
|
493
494
|
},
|
|
495
|
+
breakContextBuilding: () => {
|
|
496
|
+
isBreakingContextBuilding = true;
|
|
497
|
+
},
|
|
494
498
|
});
|
|
495
499
|
if (typeof afterHookResult === 'function') {
|
|
496
500
|
afterCalls.push(afterHookResult);
|
|
497
501
|
}
|
|
502
|
+
if (isBreakingContextBuilding === true) {
|
|
503
|
+
break;
|
|
504
|
+
}
|
|
498
505
|
}
|
|
499
506
|
for (const afterCb of afterCalls) {
|
|
500
507
|
afterCb({
|
|
@@ -619,14 +626,12 @@ function createEnvelopOrchestrator(plugins) {
|
|
|
619
626
|
const afterCalls = [];
|
|
620
627
|
let context = args.contextValue || {};
|
|
621
628
|
for (const onExecute of beforeCallbacks.execute) {
|
|
622
|
-
let stopCalled = false;
|
|
623
629
|
const after = await onExecute({
|
|
624
630
|
executeFn,
|
|
625
631
|
setExecuteFn: newExecuteFn => {
|
|
626
632
|
executeFn = newExecuteFn;
|
|
627
633
|
},
|
|
628
634
|
setResultAndStopExecution: stopResult => {
|
|
629
|
-
stopCalled = true;
|
|
630
635
|
result = stopResult;
|
|
631
636
|
},
|
|
632
637
|
extendContext: extension => {
|
|
@@ -642,22 +647,22 @@ function createEnvelopOrchestrator(plugins) {
|
|
|
642
647
|
},
|
|
643
648
|
args: args,
|
|
644
649
|
});
|
|
645
|
-
if (
|
|
646
|
-
|
|
650
|
+
if (after === null || after === void 0 ? void 0 : after.onExecuteDone) {
|
|
651
|
+
afterCalls.push(after.onExecuteDone);
|
|
647
652
|
}
|
|
648
|
-
if (
|
|
649
|
-
|
|
650
|
-
afterCalls.push(after.onExecuteDone);
|
|
651
|
-
}
|
|
653
|
+
if (result !== undefined) {
|
|
654
|
+
break;
|
|
652
655
|
}
|
|
653
656
|
}
|
|
654
657
|
if (onResolversHandlers.length) {
|
|
655
658
|
context[resolversHooksSymbol] = onResolversHandlers;
|
|
656
659
|
}
|
|
657
|
-
result
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
660
|
+
if (result === undefined) {
|
|
661
|
+
result = (await executeFn({
|
|
662
|
+
...args,
|
|
663
|
+
contextValue: context,
|
|
664
|
+
}));
|
|
665
|
+
}
|
|
661
666
|
const onNextHandler = [];
|
|
662
667
|
const onEndHandler = [];
|
|
663
668
|
for (const afterCb of afterCalls) {
|
|
@@ -1185,6 +1190,43 @@ const useMaskedErrors = (opts) => {
|
|
|
1185
1190
|
};
|
|
1186
1191
|
};
|
|
1187
1192
|
|
|
1193
|
+
const OnNonIntrospectionFieldReachedValidationRule = (onNonIntrospectionField) => () => {
|
|
1194
|
+
return {
|
|
1195
|
+
Field(field) {
|
|
1196
|
+
if (!field.name.value.startsWith('__')) {
|
|
1197
|
+
onNonIntrospectionField();
|
|
1198
|
+
}
|
|
1199
|
+
},
|
|
1200
|
+
};
|
|
1201
|
+
};
|
|
1202
|
+
const fastIntroSpectionSymbol = Symbol('fastIntrospection');
|
|
1203
|
+
/**
|
|
1204
|
+
* In case a GraphQL operation only contains introspection fields the context building can be skipped completely.
|
|
1205
|
+
* With this plugin any further context extensions will be skipped.
|
|
1206
|
+
*/
|
|
1207
|
+
const useImmediateIntrospection = () => {
|
|
1208
|
+
return {
|
|
1209
|
+
onValidate({ addValidationRule }) {
|
|
1210
|
+
let isIntrospectionOnly = true;
|
|
1211
|
+
addValidationRule(OnNonIntrospectionFieldReachedValidationRule(() => {
|
|
1212
|
+
isIntrospectionOnly = false;
|
|
1213
|
+
}));
|
|
1214
|
+
return function afterValidate({ extendContext }) {
|
|
1215
|
+
if (isIntrospectionOnly) {
|
|
1216
|
+
extendContext({ [fastIntroSpectionSymbol]: true });
|
|
1217
|
+
}
|
|
1218
|
+
};
|
|
1219
|
+
},
|
|
1220
|
+
onContextBuilding({ context, breakContextBuilding }) {
|
|
1221
|
+
if (context[fastIntroSpectionSymbol]) {
|
|
1222
|
+
// hijack and skip all other context related stuff.
|
|
1223
|
+
// We dont need a context!
|
|
1224
|
+
breakContextBuilding();
|
|
1225
|
+
}
|
|
1226
|
+
},
|
|
1227
|
+
};
|
|
1228
|
+
};
|
|
1229
|
+
|
|
1188
1230
|
Object.keys(types).forEach(function (k) {
|
|
1189
1231
|
if (k !== 'default') Object.defineProperty(exports, k, {
|
|
1190
1232
|
enumerable: true,
|
|
@@ -1215,6 +1257,7 @@ exports.useAsyncSchema = useAsyncSchema;
|
|
|
1215
1257
|
exports.useEnvelop = useEnvelop;
|
|
1216
1258
|
exports.useErrorHandler = useErrorHandler;
|
|
1217
1259
|
exports.useExtendContext = useExtendContext;
|
|
1260
|
+
exports.useImmediateIntrospection = useImmediateIntrospection;
|
|
1218
1261
|
exports.useLazyLoadedSchema = useLazyLoadedSchema;
|
|
1219
1262
|
exports.useLogger = useLogger;
|
|
1220
1263
|
exports.useMaskedErrors = useMaskedErrors;
|
package/index.mjs
CHANGED
|
@@ -481,16 +481,23 @@ function createEnvelopOrchestrator(plugins) {
|
|
|
481
481
|
const afterCalls = [];
|
|
482
482
|
try {
|
|
483
483
|
let context = orchestratorCtx ? { ...initialContext, ...orchestratorCtx } : initialContext;
|
|
484
|
+
let isBreakingContextBuilding = false;
|
|
484
485
|
for (const onContext of beforeCallbacks.context) {
|
|
485
486
|
const afterHookResult = await onContext({
|
|
486
487
|
context,
|
|
487
488
|
extendContext: extension => {
|
|
488
489
|
context = { ...context, ...extension };
|
|
489
490
|
},
|
|
491
|
+
breakContextBuilding: () => {
|
|
492
|
+
isBreakingContextBuilding = true;
|
|
493
|
+
},
|
|
490
494
|
});
|
|
491
495
|
if (typeof afterHookResult === 'function') {
|
|
492
496
|
afterCalls.push(afterHookResult);
|
|
493
497
|
}
|
|
498
|
+
if (isBreakingContextBuilding === true) {
|
|
499
|
+
break;
|
|
500
|
+
}
|
|
494
501
|
}
|
|
495
502
|
for (const afterCb of afterCalls) {
|
|
496
503
|
afterCb({
|
|
@@ -615,14 +622,12 @@ function createEnvelopOrchestrator(plugins) {
|
|
|
615
622
|
const afterCalls = [];
|
|
616
623
|
let context = args.contextValue || {};
|
|
617
624
|
for (const onExecute of beforeCallbacks.execute) {
|
|
618
|
-
let stopCalled = false;
|
|
619
625
|
const after = await onExecute({
|
|
620
626
|
executeFn,
|
|
621
627
|
setExecuteFn: newExecuteFn => {
|
|
622
628
|
executeFn = newExecuteFn;
|
|
623
629
|
},
|
|
624
630
|
setResultAndStopExecution: stopResult => {
|
|
625
|
-
stopCalled = true;
|
|
626
631
|
result = stopResult;
|
|
627
632
|
},
|
|
628
633
|
extendContext: extension => {
|
|
@@ -638,22 +643,22 @@ function createEnvelopOrchestrator(plugins) {
|
|
|
638
643
|
},
|
|
639
644
|
args: args,
|
|
640
645
|
});
|
|
641
|
-
if (
|
|
642
|
-
|
|
646
|
+
if (after === null || after === void 0 ? void 0 : after.onExecuteDone) {
|
|
647
|
+
afterCalls.push(after.onExecuteDone);
|
|
643
648
|
}
|
|
644
|
-
if (
|
|
645
|
-
|
|
646
|
-
afterCalls.push(after.onExecuteDone);
|
|
647
|
-
}
|
|
649
|
+
if (result !== undefined) {
|
|
650
|
+
break;
|
|
648
651
|
}
|
|
649
652
|
}
|
|
650
653
|
if (onResolversHandlers.length) {
|
|
651
654
|
context[resolversHooksSymbol] = onResolversHandlers;
|
|
652
655
|
}
|
|
653
|
-
result
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
656
|
+
if (result === undefined) {
|
|
657
|
+
result = (await executeFn({
|
|
658
|
+
...args,
|
|
659
|
+
contextValue: context,
|
|
660
|
+
}));
|
|
661
|
+
}
|
|
657
662
|
const onNextHandler = [];
|
|
658
663
|
const onEndHandler = [];
|
|
659
664
|
for (const afterCb of afterCalls) {
|
|
@@ -1181,4 +1186,41 @@ const useMaskedErrors = (opts) => {
|
|
|
1181
1186
|
};
|
|
1182
1187
|
};
|
|
1183
1188
|
|
|
1184
|
-
|
|
1189
|
+
const OnNonIntrospectionFieldReachedValidationRule = (onNonIntrospectionField) => () => {
|
|
1190
|
+
return {
|
|
1191
|
+
Field(field) {
|
|
1192
|
+
if (!field.name.value.startsWith('__')) {
|
|
1193
|
+
onNonIntrospectionField();
|
|
1194
|
+
}
|
|
1195
|
+
},
|
|
1196
|
+
};
|
|
1197
|
+
};
|
|
1198
|
+
const fastIntroSpectionSymbol = Symbol('fastIntrospection');
|
|
1199
|
+
/**
|
|
1200
|
+
* In case a GraphQL operation only contains introspection fields the context building can be skipped completely.
|
|
1201
|
+
* With this plugin any further context extensions will be skipped.
|
|
1202
|
+
*/
|
|
1203
|
+
const useImmediateIntrospection = () => {
|
|
1204
|
+
return {
|
|
1205
|
+
onValidate({ addValidationRule }) {
|
|
1206
|
+
let isIntrospectionOnly = true;
|
|
1207
|
+
addValidationRule(OnNonIntrospectionFieldReachedValidationRule(() => {
|
|
1208
|
+
isIntrospectionOnly = false;
|
|
1209
|
+
}));
|
|
1210
|
+
return function afterValidate({ extendContext }) {
|
|
1211
|
+
if (isIntrospectionOnly) {
|
|
1212
|
+
extendContext({ [fastIntroSpectionSymbol]: true });
|
|
1213
|
+
}
|
|
1214
|
+
};
|
|
1215
|
+
},
|
|
1216
|
+
onContextBuilding({ context, breakContextBuilding }) {
|
|
1217
|
+
if (context[fastIntroSpectionSymbol]) {
|
|
1218
|
+
// hijack and skip all other context related stuff.
|
|
1219
|
+
// We dont need a context!
|
|
1220
|
+
breakContextBuilding();
|
|
1221
|
+
}
|
|
1222
|
+
},
|
|
1223
|
+
};
|
|
1224
|
+
};
|
|
1225
|
+
|
|
1226
|
+
export { DEFAULT_ERROR_MESSAGE, EnvelopError, enableIf, envelop, envelopIsIntrospectionSymbol, errorAsyncIterator, finalAsyncIterator, formatError, handleStreamOrSingleExecutionResult, isAsyncIterable, isIntrospectionDocument, isIntrospectionOperation, isIntrospectionOperationString, isOperationDefinition, isPluginEnabled, makeExecute, makeSubscribe, mapAsyncIterator, useAsyncSchema, useEnvelop, useErrorHandler, useExtendContext, useImmediateIntrospection, useLazyLoadedSchema, useLogger, useMaskedErrors, usePayloadFormatter, useSchema, useTiming };
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@envelop/core",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1-alpha-ea62296.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
|
|
7
7
|
},
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@envelop/types": "
|
|
9
|
+
"@envelop/types": "2.0.0"
|
|
10
10
|
},
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Plugin } from '@envelop/types';
|
|
2
|
+
/**
|
|
3
|
+
* In case a GraphQL operation only contains introspection fields the context building can be skipped completely.
|
|
4
|
+
* With this plugin any further context extensions will be skipped.
|
|
5
|
+
*/
|
|
6
|
+
export declare const useImmediateIntrospection: () => Plugin;
|