@envelop/core 1.7.2-alpha-7ca7cb8.0 → 1.8.0-alpha-0107392.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.js CHANGED
@@ -27,8 +27,69 @@ function enableIf(condition, plugin) {
27
27
  }
28
28
  }
29
29
 
30
- // import { AfterResolverHook, OnResolverCalledHook, ResolverFn } from '@envelop/types';
30
+ const trackedSchemaSymbol = Symbol('TRACKED_SCHEMA');
31
31
  const resolversHooksSymbol = Symbol('RESOLVERS_HOOKS');
32
+ function prepareTracedSchema(schema) {
33
+ if (!schema || schema[trackedSchemaSymbol]) {
34
+ return;
35
+ }
36
+ schema[trackedSchemaSymbol] = true;
37
+ const entries = Object.values(schema.getTypeMap());
38
+ for (const type of entries) {
39
+ if (!graphql.isIntrospectionType(type) && graphql.isObjectType(type)) {
40
+ const fields = Object.values(type.getFields());
41
+ for (const field of fields) {
42
+ let resolverFn = (field.resolve || graphql.defaultFieldResolver);
43
+ field.resolve = async (root, args, context, info) => {
44
+ if (context && context[resolversHooksSymbol]) {
45
+ const hooks = context[resolversHooksSymbol];
46
+ const afterCalls = [];
47
+ for (const hook of hooks) {
48
+ const afterFn = await hook({
49
+ root,
50
+ args,
51
+ context,
52
+ info,
53
+ resolverFn,
54
+ replaceResolverFn: newFn => {
55
+ resolverFn = newFn;
56
+ },
57
+ });
58
+ afterFn && afterCalls.push(afterFn);
59
+ }
60
+ try {
61
+ let result = await resolverFn(root, args, context, info);
62
+ for (const afterFn of afterCalls) {
63
+ afterFn({
64
+ result,
65
+ setResult: newResult => {
66
+ result = newResult;
67
+ },
68
+ });
69
+ }
70
+ return result;
71
+ }
72
+ catch (e) {
73
+ let resultErr = e;
74
+ for (const afterFn of afterCalls) {
75
+ afterFn({
76
+ result: resultErr,
77
+ setResult: newResult => {
78
+ resultErr = newResult;
79
+ },
80
+ });
81
+ }
82
+ throw resultErr;
83
+ }
84
+ }
85
+ else {
86
+ return resolverFn(root, args, context, info);
87
+ }
88
+ };
89
+ }
90
+ }
91
+ }
92
+ }
32
93
 
33
94
  const envelopIsIntrospectionSymbol = Symbol('ENVELOP_IS_INTROSPECTION');
