graphql-jit 0.8.9 → 0.9.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.
Files changed (178) hide show
  1. package/README.md +25 -0
  2. package/dist/cjs/ast.d.ts +89 -0
  3. package/dist/cjs/ast.js +766 -0
  4. package/dist/cjs/ast.js.map +1 -0
  5. package/dist/cjs/compat.d.ts +70 -0
  6. package/dist/cjs/compat.js +144 -0
  7. package/dist/cjs/compat.js.map +1 -0
  8. package/dist/cjs/debug.d.ts +29 -0
  9. package/dist/cjs/debug.js +46 -0
  10. package/dist/cjs/debug.js.map +1 -0
  11. package/dist/cjs/error.d.ts +7 -0
  12. package/dist/cjs/error.js +58 -0
  13. package/dist/cjs/error.js.map +1 -0
  14. package/dist/cjs/execution.d.ts +154 -0
  15. package/dist/cjs/execution.js +1240 -0
  16. package/dist/cjs/execution.js.map +1 -0
  17. package/dist/cjs/generate.d.ts +4 -0
  18. package/dist/cjs/generate.js +13 -0
  19. package/dist/cjs/generate.js.map +1 -0
  20. package/dist/cjs/index.d.ts +3 -0
  21. package/dist/cjs/index.js +10 -0
  22. package/dist/cjs/index.js.map +1 -0
  23. package/dist/cjs/inspect.d.ts +5 -0
  24. package/dist/cjs/inspect.js +110 -0
  25. package/dist/cjs/inspect.js.map +1 -0
  26. package/dist/cjs/json.d.ts +9 -0
  27. package/dist/cjs/json.js +144 -0
  28. package/dist/cjs/json.js.map +1 -0
  29. package/dist/cjs/memoize.d.ts +5 -0
  30. package/dist/cjs/memoize.js +28 -0
  31. package/dist/cjs/memoize.js.map +1 -0
  32. package/dist/cjs/non-null.d.ts +9 -0
  33. package/dist/cjs/non-null.js +205 -0
  34. package/dist/cjs/non-null.js.map +1 -0
  35. package/dist/cjs/package.json +3 -0
  36. package/dist/{resolve-info.d.ts → cjs/resolve-info.d.ts} +10 -12
  37. package/dist/cjs/resolve-info.js +232 -0
  38. package/dist/cjs/resolve-info.js.map +1 -0
  39. package/dist/cjs/runtime.d.ts +14 -0
  40. package/dist/cjs/runtime.js +92 -0
  41. package/dist/cjs/runtime.js.map +1 -0
  42. package/dist/cjs/types.d.ts +1 -0
  43. package/dist/cjs/types.js +3 -0
  44. package/dist/cjs/types.js.map +1 -0
  45. package/dist/cjs/variables.d.ts +20 -0
  46. package/dist/cjs/variables.js +357 -0
  47. package/dist/cjs/variables.js.map +1 -0
  48. package/dist/esm/ast.d.ts +89 -0
  49. package/dist/esm/ast.js +751 -0
  50. package/dist/esm/ast.js.map +1 -0
  51. package/dist/esm/compat.d.ts +70 -0
  52. package/dist/esm/compat.js +102 -0
  53. package/dist/esm/compat.js.map +1 -0
  54. package/dist/esm/debug.d.ts +29 -0
  55. package/dist/esm/debug.js +40 -0
  56. package/dist/esm/debug.js.map +1 -0
  57. package/dist/esm/error.d.ts +7 -0
  58. package/dist/esm/error.js +55 -0
  59. package/dist/esm/error.js.map +1 -0
  60. package/dist/esm/execution.d.ts +154 -0
  61. package/dist/esm/execution.js +1227 -0
  62. package/dist/esm/execution.js.map +1 -0
  63. package/dist/esm/generate.d.ts +4 -0
  64. package/dist/esm/generate.js +10 -0
  65. package/dist/esm/generate.js.map +1 -0
  66. package/dist/esm/index.d.ts +3 -0
  67. package/dist/esm/index.js +3 -0
  68. package/dist/esm/index.js.map +1 -0
  69. package/dist/esm/inspect.d.ts +5 -0
  70. package/dist/esm/inspect.js +106 -0
  71. package/dist/esm/inspect.js.map +1 -0
  72. package/dist/esm/json.d.ts +9 -0
  73. package/dist/esm/json.js +141 -0
  74. package/dist/esm/json.js.map +1 -0
  75. package/dist/esm/memoize.d.ts +5 -0
  76. package/dist/esm/memoize.js +20 -0
  77. package/dist/esm/memoize.js.map +1 -0
  78. package/dist/esm/non-null.d.ts +9 -0
  79. package/dist/esm/non-null.js +199 -0
  80. package/dist/esm/non-null.js.map +1 -0
  81. package/dist/esm/package.json +3 -0
  82. package/dist/{resolve-info.d.mts → esm/resolve-info.d.ts} +10 -12
  83. package/dist/esm/resolve-info.js +224 -0
  84. package/dist/esm/resolve-info.js.map +1 -0
  85. package/dist/esm/runtime.d.ts +14 -0
  86. package/dist/esm/runtime.js +89 -0
  87. package/dist/esm/runtime.js.map +1 -0
  88. package/dist/esm/types.d.ts +1 -0
  89. package/dist/esm/types.js +2 -0
  90. package/dist/esm/types.js.map +1 -0
  91. package/dist/esm/variables.d.ts +20 -0
  92. package/dist/esm/variables.js +350 -0
  93. package/dist/esm/variables.js.map +1 -0
  94. package/package.json +39 -35
  95. package/dist/ast.d.mts +0 -7
  96. package/dist/ast.d.ts +0 -7
  97. package/dist/ast.js +0 -635
  98. package/dist/ast.js.map +0 -1
  99. package/dist/ast.mjs +0 -612
  100. package/dist/ast.mjs.map +0 -1
  101. package/dist/compat.d.mts +0 -7
  102. package/dist/compat.d.ts +0 -7
  103. package/dist/compat.js +0 -113
  104. package/dist/compat.js.map +0 -1
  105. package/dist/compat.mjs +0 -75
  106. package/dist/compat.mjs.map +0 -1
  107. package/dist/error.d.mts +0 -11
  108. package/dist/error.d.ts +0 -11
  109. package/dist/error.js +0 -79
  110. package/dist/error.js.map +0 -1
  111. package/dist/error.mjs +0 -57
  112. package/dist/error.mjs.map +0 -1
  113. package/dist/execution.d.mts +0 -7
  114. package/dist/execution.d.ts +0 -7
  115. package/dist/execution.js +0 -1262
  116. package/dist/execution.js.map +0 -1
  117. package/dist/execution.mjs +0 -1248
  118. package/dist/execution.mjs.map +0 -1
  119. package/dist/generate.d.mts +0 -6
  120. package/dist/generate.d.ts +0 -6
  121. package/dist/generate.js +0 -37
  122. package/dist/generate.js.map +0 -1
  123. package/dist/generate.mjs +0 -13
  124. package/dist/generate.mjs.map +0 -1
  125. package/dist/index-CeluTkd4.d.mts +0 -329
  126. package/dist/index-mKv2zpdA.d.ts +0 -329
  127. package/dist/index.d.mts +0 -7
  128. package/dist/index.d.ts +0 -7
  129. package/dist/index.js +0 -36
  130. package/dist/index.js.map +0 -1
  131. package/dist/index.mjs +0 -15
  132. package/dist/index.mjs.map +0 -1
  133. package/dist/inspect.d.mts +0 -7
  134. package/dist/inspect.d.ts +0 -7
  135. package/dist/inspect.js +0 -121
  136. package/dist/inspect.js.map +0 -1
  137. package/dist/inspect.mjs +0 -97
  138. package/dist/inspect.mjs.map +0 -1
  139. package/dist/json.d.mts +0 -18
  140. package/dist/json.d.ts +0 -18
  141. package/dist/json.js +0 -181
  142. package/dist/json.js.map +0 -1
  143. package/dist/json.mjs +0 -164
  144. package/dist/json.mjs.map +0 -1
  145. package/dist/memoize.d.mts +0 -6
  146. package/dist/memoize.d.ts +0 -6
  147. package/dist/memoize.js +0 -67
  148. package/dist/memoize.js.map +0 -1
  149. package/dist/memoize.mjs +0 -31
  150. package/dist/memoize.mjs.map +0 -1
  151. package/dist/non-null.d.mts +0 -7
  152. package/dist/non-null.d.ts +0 -7
  153. package/dist/non-null.js +0 -196
  154. package/dist/non-null.js.map +0 -1
  155. package/dist/non-null.mjs +0 -167
  156. package/dist/non-null.mjs.map +0 -1
  157. package/dist/resolve-info.js +0 -245
  158. package/dist/resolve-info.js.map +0 -1
  159. package/dist/resolve-info.mjs +0 -219
  160. package/dist/resolve-info.mjs.map +0 -1
  161. package/dist/runtime.d.mts +0 -7
  162. package/dist/runtime.d.ts +0 -7
  163. package/dist/runtime.js +0 -115
  164. package/dist/runtime.js.map +0 -1
  165. package/dist/runtime.mjs +0 -91
  166. package/dist/runtime.mjs.map +0 -1
  167. package/dist/types.d.mts +0 -3
  168. package/dist/types.d.ts +0 -3
  169. package/dist/types.js +0 -17
  170. package/dist/types.js.map +0 -1
  171. package/dist/types.mjs +0 -1
  172. package/dist/types.mjs.map +0 -1
  173. package/dist/variables.d.mts +0 -17
  174. package/dist/variables.d.ts +0 -17
  175. package/dist/variables.js +0 -412
  176. package/dist/variables.js.map +0 -1
  177. package/dist/variables.mjs +0 -391
  178. package/dist/variables.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memoize.js","sourceRoot":"","sources":["../../src/memoize.ts"],"names":[],"mappings":";;;;;;;;AAAA,oEAAqC;AAkCrC,SAAS,QAAQ,CAAU,EAAyB;IAClD,OAAO,CAAC,CAAI,EAAE,CAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,CAAC;AAED,SAAS,QAAQ,CAAa,EAAmC;IAC/D,OAAO,CAAC,CAAI,EAAE,CAAI,EAAE,CAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,QAAQ,CACf,EAA6C;IAE7C,OAAO,CAAC,CAAI,EAAE,CAAI,EAAE,CAAI,EAAE,CAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,kBAAuC,EAAK;IAI1C,OAAO,QAAQ,CAAC,IAAA,wBAAO,EAAC,CAAC,CAAI,EAAE,EAAE,CAAC,IAAA,wBAAO,EAAC,CAAC,CAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAM,CAAC;AACvE,CAAC;AAED,kBAAuC,EAAK;IAK1C,OAAO,QAAQ,CACb,IAAA,wBAAO,EAAC,CAAC,CAAI,EAAE,EAAE,CAAC,IAAA,wBAAO,EAAC,CAAC,CAAI,EAAE,EAAE,CAAC,IAAA,wBAAO,EAAC,CAAC,CAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAChE,CAAC;AACT,CAAC;AAED,kBAAuC,EAAK;IAM1C,OAAO,QAAQ,CACb,IAAA,wBAAO,EAAC,CAAC,CAAI,EAAE,EAAE,CACf,IAAA,wBAAO,EAAC,CAAC,CAAI,EAAE,EAAE,CAAC,IAAA,wBAAO,EAAC,CAAC,CAAI,EAAE,EAAE,CAAC,IAAA,wBAAO,EAAC,CAAC,CAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CACxE,CACG,CAAC;AACT,CAAC","sourcesContent":["import memoize from \"lodash.memoize\";\n\ntype Fn = (...args: any[]) => any;\n\ntype Args2<T> = T extends (a: infer A, b: infer B) => infer R\n ? {\n 0: A;\n 1: B;\n return: R;\n }\n : never;\ntype Args3<T> = T extends (a: infer A, b: infer B, c: infer C) => infer R\n ? {\n 0: A;\n 1: B;\n 2: C;\n return: R;\n }\n : never;\ntype Args4<T> = T extends (\n a: infer A,\n b: infer B,\n c: infer C,\n d: infer D\n) => infer R\n ? {\n 0: A;\n 1: B;\n 2: C;\n 3: D;\n return: R;\n }\n : never;\n\nfunction uncurry2<A, B, R>(fn: (a: A) => (b: B) => R) {\n return (a: A, b: B) => fn(a)(b);\n}\n\nfunction uncurry3<A, B, C, R>(fn: (a: A) => (b: B) => (c: C) => R) {\n return (a: A, b: B, c: C) => fn(a)(b)(c);\n}\n\nfunction uncurry4<A, B, C, D, R>(\n fn: (a: A) => (b: B) => (c: C) => (d: D) => R\n) {\n return (a: A, b: B, c: C, d: D) => fn(a)(b)(c)(d);\n}\n\nexport function memoize2<T extends Fn>(fn: T): T {\n type A = Args2<T>[0];\n type B = Args2<T>[1];\n\n return uncurry2(memoize((a: A) => memoize((b: B) => fn(a, b)))) as T;\n}\n\nexport function memoize3<T extends Fn>(fn: T): T {\n type A = Args3<T>[0];\n type B = Args3<T>[1];\n type C = Args3<T>[2];\n\n return uncurry3(\n memoize((a: A) => memoize((b: B) => memoize((c: C) => fn(a, b, c))))\n ) as T;\n}\n\nexport function memoize4<T extends Fn>(fn: T): T {\n type A = Args4<T>[0];\n type B = Args4<T>[1];\n type C = Args4<T>[2];\n type D = Args4<T>[3];\n\n return uncurry4(\n memoize((a: A) =>\n memoize((b: B) => memoize((c: C) => memoize((d: D) => fn(a, b, c, d))))\n )\n ) as T;\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import { type GraphQLError } from "graphql";
