@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 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 (stopCalled) {
646
- return result;
650
+ if (after === null || after === void 0 ? void 0 : after.onExecuteDone) {
651
+ afterCalls.push(after.onExecuteDone);
647
652
  }
648
- if (after) {
649
- if (after.onExecuteDone) {
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 = (await executeFn({
658
- ...args,
659
- contextValue: context,
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 (stopCalled) {
642
- return result;
646
+ if (after === null || after === void 0 ? void 0 : after.onExecuteDone) {
647
+ afterCalls.push(after.onExecuteDone);
643
648
  }
644
- if (after) {
645
- if (after.onExecuteDone) {
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 = (await executeFn({
654
- ...args,
655
- contextValue: context,
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
- 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, useLazyLoadedSchema, useLogger, useMaskedErrors, usePayloadFormatter, useSchema, useTiming };
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.0-alpha-dc1e98d.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": "1.5.1"
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;