@envelop/core 2.0.0-alpha-2c9f1ce.0 → 2.0.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({
@@ -1185,6 +1192,43 @@ const useMaskedErrors = (opts) => {
1185
1192
  };
1186
1193
  };
1187
1194
 
1195
+ const OnNonIntrospectionFieldReachedValidationRule = (onNonIntrospectionField) => () => {
1196
+ return {
1197
+ Field(field) {
1198
+ if (!field.name.value.startsWith('__')) {
1199
+ onNonIntrospectionField();
1200
+ }
1201
+ },
1202
+ };
1203
+ };
1204
+ const fastIntroSpectionSymbol = Symbol('fastIntrospection');
1205
+ /**
1206
+ * In case a GraphQL operation only contains introspection fields the context building can be skipped completely.
1207
+ * With this plugin any further context extensions will be skipped.
1208
+ */
1209
+ const useImmediateIntrospection = () => {
1210
+ return {
1211
+ onValidate({ addValidationRule }) {
1212
+ let isIntrospectionOnly = true;
1213
+ addValidationRule(OnNonIntrospectionFieldReachedValidationRule(() => {
1214
+ isIntrospectionOnly = false;
1215
+ }));
1216
+ return function afterValidate({ extendContext }) {
1217
+ if (isIntrospectionOnly) {
1218
+ extendContext({ [fastIntroSpectionSymbol]: true });
1219
+ }
1220
+ };
1221
+ },
1222
+ onContextBuilding({ context, breakContextBuilding }) {
1223
+ if (context[fastIntroSpectionSymbol]) {
1224
+ // hijack and skip all other context related stuff.
1225
+ // We dont need a context!
1226
+ breakContextBuilding();
1227
+ }
1228
+ },
1229
+ };
1230
+ };
1231
+
1188
1232
  Object.keys(types).forEach(function (k) {
1189
1233
  if (k !== 'default') Object.defineProperty(exports, k, {
1190
1234
  enumerable: true,
@@ -1215,6 +1259,7 @@ exports.useAsyncSchema = useAsyncSchema;
1215
1259
  exports.useEnvelop = useEnvelop;
1216
1260
  exports.useErrorHandler = useErrorHandler;
1217
1261
  exports.useExtendContext = useExtendContext;
1262
+ exports.useImmediateIntrospection = useImmediateIntrospection;
1218
1263
  exports.useLazyLoadedSchema = useLazyLoadedSchema;
1219
1264
  exports.useLogger = useLogger;
1220
1265
  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({
@@ -1181,4 +1188,41 @@ const useMaskedErrors = (opts) => {
1181
1188
  };
1182
1189
  };
1183
1190
 
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 };
1191
+ const OnNonIntrospectionFieldReachedValidationRule = (onNonIntrospectionField) => () => {
1192
+ return {
1193
+ Field(field) {
1194
+ if (!field.name.value.startsWith('__')) {
1195
+ onNonIntrospectionField();
1196
+ }
1197
+ },
1198
+ };
1199
+ };
1200
+ const fastIntroSpectionSymbol = Symbol('fastIntrospection');
1201
+ /**
1202
+ * In case a GraphQL operation only contains introspection fields the context building can be skipped completely.
1203
+ * With this plugin any further context extensions will be skipped.
1204
+ */
1205
+ const useImmediateIntrospection = () => {
1206
+ return {
1207
+ onValidate({ addValidationRule }) {
1208
+ let isIntrospectionOnly = true;
1209
+ addValidationRule(OnNonIntrospectionFieldReachedValidationRule(() => {
1210
+ isIntrospectionOnly = false;
1211
+ }));
1212
+ return function afterValidate({ extendContext }) {
1213
+ if (isIntrospectionOnly) {
1214
+ extendContext({ [fastIntroSpectionSymbol]: true });
1215
+ }
1216
+ };
1217
+ },
1218
+ onContextBuilding({ context, breakContextBuilding }) {
1219
+ if (context[fastIntroSpectionSymbol]) {
1220
+ // hijack and skip all other context related stuff.
1221
+ // We dont need a context!
1222
+ breakContextBuilding();
1223
+ }
1224
+ },
1225
+ };
1226
+ };
1227
+
1228
+ 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-2c9f1ce.0",
3
+ "version": "2.0.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;