34
95
  function isOperationDefinition(def) {
@@ -246,6 +307,7 @@ function createEnvelopOrchestrator(plugins) {
246
307
  // to allow setting the schema from the onPluginInit callback. We also need to make sure
247
308
  // here not to call the same plugin that initiated the schema switch.
248
309
  const replaceSchema = (newSchema, ignorePluginIndex = -1) => {
310
+ prepareTracedSchema(newSchema);
249
311
  schema = newSchema;
250
312
  if (initDone) {
251
313
  for (const [i, plugin] of plugins.entries()) {
@@ -415,13 +477,20 @@ function createEnvelopOrchestrator(plugins) {
415
477
  const afterCalls = [];
416
478
  try {
417
479
  let context = orchestratorCtx ? { ...initialContext, ...orchestratorCtx } : initialContext;
480
+ let shortCircuitContext;
418
481
  for (const onContext of beforeCallbacks.context) {
419
482
  const afterHookResult = await onContext({
420
483
  context,
421
484
  extendContext: extension => {
422
485
  context = { ...context, ...extension };
423
486
  },
487
+ shortCircuitContext: value => {
488
+ shortCircuitContext = value;
489
+ },
424
490
  });
491
+ if (shortCircuitContext !== undefined) {
492
+ break;
493
+ }
425
494
  if (typeof afterHookResult === 'function') {
426
495
  afterCalls.push(afterHookResult);
427
496
  }
package/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  export * from '@envelop/types';
2
- import { Kind, visit, BREAK, parse, specifiedRules, validate, execute, subscribe, GraphQLSchema, getOperationAST, GraphQLError } from 'graphql';
2
+ import { isIntrospectionType, isObjectType, defaultFieldResolver, Kind, visit, BREAK, parse, specifiedRules, validate, execute, subscribe, GraphQLSchema, getOperationAST, GraphQLError } from 'graphql';
3
3
 
4
4
  /**
5
5
  * This enum is used only internally in order to create nominal type for the disabled plugin
@@ -23,8 +23,69 @@ function enableIf(condition, plugin) {
23
23
  }
24
24
  }
25
25
 
26
- // import { AfterResolverHook, OnResolverCalledHook, ResolverFn } from '@envelop/types';
26
+ const trackedSchemaSymbol = Symbol('TRACKED_SCHEMA');
27
27
  const resolversHooksSymbol = Symbol('RESOLVERS_HOOKS');
28
+ function prepareTracedSchema(schema) {
29
+ if (!schema || schema[trackedSchemaSymbol]) {
30
+ return;
31
+ }
32
+ schema[trackedSchemaSymbol] = true;
33
+ const entries = Object.values(schema.getTypeMap());
34
+ for (const type of entries) {
35
+ if (!isIntrospectionType(type) && isObjectType(type)) {
36
+ const fields = Object.values(type.getFields());
37
+ for (const field of fields) {
38
+ let resolverFn = (field.resolve || defaultFieldResolver);
39
+ field.resolve = async (root, args, context, info) => {
40
+ if (context && context[resolversHooksSymbol]) {
41
+ const hooks = context[resolversHooksSymbol];
42
+ const afterCalls = [];
43
+ for (const hook of hooks) {
44
+ const afterFn = await hook({
45
+ root,
46
+ args,
47
+ context,
48
+ info,
49
+ resolverFn,
50
+ replaceResolverFn: newFn => {
51
+ resolverFn = newFn;
52
+ },
53
+ });
54
+ afterFn && afterCalls.push(afterFn);
55
+ }
56
+ try {
57
+ let result = await resolverFn(root, args, context, info);
58
+ for (const afterFn of afterCalls) {
59
+ afterFn({
60
+ result,
61
+ setResult: newResult => {
62
+ result = newResult;
63
+ },
64
+ });
65
+ }
66
+ return result;
67
+ }
68
+ catch (e) {
69
+ let resultErr = e;
70
+ for (const afterFn of afterCalls) {
71
+ afterFn({
72
+ result: resultErr,
73
+ setResult: newResult => {
74
+ resultErr = newResult;
75
+ },
76
+ });
77
+ }
78
+ throw resultErr;
79
+ }
80
+ }
81
+ else {
82
+ return resolverFn(root, args, context, info);
83
+ }
84
+ };
85
+ }
86
+ }
87
+ }
88
+ }
28
89
 
29
90
  const envelopIsIntrospectionSymbol = Symbol('ENVELOP_IS_INTROSPECTION');
30
91
  function isOperationDefinition(def) {
@@ -242,6 +303,7 @@ function createEnvelopOrchestrator(plugins) {
242
303
  // to allow setting the schema from the onPluginInit callback. We also need to make sure
243
304
  // here not to call the same plugin that initiated the schema switch.
244
305
  const replaceSchema = (newSchema, ignorePluginIndex = -1) => {
306
+ prepareTracedSchema(newSchema);
245
307
  schema = newSchema;
246
308
  if (initDone) {
247
309
  for (const [i, plugin] of plugins.entries()) {
@@ -411,13 +473,20 @@ function createEnvelopOrchestrator(plugins) {
411
473
  const afterCalls = [];
412
474
  try {
413
475
  let context = orchestratorCtx ? { ...initialContext, ...orchestratorCtx } : initialContext;
476
+ let shortCircuitContext;
414
477
  for (const onContext of beforeCallbacks.context) {
415
478
  const afterHookResult = await onContext({
416
479
  context,
417
480
  extendContext: extension => {
418
481
  context = { ...context, ...extension };
419
482
  },
483
+ shortCircuitContext: value => {
484
+ shortCircuitContext = value;
485
+ },
420
486
  });
487
+ if (shortCircuitContext !== undefined) {
488
+ break;
489
+ }
421
490
  if (typeof afterHookResult === 'function') {
422
491
  afterCalls.push(afterHookResult);
423
492
  }
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@envelop/core",
3
- "version": "1.7.2-alpha-7ca7cb8.0",
3
+ "version": "1.8.0-alpha-0107392.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": "1.6.0-alpha-0107392.0"
10
10
  },
11
11
  "repository": {
12
12
  "type": "git",
@@ -0,0 +1,2 @@
1
+ import type { Plugin } from '@envelop/types';
2
+ export declare const useFastIntrospection: () => Plugin;