2
+ import { type CompilationContext } from "./execution.js";
3
+ export type NullTrimmer = (data: any, errors: GraphQLError[]) => any;
4
+ /**
5
+ *
6
+ * @param {CompilationContext} compilationContext
7
+ * @returns {(data: any, errors: GraphQLError[]) => {data: any; errors: GraphQLError[]}}
8
+ */
9
+ export declare function createNullTrimmer(compilationContext: CompilationContext): NullTrimmer;
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createNullTrimmer = createNullTrimmer;
7
+ const graphql_1 = require("graphql");
8
+ const lodash_merge_1 = __importDefault(require("lodash.merge"));
9
+ const ast_js_1 = require("./ast.js");
10
+ const compat_js_1 = require("./compat.js");
11
+ /**
12
+ *
13
+ * @param {CompilationContext} compilationContext
14
+ * @returns {(data: any, errors: GraphQLError[]) => {data: any; errors: GraphQLError[]}}
15
+ */
16
+ function createNullTrimmer(compilationContext) {
17
+ return trimData(parseQueryNullables(compilationContext));
18
+ }
19
+ /**
20
+ * Trims a data response according to the field errors in non null fields.
21
+ *
22
+ * Errors are filtered to ensure a single field error per field.
23
+ *
24
+ * @param {QueryMetadata} nullable Description of the query and their nullability
25
+ * @returns {(data: any, errors: GraphQLError[]) => {data: any; errors: GraphQLError[]}}
26
+ * the trimmed data and a filtered list of errors.
27
+ */
28
+ function trimData(nullable) {
29
+ return (data, errors) => {
30
+ const finalErrors = [];
31
+ const processedErrors = new Set();
32
+ for (const error of errors) {
33
+ if (!error.path) {
34
+ // should never happen, it is a bug if it does
35
+ throw new Error("no path available for tree trimming");
36
+ }
37
+ if (processedErrors.has(error.path.join("."))) {
38
+ // there can be multiple field errors in some scenario
39
+ // there is no need to continue processing and it should not be part of the final response
40
+ continue;
41
+ }
42
+ const ancestors = findNullableAncestor(nullable, error.path);
43
+ // The top level field is always nullable
44
+ // http://facebook.github.io/graphql/June2018/#sec-Errors-and-Non-Nullability
45
+ //
46
+ // There is no mention if the following errors need to be present in the response.
47
+ // For now we assume this is not needed.
48
+ if (ancestors.length === 0) {
49
+ data = null;
50
+ finalErrors.push(error);
51
+ break;
52
+ }
53
+ removeBranch(data, ancestors);
54
+ processedErrors.add(error.path.join("."));
55
+ finalErrors.push(error);
56
+ }
57
+ return { data, errors: finalErrors };
58
+ };
59
+ }
60
+ /**
61
+ * Removes a branch out of the response data by mutating the original object.
62
+ *
63
+ * @param tree response data
64
+ * @param {Array<number | string>} branch array with the path that should be trimmed
65
+ */
66
+ function removeBranch(tree, branch) {
67
+ for (let i = 0; i < branch.length - 1; ++i) {
68
+ // if ancestor has already been removed, there's nothing to do
69
+ if (tree[branch[i]] === null) {
70
+ return;
71
+ }
72
+ tree = tree[branch[i]];
73
+ }
74
+ const toNull = branch[branch.length - 1];
75
+ tree[toNull] = null;
76
+ }
77
+ /**
78
+ * Name of the child used in array to contain the description.
79
+ *
80
+ * Only used for list to contain the child description.
81
+ */
82
+ const ARRAY_CHILD_NAME = "index";
83
+ /**
84
+ *
85
+ * @param {QueryMetadata} nullable Description of the query and their nullability
86
+ * @param {ReadonlyArray<string | number>} paths path of the error location
87
+ * @returns {Array<string | number>} path of the branch to be made null
88
+ */
89
+ function findNullableAncestor(nullable, paths) {
90
+ let lastNullable = 0;
91
+ for (let i = 0; i < paths.length; ++i) {
92
+ const path = paths[i];
93
+ const child = nullable.children[typeof path === "string" ? path : ARRAY_CHILD_NAME];
94
+ if (!child) {
95
+ // Stopping the search since we reached a leaf node,
96
+ // the loop should be on its final iteration
97
+ break;
98
+ }
99
+ if (child.isNullable) {
100
+ lastNullable = i + 1;
101
+ }
102
+ nullable = child;
103
+ }
104
+ return paths.slice(0, lastNullable);
105
+ }
106
+ /**
107
+ * Produce a description of the query regarding its nullability.
108
+ *
109
+ * Leaf nodes are not present in this representation since they are not
110
+ * interesting for removing branches of the response tree.
111
+ *
112
+ * The structure is recursive like the query.
113
+ * @param {CompilationContext} compilationContext Execution content
114
+ * @returns {QueryMetadata} description of the query
115
+ */
116
+ function parseQueryNullables(compilationContext) {
117
+ const type = (0, compat_js_1.getOperationRootType)(compilationContext.schema, compilationContext.operation);
118
+ const fields = (0, ast_js_1.collectFields)(compilationContext, type, compilationContext.operation.selectionSet, Object.create(null), Object.create(null));
119
+ const properties = Object.create(null);
120
+ for (const responseName of Object.keys(fields)) {
121
+ const fieldType = (0, ast_js_1.resolveFieldDef)(compilationContext, type, fields[responseName]);
122
+ if (!fieldType) {
123
+ // if field does not exist, it should be ignored for compatibility concerns.
124
+ // Usually, validation would stop it before getting here but this could be an old query
125
+ continue;
126
+ }
127
+ const property = transformNode(compilationContext, fields[responseName], fieldType.type);
128
+ if (property != null) {
129
+ properties[responseName] = property;
130
+ }
131
+ }
132
+ return {
133
+ isNullable: true,
134
+ children: properties
135
+ };
136
+ }
137
+ /**
138
+ * Processes a single node to produce a description of itself and its children.
139
+ *
140
+ * Leaf nodes are ignore and removed from the description
141
+ * @param {CompilationContext} compilationContext
142
+ * @param {FieldNode[]} fieldNodes list of fields
143
+ * @param {GraphQLType} type Current type being processed.
144
+ * @returns {QueryMetadata | null} null if node is a leaf, otherwise a description of the node and its children.
145
+ */
146
+ function transformNode(compilationContext, fieldNodes, type) {
147
+ if ((0, graphql_1.isNonNullType)(type)) {
148
+ const nullable = transformNode(compilationContext, fieldNodes, type.ofType);
149
+ if (nullable != null) {
150
+ nullable.isNullable = false;
151
+ return nullable;
152
+ }
153
+ return null;
154
+ }
155
+ if ((0, graphql_1.isObjectType)(type)) {
156
+ const subfields = (0, ast_js_1.collectSubfields)(compilationContext, type, fieldNodes);
157
+ const properties = Object.create(null);
158
+ for (const responseName of Object.keys(subfields)) {
159
+ const fieldType = (0, ast_js_1.resolveFieldDef)(compilationContext, type, subfields[responseName]);
160
+ if (!fieldType) {
161
+ // if field does not exist, it should be ignored for compatibility concerns.
162
+ // Usually, validation would stop it before getting here but this could be an old query
163
+ continue;
164
+ }
165
+ const property = transformNode(compilationContext, subfields[responseName], fieldType.type);
166
+ if (property != null) {
167
+ properties[responseName] = property;
168
+ }
169
+ }
170
+ return {
171
+ isNullable: true,
172
+ children: properties
173
+ };
174
+ }
175
+ if ((0, graphql_1.isListType)(type)) {
176
+ const child = transformNode(compilationContext, fieldNodes, type.ofType);
177
+ if (child != null) {
178
+ return {
179
+ isNullable: true,
180
+ children: { [ARRAY_CHILD_NAME]: child }
181
+ };
182
+ }
183
+ return {
184
+ isNullable: true,
185
+ children: {}
186
+ };
187
+ }
188
+ if ((0, graphql_1.isAbstractType)(type)) {
189
+ return compilationContext.schema.getPossibleTypes(type).reduce((res, t) => {
190
+ const property = transformNode(compilationContext, fieldNodes, t);
191
+ if (property != null) {
192
+ // We do a deep merge because children can have subset of properties
193
+ // TODO: Possible bug: two object with different nullability on objects.
194
+ res.children = (0, lodash_merge_1.default)(res.children, property.children);
195
+ }
196
+ return res;
197
+ }, {
198
+ isNullable: true,
199
+ children: {}
200
+ });
201
+ }
202
+ // Scalars and enum are ignored since they are leaf values
203
+ return null;
204
+ }
205
+ //# sourceMappingURL=non-null.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"non-null.js","sourceRoot":"","sources":["../../src/non-null.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type ExecutionResult,\n type FieldNode,\n type GraphQLError,\n type GraphQLType,\n isListType,\n isNonNullType,\n isObjectType,\n isAbstractType\n} from \"graphql\";\nimport merge from \"lodash.merge\";\nimport { collectFields, collectSubfields, resolveFieldDef } from \"./ast.js\";\nimport { getOperationRootType } from \"./compat.js\";\nimport { type CompilationContext } from \"./execution.js\";\n\ninterface QueryMetadata {\n isNullable: boolean;\n children: { [key: string]: QueryMetadata };\n}\n\nexport type NullTrimmer = (data: any, errors: GraphQLError[]) => any;\n\n/**\n *\n * @param {CompilationContext} compilationContext\n * @returns {(data: any, errors: GraphQLError[]) => {data: any; errors: GraphQLError[]}}\n */\nexport function createNullTrimmer(\n compilationContext: CompilationContext\n): NullTrimmer {\n return trimData(parseQueryNullables(compilationContext));\n}\n\n/**\n * Trims a data response according to the field errors in non null fields.\n *\n * Errors are filtered to ensure a single field error per field.\n *\n * @param {QueryMetadata} nullable Description of the query and their nullability\n * @returns {(data: any, errors: GraphQLError[]) => {data: any; errors: GraphQLError[]}}\n * the trimmed data and a filtered list of errors.\n */\nfunction trimData(nullable: QueryMetadata): NullTrimmer {\n return (data: any, errors: GraphQLError[]): ExecutionResult => {\n const finalErrors = [];\n const processedErrors = new Set<string>();\n for (const error of errors) {\n if (!error.path) {\n // should never happen, it is a bug if it does\n throw new Error(\"no path available for tree trimming\");\n }\n if (processedErrors.has(error.path.join(\".\"))) {\n // there can be multiple field errors in some scenario\n // there is no need to continue processing and it should not be part of the final response\n continue;\n }\n const ancestors = findNullableAncestor(nullable, error.path);\n // The top level field is always nullable\n // http://facebook.github.io/graphql/June2018/#sec-Errors-and-Non-Nullability\n //\n // There is no mention if the following errors need to be present in the response.\n // For now we assume this is not needed.\n if (ancestors.length === 0) {\n data = null;\n finalErrors.push(error);\n break;\n }\n removeBranch(data, ancestors);\n processedErrors.add(error.path.join(\".\"));\n finalErrors.push(error);\n }\n return { data, errors: finalErrors };\n };\n}\n\n/**\n * Removes a branch out of the response data by mutating the original object.\n *\n * @param tree response data\n * @param {Array<number | string>} branch array with the path that should be trimmed\n */\nfunction removeBranch(tree: any, branch: Array<number | string>): void {\n for (let i = 0; i < branch.length - 1; ++i) {\n // if ancestor has already been removed, there's nothing to do\n if (tree[branch[i]] === null) {\n return;\n }\n tree = tree[branch[i]];\n }\n const toNull = branch[branch.length - 1];\n tree[toNull] = null;\n}\n\n/**\n * Name of the child used in array to contain the description.\n *\n * Only used for list to contain the child description.\n */\nconst ARRAY_CHILD_NAME = \"index\";\n\n/**\n *\n * @param {QueryMetadata} nullable Description of the query and their nullability\n * @param {ReadonlyArray<string | number>} paths path of the error location\n * @returns {Array<string | number>} path of the branch to be made null\n */\nfunction findNullableAncestor(\n nullable: QueryMetadata,\n paths: ReadonlyArray<string | number>\n): Array<string | number> {\n let lastNullable = 0;\n for (let i = 0; i < paths.length; ++i) {\n const path = paths[i];\n const child =\n nullable.children[typeof path === \"string\" ? path : ARRAY_CHILD_NAME];\n if (!child) {\n // Stopping the search since we reached a leaf node,\n // the loop should be on its final iteration\n break;\n }\n if (child.isNullable) {\n lastNullable = i + 1;\n }\n nullable = child;\n }\n return paths.slice(0, lastNullable);\n}\n\n/**\n * Produce a description of the query regarding its nullability.\n *\n * Leaf nodes are not present in this representation since they are not\n * interesting for removing branches of the response tree.\n *\n * The structure is recursive like the query.\n * @param {CompilationContext} compilationContext Execution content\n * @returns {QueryMetadata} description of the query\n */\nfunction parseQueryNullables(\n compilationContext: CompilationContext\n): QueryMetadata {\n const type = getOperationRootType(\n compilationContext.schema,\n compilationContext.operation\n );\n const fields = collectFields(\n compilationContext,\n type,\n compilationContext.operation.selectionSet,\n Object.create(null),\n Object.create(null)\n );\n const properties = Object.create(null);\n for (const responseName of Object.keys(fields)) {\n const fieldType = resolveFieldDef(\n compilationContext,\n type,\n fields[responseName]\n );\n if (!fieldType) {\n // if field does not exist, it should be ignored for compatibility concerns.\n // Usually, validation would stop it before getting here but this could be an old query\n continue;\n }\n const property = transformNode(\n compilationContext,\n fields[responseName],\n fieldType.type\n );\n if (property != null) {\n properties[responseName] = property;\n }\n }\n return {\n isNullable: true,\n children: properties\n };\n}\n\n/**\n * Processes a single node to produce a description of itself and its children.\n *\n * Leaf nodes are ignore and removed from the description\n * @param {CompilationContext} compilationContext\n * @param {FieldNode[]} fieldNodes list of fields\n * @param {GraphQLType} type Current type being processed.\n * @returns {QueryMetadata | null} null if node is a leaf, otherwise a description of the node and its children.\n */\nfunction transformNode(\n compilationContext: CompilationContext,\n fieldNodes: FieldNode[],\n type: GraphQLType\n): QueryMetadata | null {\n if (isNonNullType(type)) {\n const nullable = transformNode(compilationContext, fieldNodes, type.ofType);\n if (nullable != null) {\n nullable.isNullable = false;\n return nullable;\n }\n return null;\n }\n if (isObjectType(type)) {\n const subfields = collectSubfields(compilationContext, type, fieldNodes);\n const properties = Object.create(null);\n for (const responseName of Object.keys(subfields)) {\n const fieldType = resolveFieldDef(\n compilationContext,\n type,\n subfields[responseName]\n );\n if (!fieldType) {\n // if field does not exist, it should be ignored for compatibility concerns.\n // Usually, validation would stop it before getting here but this could be an old query\n continue;\n }\n const property = transformNode(\n compilationContext,\n subfields[responseName],\n fieldType.type\n );\n if (property != null) {\n properties[responseName] = property;\n }\n }\n return {\n isNullable: true,\n children: properties\n };\n }\n if (isListType(type)) {\n const child = transformNode(compilationContext, fieldNodes, type.ofType);\n if (child != null) {\n return {\n isNullable: true,\n children: { [ARRAY_CHILD_NAME]: child }\n };\n }\n\n return {\n isNullable: true,\n children: {}\n };\n }\n if (isAbstractType(type)) {\n return compilationContext.schema.getPossibleTypes(type).reduce(\n (res, t) => {\n const property = transformNode(compilationContext, fieldNodes, t);\n if (property != null) {\n // We do a deep merge because children can have subset of properties\n // TODO: Possible bug: two object with different nullability on objects.\n res.children = merge(res.children, property.children);\n }\n return res;\n },\n {\n isNullable: true,\n children: {}\n }\n );\n }\n\n // Scalars and enum are ignored since they are leaf values\n return null;\n}\n"]}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -1,7 +1,6 @@
1
- import { GraphQLResolveInfo, GraphQLObjectType, GraphQLOutputType, FieldNode } from 'graphql';
2
-
3
- type GraphQLJitResolveInfo<Enrichments> = GraphQLResolveInfo & Enrichments;
4
- interface ResolveInfoEnricherInput {
1
+ import { type FieldNode, GraphQLObjectType, type GraphQLOutputType, type GraphQLResolveInfo } from "graphql";
2
+ export type GraphQLJitResolveInfo<Enrichments> = GraphQLResolveInfo & Enrichments;
3
+ export interface ResolveInfoEnricherInput {
5
4
  schema: GraphQLResolveInfo["schema"];
6
5
  fragments: GraphQLResolveInfo["fragments"];
7
6
  operation: GraphQLResolveInfo["operation"];
@@ -10,23 +9,23 @@ interface ResolveInfoEnricherInput {
10
9
  fieldName: string;
11
10
  fieldNodes: FieldNode[];
12
11
  }
13
- interface FieldExpansion {
12
+ export interface FieldExpansion {
14
13
  [returnType: string]: TypeExpansion;
15
14
  }
16
15
  declare const LeafFieldSymbol: unique symbol;
17
- interface LeafField {
16
+ export interface LeafField {
18
17
  [LeafFieldSymbol]: true;
19
18
  }
20
- interface TypeExpansion {
19
+ export interface TypeExpansion {
21
20
  [fieldName: string]: FieldExpansion | LeafField;
22
21
  }
23
- declare function isLeafField(obj: LeafField | FieldExpansion): obj is LeafField;
22
+ export declare function isLeafField(obj: LeafField | FieldExpansion): obj is LeafField;
24
23
  /**
25
24
  * Compute the GraphQLJitResolveInfo's `fieldExpansion` and return a function
26
25
  * that returns the computed resolveInfo. This thunk is registered in
27
26
  * context.dependencies for the field's resolveInfoName
28
27
  */
29
- declare function createResolveInfoThunk<T>({ schema, fragments, operation, parentType, fieldName, fieldType, fieldNodes }: {
28
+ export declare function createResolveInfoThunk<T>({ schema, fragments, operation, parentType, fieldName, fieldType, fieldNodes }: {
30
29
  schema: GraphQLResolveInfo["schema"];
31
30
  fragments: GraphQLResolveInfo["fragments"];
32
31
  operation: GraphQLResolveInfo["operation"];
@@ -35,8 +34,7 @@ declare function createResolveInfoThunk<T>({ schema, fragments, operation, paren
35
34
  fieldName: string;
36
35
  fieldNodes: FieldNode[];
37
36
  }, enricher?: (inp: ResolveInfoEnricherInput) => T): any;
38
- declare function fieldExpansionEnricher(input: ResolveInfoEnricherInput): {
37
+ export declare function fieldExpansionEnricher(input: ResolveInfoEnricherInput): {
39
38
  fieldExpansion: FieldExpansion;
40
39
  };
41
-
42
- export { type FieldExpansion, type GraphQLJitResolveInfo, type LeafField, type ResolveInfoEnricherInput, type TypeExpansion, createResolveInfoThunk, fieldExpansionEnricher, isLeafField };
40
+ export {};
@@ -0,0 +1,232 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isLeafField = isLeafField;
7
+ exports.createResolveInfoThunk = createResolveInfoThunk;
8
+ exports.fieldExpansionEnricher = fieldExpansionEnricher;
9
+ const generate_js_1 = require("./generate.js");
10
+ const graphql_1 = require("graphql");
11
+ const lodash_memoize_1 = __importDefault(require("lodash.memoize"));
12
+ const lodash_mergewith_1 = __importDefault(require("lodash.mergewith"));
13
+ const memoize_js_1 = require("./memoize.js");
14
+ const LeafFieldSymbol = Symbol("LeafFieldSymbol");
15
+ function createLeafField(props) {
16
+ return {
17
+ [LeafFieldSymbol]: true,
18
+ ...props
19
+ };
20
+ }
21
+ function isLeafField(obj) {
22
+ return (obj != null && Object.prototype.hasOwnProperty.call(obj, LeafFieldSymbol));
23
+ }
24
+ /**
25
+ * Compute the GraphQLJitResolveInfo's `fieldExpansion` and return a function
26
+ * that returns the computed resolveInfo. This thunk is registered in
27
+ * context.dependencies for the field's resolveInfoName
28
+ */
29
+ function createResolveInfoThunk({ schema, fragments, operation, parentType, fieldName, fieldType, fieldNodes }, enricher) {
30
+ let enrichedInfo = {};
31
+ if (typeof enricher === "function") {
32
+ enrichedInfo =
33
+ enricher({
34
+ fieldName,
35
+ fieldNodes,
36
+ returnType: fieldType,
37
+ parentType,
38
+ schema,
39
+ fragments,
40
+ operation
41
+ }) || {};
42
+ if (typeof enrichedInfo !== "object" || Array.isArray(enrichedInfo)) {
43
+ enrichedInfo = {};
44
+ }
45
+ }
46
+ const gen = (0, generate_js_1.genFn)();
47
+ gen(`return function getGraphQLResolveInfo(rootValue, variableValues, path) {
48
+ return {
49
+ fieldName,
50
+ fieldNodes,
51
+ returnType: fieldType,
52
+ parentType,
53
+ path,
54
+ schema,
55
+ fragments,
56
+ rootValue,
57
+ operation,
58
+ variableValues,`);
59
+ Object.keys(enrichedInfo).forEach((key) => {
60
+ gen(`${key}: enrichedInfo["${key}"],\n`);
61
+ });
62
+ gen(`};};`);
63
+ // eslint-disable-next-line
64
+ return new Function("fieldName", "fieldNodes", "fieldType", "parentType", "schema", "fragments", "operation", "enrichedInfo", gen.toString()).call(null, fieldName, fieldNodes, fieldType, parentType, schema, fragments, operation, enrichedInfo);
65
+ }
66
+ function fieldExpansionEnricher(input) {
67
+ const { schema, fragments, returnType, fieldNodes } = input;
68
+ const fieldExpansion = {};
69
+ for (const fieldNode of fieldNodes) {
70
+ deepMerge(fieldExpansion, memoizedExpandFieldNode(schema, fragments, fieldNode, returnType));
71
+ }
72
+ return {
73
+ fieldExpansion
74
+ };
75
+ }
76
+ const MEMOIZATION = true;
77
+ const memoizedGetReturnType = MEMOIZATION
78
+ ? (0, memoize_js_1.memoize2)(getReturnType)
79
+ : getReturnType;
80
+ const memoizedHasField = MEMOIZATION ? (0, memoize_js_1.memoize2)(hasField) : hasField;
81
+ const memoizedResolveEndType = MEMOIZATION
82
+ ? (0, lodash_memoize_1.default)(resolveEndType)
83
+ : resolveEndType;
84
+ const memoizedGetPossibleTypes = MEMOIZATION
85
+ ? (0, memoize_js_1.memoize2)(getPossibleTypes)
86
+ : getPossibleTypes;
87
+ const memoizedExpandFieldNodeType = MEMOIZATION
88
+ ? (0, memoize_js_1.memoize4)(expandFieldNodeType)
89
+ : expandFieldNodeType;
90
+ const memoizedExpandFieldNode = MEMOIZATION
91
+ ? (0, memoize_js_1.memoize4)(expandFieldNode)
92
+ : expandFieldNode;
93
+ function expandFieldNode(schema, fragments, node, fieldType) {
94
+ if (node.selectionSet == null) {
95
+ return createLeafField({});
96
+ }
97
+ // there is a selectionSet which makes the fieldType a CompositeType
98
+ const typ = memoizedResolveEndType(fieldType);
99
+ const possibleTypes = memoizedGetPossibleTypes(schema, typ);
100
+ const fieldExpansion = {};
101
+ for (const possibleType of possibleTypes) {
102
+ if (!(0, graphql_1.isUnionType)(possibleType)) {
103
+ fieldExpansion[possibleType.name] = memoizedExpandFieldNodeType(schema, fragments, possibleType, node.selectionSet);
104
+ }
105
+ }
106
+ return fieldExpansion;
107
+ }
108
+ function expandFieldNodeType(schema, fragments, parentType, selectionSet) {
109
+ const typeExpansion = {};
110
+ for (const selection of selectionSet.selections) {
111
+ if (selection.kind === graphql_1.Kind.FIELD) {
112
+ if (!(0, graphql_1.isUnionType)(parentType) &&
113
+ memoizedHasField(parentType, selection.name.value)) {
114
+ typeExpansion[selection.name.value] = memoizedExpandFieldNode(schema, fragments, selection, memoizedGetReturnType(parentType, selection.name.value));
115
+ }
116
+ }
117
+ else {
118
+ const selectionSet = selection.kind === graphql_1.Kind.INLINE_FRAGMENT
119
+ ? selection.selectionSet
120
+ : fragments[selection.name.value].selectionSet;
121
+ const nextType = selection.kind === graphql_1.Kind.INLINE_FRAGMENT
122
+ ? selection.typeCondition
123
+ ? schema.getType(selection.typeCondition.name.value)
124
+ : parentType
125
+ : schema.getType(fragments[selection.name.value].typeCondition.name.value);
126
+ /**
127
+ * nextType (comes from query) is the type extracted from the fragment
128
+ * parentType (comes from schema) is the possibleType for which we are filling fields
129
+ *
130
+ * if the type from query (nextType) is the same as the type we are filling (parentType)
131
+ * or
132
+ * if the type from query (nextType) is an abstract type - this case is when we jump
133
+ * to a super type or sub type. Here we maintain the context (parentType) for which
134
+ * we are filling the fields. The super type / sub type will be filled in its own
135
+ * pass.
136
+ */
137
+ if (nextType === parentType || (0, graphql_1.isAbstractType)(nextType)) {
138
+ deepMerge(typeExpansion, memoizedExpandFieldNodeType(schema, fragments, parentType, selectionSet));
139
+ }
140
+ }
141
+ }
142
+ return typeExpansion;
143
+ }
144
+ /**
145
+ * Returns a list of Possible types that one can get to from the
146
+ * resolvedType. As an analogy, these are the same types that one
147
+ * can use in a fragment's typeCondition.
148
+ *
149
+ * Note: This is different from schema.getPossibleTypes() that this
150
+ * returns all possible types and not just the ones from the type definition.
151
+ *
152
+ * Example:
153
+ * interface Node {
154
+ * id: ID!
155
+ * }
156
+ * type User implements Node {
157
+ * id: ID!
158
+ * name: String
159
+ * }
160
+ * type Article implements Node {
161
+ * id: ID!
162
+ * title: String
163
+ * }
164
+ * union Card = User | Article
165
+ *
166
+ * - schema.getPossibleTypes(Card) would give [User, Article]
167
+ * - This function getPossibleTypes(schema, Card) would give [User, Article, Node]
168
+ *
169
+ */
170
+ function getPossibleTypes(schema, compositeType) {
171
+ if ((0, graphql_1.isObjectType)(compositeType)) {
172
+ return [compositeType];
173
+ }
174
+ const possibleTypes = [];
175
+ const types = schema.getTypeMap();
176
+ for (const typeName in types) {
177
+ if (Object.prototype.hasOwnProperty.call(types, typeName)) {
178
+ const typ = types[typeName];
179
+ if ((0, graphql_1.isCompositeType)(typ) && (0, graphql_1.doTypesOverlap)(schema, typ, compositeType)) {
180
+ possibleTypes.push(typ);
181
+ }
182
+ }
183
+ }
184
+ return possibleTypes;
185
+ }
186
+ /**
187
+ * Given an (Object|Interface)Type, and a fieldName, find the
188
+ * appropriate `end` return type for the field in the Composite Type.
189
+ *
190
+ * Note: The `end` return type is the type by unwrapping non-null types
191
+ * and list types. Check `resolveEndType`
192
+ */
193
+ function getReturnType(parentType, fieldName) {
194
+ const fields = parentType.getFields();
195
+ if (!Object.prototype.hasOwnProperty.call(fields, fieldName)) {
196
+ throw new graphql_1.GraphQLError(`Field "${fieldName}" does not exist in "${parentType.name}"`);
197
+ }
198
+ const outputType = fields[fieldName].type;
199
+ return memoizedResolveEndType(outputType);
200
+ }
201
+ /**
202
+ * Resolve to the end type of the Output type unwrapping non-null types and lists
203
+ */
204
+ function resolveEndType(typ) {
205
+ if ((0, graphql_1.isListType)(typ) || (0, graphql_1.isNonNullType)(typ)) {
206
+ return memoizedResolveEndType(typ.ofType);
207
+ }
208
+ return typ;
209
+ }
210
+ function hasField(typ, fieldName) {
211
+ return Object.prototype.hasOwnProperty.call(typ.getFields(), fieldName);
212
+ }
213
+ // This is because lodash does not support merging keys
214
+ // which are symbols. We require them for leaf fields
215
+ function deepMerge(obj, src) {
216
+ (0, lodash_mergewith_1.default)(obj, src, (objValue, srcValue) => {
217
+ if (isLeafField(objValue)) {
218
+ if (isLeafField(srcValue)) {
219
+ return {
220
+ ...objValue,
221
+ ...srcValue
222
+ };
223
+ }
224
+ return objValue;
225
+ }
226
+ else if (isLeafField(srcValue)) {
227
+ return srcValue;
228
+ }
229
+ return undefined;
230
+ });
231
+ }
232
+ //# sourceMappingURL=resolve-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-info.js","sourceRoot":"","sources":["../../src/resolve-info.ts"],"names":[],"mappings":"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","sourcesContent":["import { genFn } from \"./generate.js\";\nimport {\n doTypesOverlap,\n type FieldNode,\n type GraphQLCompositeType,\n GraphQLError,\n GraphQLInterfaceType,\n type GraphQLNamedType,\n GraphQLObjectType,\n type GraphQLOutputType,\n type GraphQLResolveInfo,\n GraphQLSchema,\n isAbstractType,\n isCompositeType,\n isListType,\n isNonNullType,\n isObjectType,\n isUnionType,\n Kind,\n type SelectionSetNode\n} from \"graphql\";\nimport memoize from \"lodash.memoize\";\nimport mergeWith from \"lodash.mergewith\";\nimport { memoize2, memoize4 } from \"./memoize.js\";\n\n// TODO(boopathi): Use negated types to express\n// Enrichments<T> = { [key in (string & not keyof GraphQLResolveInfo)]: T[key] }\n// in TypeScript 3.5\n// https://github.com/Microsoft/TypeScript/pull/29317\nexport type GraphQLJitResolveInfo<Enrichments> = GraphQLResolveInfo &\n Enrichments;\n\nexport interface ResolveInfoEnricherInput {\n schema: GraphQLResolveInfo[\"schema\"];\n fragments: GraphQLResolveInfo[\"fragments\"];\n operation: GraphQLResolveInfo[\"operation\"];\n parentType: GraphQLObjectType;\n returnType: GraphQLOutputType;\n fieldName: string;\n fieldNodes: FieldNode[];\n}\n\nexport interface FieldExpansion {\n // The possible return types that the field can return\n // It includes all the types in the Schema that intersect with the actual return type\n [returnType: string]: TypeExpansion;\n}\n\nconst LeafFieldSymbol = Symbol(\"LeafFieldSymbol\");\n\nexport interface LeafField {\n [LeafFieldSymbol]: true;\n}\n\nexport interface TypeExpansion {\n // The fields that are requested in the Query for a particular type\n // `true` indicates a leaf node\n [fieldName: string]: FieldExpansion | LeafField;\n}\n\nfunction createLeafField<T extends object>(props: T): T & LeafField {\n return {\n [LeafFieldSymbol]: true,\n ...props\n };\n}\n\nexport function isLeafField(obj: LeafField | FieldExpansion): obj is LeafField {\n return (\n obj != null && Object.prototype.hasOwnProperty.call(obj, LeafFieldSymbol)\n );\n}\n\n/**\n * Compute the GraphQLJitResolveInfo's `fieldExpansion` and return a function\n * that returns the computed resolveInfo. This thunk is registered in\n * context.dependencies for the field's resolveInfoName\n */\nexport function createResolveInfoThunk<T>(\n {\n schema,\n fragments,\n operation,\n parentType,\n fieldName,\n fieldType,\n fieldNodes\n }: {\n schema: GraphQLResolveInfo[\"schema\"];\n fragments: GraphQLResolveInfo[\"fragments\"];\n operation: GraphQLResolveInfo[\"operation\"];\n parentType: GraphQLObjectType;\n fieldType: GraphQLOutputType;\n fieldName: string;\n fieldNodes: FieldNode[];\n },\n enricher?: (inp: ResolveInfoEnricherInput) => T\n) {\n let enrichedInfo = {};\n if (typeof enricher === \"function\") {\n enrichedInfo =\n enricher({\n fieldName,\n fieldNodes,\n returnType: fieldType,\n parentType,\n schema,\n fragments,\n operation\n }) || {};\n if (typeof enrichedInfo !== \"object\" || Array.isArray(enrichedInfo)) {\n enrichedInfo = {};\n }\n }\n const gen = genFn();\n gen(`return function getGraphQLResolveInfo(rootValue, variableValues, path) {\n return {\n fieldName,\n fieldNodes,\n returnType: fieldType,\n parentType,\n path,\n schema,\n fragments,\n rootValue,\n operation,\n variableValues,`);\n Object.keys(enrichedInfo).forEach((key) => {\n gen(`${key}: enrichedInfo[\"${key}\"],\\n`);\n });\n gen(`};};`);\n // eslint-disable-next-line\n return new Function(\n \"fieldName\",\n \"fieldNodes\",\n \"fieldType\",\n \"parentType\",\n \"schema\",\n \"fragments\",\n \"operation\",\n \"enrichedInfo\",\n gen.toString()\n ).call(\n null,\n fieldName,\n fieldNodes,\n fieldType,\n parentType,\n schema,\n fragments,\n operation,\n enrichedInfo\n );\n}\n\nexport function fieldExpansionEnricher(input: ResolveInfoEnricherInput) {\n const { schema, fragments, returnType, fieldNodes } = input;\n const fieldExpansion: FieldExpansion | LeafField = {};\n\n for (const fieldNode of fieldNodes) {\n deepMerge(\n fieldExpansion,\n memoizedExpandFieldNode(schema, fragments, fieldNode, returnType)\n );\n }\n\n return {\n fieldExpansion\n };\n}\n\ntype FragmentsType = GraphQLResolveInfo[\"fragments\"];\ntype GraphQLNamedOutputType = GraphQLNamedType & GraphQLOutputType;\ntype GraphQLObjectLike = GraphQLInterfaceType | GraphQLObjectType;\n\nconst MEMOIZATION = true;\n\nconst memoizedGetReturnType = MEMOIZATION\n ? memoize2(getReturnType)\n : getReturnType;\nconst memoizedHasField = MEMOIZATION ? memoize2(hasField) : hasField;\nconst memoizedResolveEndType = MEMOIZATION\n ? memoize(resolveEndType)\n : resolveEndType;\nconst memoizedGetPossibleTypes = MEMOIZATION\n ? memoize2(getPossibleTypes)\n : getPossibleTypes;\nconst memoizedExpandFieldNodeType = MEMOIZATION\n ? memoize4(expandFieldNodeType)\n : expandFieldNodeType;\nconst memoizedExpandFieldNode = MEMOIZATION\n ? memoize4(expandFieldNode)\n : expandFieldNode;\n\nfunction expandFieldNode(\n schema: GraphQLSchema,\n fragments: FragmentsType,\n node: FieldNode,\n fieldType: GraphQLOutputType\n): FieldExpansion | LeafField {\n if (node.selectionSet == null) {\n return createLeafField({});\n }\n\n // there is a selectionSet which makes the fieldType a CompositeType\n const typ = memoizedResolveEndType(fieldType) as GraphQLCompositeType;\n const possibleTypes = memoizedGetPossibleTypes(schema, typ);\n\n const fieldExpansion: FieldExpansion = {};\n for (const possibleType of possibleTypes) {\n if (!isUnionType(possibleType)) {\n fieldExpansion[possibleType.name] = memoizedExpandFieldNodeType(\n schema,\n fragments,\n possibleType,\n node.selectionSet\n );\n }\n }\n\n return fieldExpansion;\n}\n\nfunction expandFieldNodeType(\n schema: GraphQLSchema,\n fragments: FragmentsType,\n parentType: GraphQLCompositeType,\n selectionSet: SelectionSetNode\n): TypeExpansion {\n const typeExpansion: TypeExpansion = {};\n\n for (const selection of selectionSet.selections) {\n if (selection.kind === Kind.FIELD) {\n if (\n !isUnionType(parentType) &&\n memoizedHasField(parentType, selection.name.value)\n ) {\n typeExpansion[selection.name.value] = memoizedExpandFieldNode(\n schema,\n fragments,\n selection,\n memoizedGetReturnType(parentType, selection.name.value)\n );\n }\n } else {\n const selectionSet =\n selection.kind === Kind.INLINE_FRAGMENT\n ? selection.selectionSet\n : fragments[selection.name.value].selectionSet;\n\n const nextType =\n selection.kind === Kind.INLINE_FRAGMENT\n ? selection.typeCondition\n ? (schema.getType(\n selection.typeCondition.name.value\n ) as GraphQLCompositeType)\n : parentType\n : (schema.getType(\n fragments[selection.name.value].typeCondition.name.value\n ) as GraphQLCompositeType);\n\n /**\n * nextType (comes from query) is the type extracted from the fragment\n * parentType (comes from schema) is the possibleType for which we are filling fields\n *\n * if the type from query (nextType) is the same as the type we are filling (parentType)\n * or\n * if the type from query (nextType) is an abstract type - this case is when we jump\n * to a super type or sub type. Here we maintain the context (parentType) for which\n * we are filling the fields. The super type / sub type will be filled in its own\n * pass.\n */\n if (nextType === parentType || isAbstractType(nextType)) {\n deepMerge(\n typeExpansion,\n memoizedExpandFieldNodeType(\n schema,\n fragments,\n parentType,\n selectionSet\n )\n );\n }\n }\n }\n\n return typeExpansion;\n}\n\n/**\n * Returns a list of Possible types that one can get to from the\n * resolvedType. As an analogy, these are the same types that one\n * can use in a fragment's typeCondition.\n *\n * Note: This is different from schema.getPossibleTypes() that this\n * returns all possible types and not just the ones from the type definition.\n *\n * Example:\n * interface Node {\n * id: ID!\n * }\n * type User implements Node {\n * id: ID!\n * name: String\n * }\n * type Article implements Node {\n * id: ID!\n * title: String\n * }\n * union Card = User | Article\n *\n * - schema.getPossibleTypes(Card) would give [User, Article]\n * - This function getPossibleTypes(schema, Card) would give [User, Article, Node]\n *\n */\nfunction getPossibleTypes(\n schema: GraphQLSchema,\n compositeType: GraphQLCompositeType\n) {\n if (isObjectType(compositeType)) {\n return [compositeType];\n }\n\n const possibleTypes: GraphQLCompositeType[] = [];\n const types = schema.getTypeMap();\n for (const typeName in types) {\n if (Object.prototype.hasOwnProperty.call(types, typeName)) {\n const typ = types[typeName];\n if (isCompositeType(typ) && doTypesOverlap(schema, typ, compositeType)) {\n possibleTypes.push(typ);\n }\n }\n }\n\n return possibleTypes;\n}\n\n/**\n * Given an (Object|Interface)Type, and a fieldName, find the\n * appropriate `end` return type for the field in the Composite Type.\n *\n * Note: The `end` return type is the type by unwrapping non-null types\n * and list types. Check `resolveEndType`\n */\nfunction getReturnType(\n parentType: GraphQLObjectLike,\n fieldName: string\n): GraphQLNamedOutputType {\n const fields = parentType.getFields();\n if (!Object.prototype.hasOwnProperty.call(fields, fieldName)) {\n throw new GraphQLError(\n `Field \"${fieldName}\" does not exist in \"${parentType.name}\"`\n );\n }\n\n const outputType = fields[fieldName].type;\n return memoizedResolveEndType(outputType);\n}\n\n/**\n * Resolve to the end type of the Output type unwrapping non-null types and lists\n */\nfunction resolveEndType(typ: GraphQLOutputType): GraphQLNamedOutputType {\n if (isListType(typ) || isNonNullType(typ)) {\n return memoizedResolveEndType(typ.ofType);\n }\n return typ;\n}\n\nfunction hasField(typ: GraphQLObjectLike, fieldName: string) {\n return Object.prototype.hasOwnProperty.call(typ.getFields(), fieldName);\n}\n\n// This is because lodash does not support merging keys\n// which are symbols. We require them for leaf fields\nfunction deepMerge<TObject, TSource>(obj: TObject, src: TSource) {\n mergeWith(obj, src, (objValue, srcValue): LeafField | undefined => {\n if (isLeafField(objValue)) {\n if (isLeafField(srcValue)) {\n return {\n ...objValue,\n ...srcValue\n };\n }\n\n return objValue;\n } else if (isLeafField(srcValue)) {\n return srcValue;\n }\n\n return undefined;\n });\n}\n"]}
@@ -0,0 +1,14 @@
1
+ import { type ExecutionContext } from "./execution.js";
2
+ type Serializer = (c: ExecutionContext, v: any, onError: any, ...idx: number[]) => any;
3
+ export declare const jitRuntime: {
4
+ isPromise(value: unknown): boolean;
5
+ checkNonNullLeaf(ctx: ExecutionContext, value: unknown, dest: any[], nullMsg: string, locs: any, path: any, capStack: boolean, serialize: Serializer, errHandler: any, ...parentIndexes: number[]): any;
6
+ checkNullableLeaf(ctx: ExecutionContext, value: unknown, dest: any[], locs: any, path: any, capStack: boolean, serialize: Serializer, errHandler: any, ...parentIndexes: number[]): any;
7
+ callResolver(ctx: ExecutionContext, call: () => unknown, onSuccess: (result: unknown) => void, onError: (err: unknown) => void): void;
8
+ handleResolverResult(ctx: ExecutionContext, value: unknown, onSuccess: (result: unknown) => void, onError: (err: unknown) => void): void;
9
+ handleListItemResult(ctx: ExecutionContext, item: unknown, onSuccess: (result: unknown) => void, onError: (err: unknown) => void): void;
10
+ finalizeResult(ctx: ExecutionContext): Promise<unknown> | undefined;
11
+ safeMap(ctx: ExecutionContext, iterable: Iterable<unknown> | string, cb: (context: ExecutionContext, a: unknown, index: number, resultArray: unknown[], ...idx: number[]) => void, ...idx: number[]): unknown[];
12
+ };
13
+ export type JitRuntime = typeof jitRuntime;
14
+ export {};