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,199 @@
1
+ import { isListType, isNonNullType, isObjectType, isAbstractType } from "graphql";
2
+ import merge from "lodash.merge";
3
+ import { collectFields, collectSubfields, resolveFieldDef } from "./ast.js";
4
+ import { getOperationRootType } from "./compat.js";
5
+ /**
6
+ *
7
+ * @param {CompilationContext} compilationContext
8
+ * @returns {(data: any, errors: GraphQLError[]) => {data: any; errors: GraphQLError[]}}
9
+ */
10
+ export function createNullTrimmer(compilationContext) {
11
+ return trimData(parseQueryNullables(compilationContext));
12
+ }
13
+ /**
14
+ * Trims a data response according to the field errors in non null fields.
15
+ *
16
+ * Errors are filtered to ensure a single field error per field.
17
+ *
18
+ * @param {QueryMetadata} nullable Description of the query and their nullability
19
+ * @returns {(data: any, errors: GraphQLError[]) => {data: any; errors: GraphQLError[]}}
20
+ * the trimmed data and a filtered list of errors.
21
+ */
22
+ function trimData(nullable) {
23
+ return (data, errors) => {
24
+ const finalErrors = [];
25
+ const processedErrors = new Set();
26
+ for (const error of errors) {
27
+ if (!error.path) {
28
+ // should never happen, it is a bug if it does
29
+ throw new Error("no path available for tree trimming");
30
+ }
31
+ if (processedErrors.has(error.path.join("."))) {
32
+ // there can be multiple field errors in some scenario
33
+ // there is no need to continue processing and it should not be part of the final response
34
+ continue;
35
+ }
36
+ const ancestors = findNullableAncestor(nullable, error.path);
37
+ // The top level field is always nullable
38
+ // http://facebook.github.io/graphql/June2018/#sec-Errors-and-Non-Nullability
39
+ //
40
+ // There is no mention if the following errors need to be present in the response.
41
+ // For now we assume this is not needed.
42
+ if (ancestors.length === 0) {
43
+ data = null;
44
+ finalErrors.push(error);
45
+ break;
46
+ }
47
+ removeBranch(data, ancestors);
48
+ processedErrors.add(error.path.join("."));
49
+ finalErrors.push(error);
50
+ }
51
+ return { data, errors: finalErrors };
52
+ };
53
+ }
54
+ /**
55
+ * Removes a branch out of the response data by mutating the original object.
56
+ *
57
+ * @param tree response data
58
+ * @param {Array<number | string>} branch array with the path that should be trimmed
59
+ */
60
+ function removeBranch(tree, branch) {
61
+ for (let i = 0; i < branch.length - 1; ++i) {
62
+ // if ancestor has already been removed, there's nothing to do
63
+ if (tree[branch[i]] === null) {
64
+ return;
65
+ }
66
+ tree = tree[branch[i]];
67
+ }
68
+ const toNull = branch[branch.length - 1];
69
+ tree[toNull] = null;
70
+ }
71
+ /**
72
+ * Name of the child used in array to contain the description.
73
+ *
74
+ * Only used for list to contain the child description.
75
+ */
76
+ const ARRAY_CHILD_NAME = "index";
77
+ /**
78
+ *
79
+ * @param {QueryMetadata} nullable Description of the query and their nullability
80
+ * @param {ReadonlyArray<string | number>} paths path of the error location
81
+ * @returns {Array<string | number>} path of the branch to be made null
82
+ */
83
+ function findNullableAncestor(nullable, paths) {
84
+ let lastNullable = 0;
85
+ for (let i = 0; i < paths.length; ++i) {
86
+ const path = paths[i];
87
+ const child = nullable.children[typeof path === "string" ? path : ARRAY_CHILD_NAME];
88
+ if (!child) {
89
+ // Stopping the search since we reached a leaf node,
90
+ // the loop should be on its final iteration
91
+ break;
92
+ }
93
+ if (child.isNullable) {
94
+ lastNullable = i + 1;
95
+ }
96
+ nullable = child;
97
+ }
98
+ return paths.slice(0, lastNullable);
99
+ }
100
+ /**
101
+ * Produce a description of the query regarding its nullability.
102
+ *
103
+ * Leaf nodes are not present in this representation since they are not
104
+ * interesting for removing branches of the response tree.
105
+ *
106
+ * The structure is recursive like the query.
107
+ * @param {CompilationContext} compilationContext Execution content
108
+ * @returns {QueryMetadata} description of the query
109
+ */
110
+ function parseQueryNullables(compilationContext) {
111
+ const type = getOperationRootType(compilationContext.schema, compilationContext.operation);
112
+ const fields = collectFields(compilationContext, type, compilationContext.operation.selectionSet, Object.create(null), Object.create(null));
113
+ const properties = Object.create(null);
114
+ for (const responseName of Object.keys(fields)) {
115
+ const fieldType = resolveFieldDef(compilationContext, type, fields[responseName]);
116
+ if (!fieldType) {
117
+ // if field does not exist, it should be ignored for compatibility concerns.
118
+ // Usually, validation would stop it before getting here but this could be an old query
119
+ continue;
120
+ }
121
+ const property = transformNode(compilationContext, fields[responseName], fieldType.type);
122
+ if (property != null) {
123
+ properties[responseName] = property;
124
+ }
125
+ }
126
+ return {
127
+ isNullable: true,
128
+ children: properties
129
+ };
130
+ }
131
+ /**
132
+ * Processes a single node to produce a description of itself and its children.
133
+ *
134
+ * Leaf nodes are ignore and removed from the description
135
+ * @param {CompilationContext} compilationContext
136
+ * @param {FieldNode[]} fieldNodes list of fields
137
+ * @param {GraphQLType} type Current type being processed.
138
+ * @returns {QueryMetadata | null} null if node is a leaf, otherwise a description of the node and its children.
139
+ */
140
+ function transformNode(compilationContext, fieldNodes, type) {
141
+ if (isNonNullType(type)) {
142
+ const nullable = transformNode(compilationContext, fieldNodes, type.ofType);
143
+ if (nullable != null) {
144
+ nullable.isNullable = false;
145
+ return nullable;
146
+ }
147
+ return null;
148
+ }
149
+ if (isObjectType(type)) {
150
+ const subfields = collectSubfields(compilationContext, type, fieldNodes);
151
+ const properties = Object.create(null);
152
+ for (const responseName of Object.keys(subfields)) {
153
+ const fieldType = resolveFieldDef(compilationContext, type, subfields[responseName]);
154
+ if (!fieldType) {
155
+ // if field does not exist, it should be ignored for compatibility concerns.
156
+ // Usually, validation would stop it before getting here but this could be an old query
157
+ continue;
158
+ }
159
+ const property = transformNode(compilationContext, subfields[responseName], fieldType.type);
160
+ if (property != null) {
161
+ properties[responseName] = property;
162
+ }
163
+ }
164
+ return {
165
+ isNullable: true,
166
+ children: properties
167
+ };
168
+ }
169
+ if (isListType(type)) {
170
+ const child = transformNode(compilationContext, fieldNodes, type.ofType);
171
+ if (child != null) {
172
+ return {
173
+ isNullable: true,
174
+ children: { [ARRAY_CHILD_NAME]: child }
175
+ };
176
+ }
177
+ return {
178
+ isNullable: true,
179
+ children: {}
180
+ };
181
+ }
182
+ if (isAbstractType(type)) {
183
+ return compilationContext.schema.getPossibleTypes(type).reduce((res, t) => {
184
+ const property = transformNode(compilationContext, fieldNodes, t);
185
+ if (property != null) {
186
+ // We do a deep merge because children can have subset of properties
187
+ // TODO: Possible bug: two object with different nullability on objects.
188
+ res.children = merge(res.children, property.children);
189
+ }
190
+ return res;
191
+ }, {
192
+ isNullable: true,
193
+ children: {}
194
+ });
195
+ }
196
+ // Scalars and enum are ignored since they are leaf values
197
+ return null;
198
+ }
199
+ //# 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": "module"
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,224 @@
1
+ import { genFn } from "./generate.js";
2
+ import { doTypesOverlap, GraphQLError, isAbstractType, isCompositeType, isListType, isNonNullType, isObjectType, isUnionType, Kind } from "graphql";
3
+ import memoize from "lodash.memoize";
4
+ import mergeWith from "lodash.mergewith";
5
+ import { memoize2, memoize4 } from "./memoize.js";
6
+ const LeafFieldSymbol = Symbol("LeafFieldSymbol");
7
+ function createLeafField(props) {
8
+ return {
9
+ [LeafFieldSymbol]: true,
10
+ ...props
11
+ };
12
+ }
13
+ export function isLeafField(obj) {
14
+ return (obj != null && Object.prototype.hasOwnProperty.call(obj, LeafFieldSymbol));
15
+ }
16
+ /**
17
+ * Compute the GraphQLJitResolveInfo's `fieldExpansion` and return a function
18
+ * that returns the computed resolveInfo. This thunk is registered in
19
+ * context.dependencies for the field's resolveInfoName
20
+ */
21
+ export function createResolveInfoThunk({ schema, fragments, operation, parentType, fieldName, fieldType, fieldNodes }, enricher) {
22
+ let enrichedInfo = {};
23
+ if (typeof enricher === "function") {
24
+ enrichedInfo =
25
+ enricher({
26
+ fieldName,
27
+ fieldNodes,
28
+ returnType: fieldType,
29
+ parentType,
30
+ schema,
31
+ fragments,
32
+ operation
33
+ }) || {};
34
+ if (typeof enrichedInfo !== "object" || Array.isArray(enrichedInfo)) {
35
+ enrichedInfo = {};
36
+ }
37
+ }
38
+ const gen = genFn();
39
+ gen(`return function getGraphQLResolveInfo(rootValue, variableValues, path) {
40
+ return {
41
+ fieldName,
42
+ fieldNodes,
43
+ returnType: fieldType,
44
+ parentType,
45
+ path,
46
+ schema,
47
+ fragments,
48
+ rootValue,
49
+ operation,
50
+ variableValues,`);
51
+ Object.keys(enrichedInfo).forEach((key) => {
52
+ gen(`${key}: enrichedInfo["${key}"],\n`);
53
+ });
54
+ gen(`};};`);
55
+ // eslint-disable-next-line
56
+ return new Function("fieldName", "fieldNodes", "fieldType", "parentType", "schema", "fragments", "operation", "enrichedInfo", gen.toString()).call(null, fieldName, fieldNodes, fieldType, parentType, schema, fragments, operation, enrichedInfo);
57
+ }
58
+ export function fieldExpansionEnricher(input) {
59
+ const { schema, fragments, returnType, fieldNodes } = input;
60
+ const fieldExpansion = {};
61
+ for (const fieldNode of fieldNodes) {
62
+ deepMerge(fieldExpansion, memoizedExpandFieldNode(schema, fragments, fieldNode, returnType));
63
+ }
64
+ return {
65
+ fieldExpansion
66
+ };
67
+ }
68
+ const MEMOIZATION = true;
69
+ const memoizedGetReturnType = MEMOIZATION
70
+ ? memoize2(getReturnType)
71
+ : getReturnType;
72
+ const memoizedHasField = MEMOIZATION ? memoize2(hasField) : hasField;
73
+ const memoizedResolveEndType = MEMOIZATION
74
+ ? memoize(resolveEndType)
75
+ : resolveEndType;
76
+ const memoizedGetPossibleTypes = MEMOIZATION
77
+ ? memoize2(getPossibleTypes)
78
+ : getPossibleTypes;
79
+ const memoizedExpandFieldNodeType = MEMOIZATION
80
+ ? memoize4(expandFieldNodeType)
81
+ : expandFieldNodeType;
82
+ const memoizedExpandFieldNode = MEMOIZATION
83
+ ? memoize4(expandFieldNode)
84
+ : expandFieldNode;
85
+ function expandFieldNode(schema, fragments, node, fieldType) {
86
+ if (node.selectionSet == null) {
87
+ return createLeafField({});
88
+ }
89
+ // there is a selectionSet which makes the fieldType a CompositeType
90
+ const typ = memoizedResolveEndType(fieldType);
91
+ const possibleTypes = memoizedGetPossibleTypes(schema, typ);
92
+ const fieldExpansion = {};
93
+ for (const possibleType of possibleTypes) {
94
+ if (!isUnionType(possibleType)) {
95
+ fieldExpansion[possibleType.name] = memoizedExpandFieldNodeType(schema, fragments, possibleType, node.selectionSet);
96
+ }
97
+ }
98
+ return fieldExpansion;
99
+ }
100
+ function expandFieldNodeType(schema, fragments, parentType, selectionSet) {
101
+ const typeExpansion = {};
102
+ for (const selection of selectionSet.selections) {
103
+ if (selection.kind === Kind.FIELD) {
104
+ if (!isUnionType(parentType) &&
105
+ memoizedHasField(parentType, selection.name.value)) {
106
+ typeExpansion[selection.name.value] = memoizedExpandFieldNode(schema, fragments, selection, memoizedGetReturnType(parentType, selection.name.value));
107
+ }
108
+ }
109
+ else {
110
+ const selectionSet = selection.kind === Kind.INLINE_FRAGMENT
111
+ ? selection.selectionSet
112
+ : fragments[selection.name.value].selectionSet;
113
+ const nextType = selection.kind === Kind.INLINE_FRAGMENT
114
+ ? selection.typeCondition
115
+ ? schema.getType(selection.typeCondition.name.value)
116
+ : parentType
117
+ : schema.getType(fragments[selection.name.value].typeCondition.name.value);
118
+ /**
119
+ * nextType (comes from query) is the type extracted from the fragment
120
+ * parentType (comes from schema) is the possibleType for which we are filling fields
121
+ *
122
+ * if the type from query (nextType) is the same as the type we are filling (parentType)
123
+ * or
124
+ * if the type from query (nextType) is an abstract type - this case is when we jump
125
+ * to a super type or sub type. Here we maintain the context (parentType) for which
126
+ * we are filling the fields. The super type / sub type will be filled in its own
127
+ * pass.
128
+ */
129
+ if (nextType === parentType || isAbstractType(nextType)) {
130
+ deepMerge(typeExpansion, memoizedExpandFieldNodeType(schema, fragments, parentType, selectionSet));
131
+ }
132
+ }
133
+ }
134
+ return typeExpansion;
135
+ }
136
+ /**
137
+ * Returns a list of Possible types that one can get to from the
138
+ * resolvedType. As an analogy, these are the same types that one
139
+ * can use in a fragment's typeCondition.
140
+ *
141
+ * Note: This is different from schema.getPossibleTypes() that this
142
+ * returns all possible types and not just the ones from the type definition.
143
+ *
144
+ * Example:
145
+ * interface Node {
146
+ * id: ID!
147
+ * }
148
+ * type User implements Node {
149
+ * id: ID!
150
+ * name: String
151
+ * }
152
+ * type Article implements Node {
153
+ * id: ID!
154
+ * title: String
155
+ * }
156
+ * union Card = User | Article
157
+ *
158
+ * - schema.getPossibleTypes(Card) would give [User, Article]
159
+ * - This function getPossibleTypes(schema, Card) would give [User, Article, Node]
160
+ *
161
+ */
162
+ function getPossibleTypes(schema, compositeType) {
163
+ if (isObjectType(compositeType)) {
164
+ return [compositeType];
165
+ }
166
+ const possibleTypes = [];
167
+ const types = schema.getTypeMap();
168
+ for (const typeName in types) {
169
+ if (Object.prototype.hasOwnProperty.call(types, typeName)) {
170
+ const typ = types[typeName];
171
+ if (isCompositeType(typ) && doTypesOverlap(schema, typ, compositeType)) {
172
+ possibleTypes.push(typ);
173
+ }
174
+ }
175
+ }
176
+ return possibleTypes;
177
+ }
178
+ /**
179
+ * Given an (Object|Interface)Type, and a fieldName, find the
180
+ * appropriate `end` return type for the field in the Composite Type.
181
+ *
182
+ * Note: The `end` return type is the type by unwrapping non-null types
183
+ * and list types. Check `resolveEndType`
184
+ */
185
+ function getReturnType(parentType, fieldName) {
186
+ const fields = parentType.getFields();
187
+ if (!Object.prototype.hasOwnProperty.call(fields, fieldName)) {
188
+ throw new GraphQLError(`Field "${fieldName}" does not exist in "${parentType.name}"`);
189
+ }
190
+ const outputType = fields[fieldName].type;
191
+ return memoizedResolveEndType(outputType);
192
+ }
193
+ /**
194
+ * Resolve to the end type of the Output type unwrapping non-null types and lists
195
+ */
196
+ function resolveEndType(typ) {
197
+ if (isListType(typ) || isNonNullType(typ)) {
198
+ return memoizedResolveEndType(typ.ofType);
199
+ }
200
+ return typ;
201
+ }
202
+ function hasField(typ, fieldName) {
203
+ return Object.prototype.hasOwnProperty.call(typ.getFields(), fieldName);
204
+ }
205
+ // This is because lodash does not support merging keys
206
+ // which are symbols. We require them for leaf fields
207
+ function deepMerge(obj, src) {
208
+ mergeWith(obj, src, (objValue, srcValue) => {
209
+ if (isLeafField(objValue)) {
210
+ if (isLeafField(srcValue)) {
211
+ return {
212
+ ...objValue,
213
+ ...srcValue
214
+ };
215
+ }
216
+ return objValue;
217
+ }
218
+ else if (isLeafField(srcValue)) {
219
+ return srcValue;
220
+ }
221
+ return undefined;
222
+ });
223
+ }
224
+ //# 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 {};
@@ -0,0 +1,89 @@
1
+ function resolvePromise(ctx, promise, onSuccess, onError) {
2
+ ++ctx.promiseCounter;
3
+ promise.then((result) => {
4
+ onSuccess(result);
5
+ --ctx.promiseCounter;
6
+ if (ctx.promiseCounter === 0)
7
+ ctx.resolve(ctx);
8
+ }, (err) => {
9
+ onError(err);
10
+ --ctx.promiseCounter;
11
+ if (ctx.promiseCounter === 0)
12
+ ctx.resolve(ctx);
13
+ });
14
+ }
15
+ export const jitRuntime = {
16
+ isPromise(value) {
17
+ return (value != null &&
18
+ typeof value === "object" &&
19
+ typeof value.then === "function");
20
+ },
21
+ checkNonNullLeaf(ctx, value, dest, nullMsg, locs, path, capStack, serialize, errHandler, ...parentIndexes) {
22
+ const GQLError = ctx.GraphQLError;
23
+ if (value == null) {
24
+ dest.push(new GQLError(nullMsg, locs, path, undefined, capStack));
25
+ return null;
26
+ }
27
+ if (value instanceof Error) {
28
+ dest.push(new GQLError(value.message ?? value, locs, path, value, capStack));
29
+ return null;
30
+ }
31
+ return serialize(ctx, value, errHandler, ...parentIndexes);
32
+ },
33
+ checkNullableLeaf(ctx, value, dest, locs, path, capStack, serialize, errHandler, ...parentIndexes) {
34
+ if (value == null)
35
+ return null;
36
+ const GQLError = ctx.GraphQLError;
37
+ if (value instanceof Error) {
38
+ dest.push(new GQLError(value.message ?? value, locs, path, value, capStack));
39
+ return null;
40
+ }
41
+ return serialize(ctx, value, errHandler, ...parentIndexes);
42
+ },
43
+ callResolver(ctx, call, onSuccess, onError) {
44
+ let value;
45
+ try {
46
+ value = call();
47
+ }
48
+ catch (err) {
49
+ onError(err);
50
+ onSuccess(null);
51
+ return;
52
+ }
53
+ this.handleResolverResult(ctx, value, onSuccess, onError);
54
+ },
55
+ handleResolverResult(ctx, value, onSuccess, onError) {
56
+ if (this.isPromise(value)) {
57
+ resolvePromise(ctx, value, onSuccess, onError);
58
+ }
59
+ else {
60
+ onSuccess(value);
61
+ }
62
+ },
63
+ handleListItemResult(ctx, item, onSuccess, onError) {
64
+ if (this.isPromise(item)) {
65
+ resolvePromise(ctx, item, onSuccess, onError);
66
+ }
67
+ else {
68
+ onSuccess(item);
69
+ }
70
+ },
71
+ finalizeResult(ctx) {
72
+ if (ctx.promiseCounter > 0) {
73
+ return new Promise((resolve) => {
74
+ ctx.resolve = resolve;
75
+ });
76
+ }
77
+ return undefined;
78
+ },
79
+ safeMap(ctx, iterable, cb, ...idx) {
80
+ let index = 0;
81
+ const result = [];
82
+ for (const a of iterable) {
83
+ cb(ctx, a, index, result, ...idx);
84
+ ++index;
85
+ }
86
+ return result;
87
+ }
88
+ };
89
+ //# sourceMappingURL=runtime.js.map