@depup/apollo__server 5.5.0-depup.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 (557) hide show
  1. package/README.md +40 -0
  2. package/changes.json +46 -0
  3. package/dist/cjs/ApolloServer.d.ts +126 -0
  4. package/dist/cjs/ApolloServer.d.ts.map +1 -0
  5. package/dist/cjs/ApolloServer.js +726 -0
  6. package/dist/cjs/ApolloServer.js.map +1 -0
  7. package/dist/cjs/cachePolicy.d.ts +3 -0
  8. package/dist/cjs/cachePolicy.d.ts.map +1 -0
  9. package/dist/cjs/cachePolicy.js +33 -0
  10. package/dist/cjs/cachePolicy.js.map +1 -0
  11. package/dist/cjs/determineApolloConfig.d.ts +4 -0
  12. package/dist/cjs/determineApolloConfig.d.ts.map +1 -0
  13. package/dist/cjs/determineApolloConfig.js +58 -0
  14. package/dist/cjs/determineApolloConfig.js.map +1 -0
  15. package/dist/cjs/errorNormalize.d.ts +12 -0
  16. package/dist/cjs/errorNormalize.d.ts.map +1 -0
  17. package/dist/cjs/errorNormalize.js +71 -0
  18. package/dist/cjs/errorNormalize.js.map +1 -0
  19. package/dist/cjs/errors/index.d.ts +16 -0
  20. package/dist/cjs/errors/index.d.ts.map +1 -0
  21. package/dist/cjs/errors/index.js +28 -0
  22. package/dist/cjs/errors/index.js.map +1 -0
  23. package/dist/cjs/externalTypes/constructor.d.ts +78 -0
  24. package/dist/cjs/externalTypes/constructor.d.ts.map +1 -0
  25. package/dist/cjs/externalTypes/constructor.js +3 -0
  26. package/dist/cjs/externalTypes/constructor.js.map +1 -0
  27. package/dist/cjs/externalTypes/context.d.ts +4 -0
  28. package/dist/cjs/externalTypes/context.d.ts.map +1 -0
  29. package/dist/cjs/externalTypes/context.js +3 -0
  30. package/dist/cjs/externalTypes/context.js.map +1 -0
  31. package/dist/cjs/externalTypes/graphql.d.ts +41 -0
  32. package/dist/cjs/externalTypes/graphql.d.ts.map +1 -0
  33. package/dist/cjs/externalTypes/graphql.js +3 -0
  34. package/dist/cjs/externalTypes/graphql.js.map +1 -0
  35. package/dist/cjs/externalTypes/http.d.ts +22 -0
  36. package/dist/cjs/externalTypes/http.d.ts.map +1 -0
  37. package/dist/cjs/externalTypes/http.js +3 -0
  38. package/dist/cjs/externalTypes/http.js.map +1 -0
  39. package/dist/cjs/externalTypes/incrementalDeliveryPolyfillAlpha2.d.ts +28 -0
  40. package/dist/cjs/externalTypes/incrementalDeliveryPolyfillAlpha2.d.ts.map +1 -0
  41. package/dist/cjs/externalTypes/incrementalDeliveryPolyfillAlpha2.js +3 -0
  42. package/dist/cjs/externalTypes/incrementalDeliveryPolyfillAlpha2.js.map +1 -0
  43. package/dist/cjs/externalTypes/incrementalDeliveryPolyfillAlpha9.d.ts +43 -0
  44. package/dist/cjs/externalTypes/incrementalDeliveryPolyfillAlpha9.d.ts.map +1 -0
  45. package/dist/cjs/externalTypes/incrementalDeliveryPolyfillAlpha9.js +3 -0
  46. package/dist/cjs/externalTypes/incrementalDeliveryPolyfillAlpha9.js.map +1 -0
  47. package/dist/cjs/externalTypes/index.d.ts +9 -0
  48. package/dist/cjs/externalTypes/index.d.ts.map +1 -0
  49. package/dist/cjs/externalTypes/index.js +3 -0
  50. package/dist/cjs/externalTypes/index.js.map +1 -0
  51. package/dist/cjs/externalTypes/plugins.d.ts +75 -0
  52. package/dist/cjs/externalTypes/plugins.d.ts.map +1 -0
  53. package/dist/cjs/externalTypes/plugins.js +3 -0
  54. package/dist/cjs/externalTypes/plugins.js.map +1 -0
  55. package/dist/cjs/externalTypes/requestPipeline.d.ts +50 -0
  56. package/dist/cjs/externalTypes/requestPipeline.d.ts.map +1 -0
  57. package/dist/cjs/externalTypes/requestPipeline.js +3 -0
  58. package/dist/cjs/externalTypes/requestPipeline.js.map +1 -0
  59. package/dist/cjs/generated/packageVersion.d.ts +2 -0
  60. package/dist/cjs/generated/packageVersion.d.ts.map +1 -0
  61. package/dist/cjs/generated/packageVersion.js +5 -0
  62. package/dist/cjs/generated/packageVersion.js.map +1 -0
  63. package/dist/cjs/httpBatching.d.ts +4 -0
  64. package/dist/cjs/httpBatching.d.ts.map +1 -0
  65. package/dist/cjs/httpBatching.js +58 -0
  66. package/dist/cjs/httpBatching.js.map +1 -0
  67. package/dist/cjs/incrementalDeliveryPolyfill.d.ts +82 -0
  68. package/dist/cjs/incrementalDeliveryPolyfill.d.ts.map +1 -0
  69. package/dist/cjs/incrementalDeliveryPolyfill.js +74 -0
  70. package/dist/cjs/incrementalDeliveryPolyfill.js.map +1 -0
  71. package/dist/cjs/index.d.ts +4 -0
  72. package/dist/cjs/index.d.ts.map +1 -0
  73. package/dist/cjs/index.js +23 -0
  74. package/dist/cjs/index.js.map +1 -0
  75. package/dist/cjs/internalErrorClasses.d.ts +28 -0
  76. package/dist/cjs/internalErrorClasses.d.ts.map +1 -0
  77. package/dist/cjs/internalErrorClasses.js +91 -0
  78. package/dist/cjs/internalErrorClasses.js.map +1 -0
  79. package/dist/cjs/internalPlugin.d.ts +9 -0
  80. package/dist/cjs/internalPlugin.d.ts.map +1 -0
  81. package/dist/cjs/internalPlugin.js +11 -0
  82. package/dist/cjs/internalPlugin.js.map +1 -0
  83. package/dist/cjs/package.json +1 -0
  84. package/dist/cjs/plugin/cacheControl/index.d.ts +9 -0
  85. package/dist/cjs/plugin/cacheControl/index.d.ts.map +1 -0
  86. package/dist/cjs/plugin/cacheControl/index.js +223 -0
  87. package/dist/cjs/plugin/cacheControl/index.js.map +1 -0
  88. package/dist/cjs/plugin/disableSuggestions/index.d.ts +3 -0
  89. package/dist/cjs/plugin/disableSuggestions/index.d.ts.map +1 -0
  90. package/dist/cjs/plugin/disableSuggestions/index.js +22 -0
  91. package/dist/cjs/plugin/disableSuggestions/index.js.map +1 -0
  92. package/dist/cjs/plugin/disabled/index.d.ts +7 -0
  93. package/dist/cjs/plugin/disabled/index.d.ts.map +1 -0
  94. package/dist/cjs/plugin/disabled/index.js +30 -0
  95. package/dist/cjs/plugin/disabled/index.js.map +1 -0
  96. package/dist/cjs/plugin/drainHttpServer/index.d.ts +8 -0
  97. package/dist/cjs/plugin/drainHttpServer/index.d.ts.map +1 -0
  98. package/dist/cjs/plugin/drainHttpServer/index.js +19 -0
  99. package/dist/cjs/plugin/drainHttpServer/index.js.map +1 -0
  100. package/dist/cjs/plugin/drainHttpServer/stoppable.d.ts +10 -0
  101. package/dist/cjs/plugin/drainHttpServer/stoppable.d.ts.map +1 -0
  102. package/dist/cjs/plugin/drainHttpServer/stoppable.js +54 -0
  103. package/dist/cjs/plugin/drainHttpServer/stoppable.js.map +1 -0
  104. package/dist/cjs/plugin/inlineTrace/index.d.ts +8 -0
  105. package/dist/cjs/plugin/inlineTrace/index.d.ts.map +1 -0
  106. package/dist/cjs/plugin/inlineTrace/index.js +70 -0
  107. package/dist/cjs/plugin/inlineTrace/index.js.map +1 -0
  108. package/dist/cjs/plugin/landingPage/default/getEmbeddedHTML.d.ts +4 -0
  109. package/dist/cjs/plugin/landingPage/default/getEmbeddedHTML.d.ts.map +1 -0
  110. package/dist/cjs/plugin/landingPage/default/getEmbeddedHTML.js +143 -0
  111. package/dist/cjs/plugin/landingPage/default/getEmbeddedHTML.js.map +1 -0
  112. package/dist/cjs/plugin/landingPage/default/index.d.ts +9 -0
  113. package/dist/cjs/plugin/landingPage/default/index.d.ts.map +1 -0
  114. package/dist/cjs/plugin/landingPage/default/index.js +146 -0
  115. package/dist/cjs/plugin/landingPage/default/index.js.map +1 -0
  116. package/dist/cjs/plugin/landingPage/default/types.d.ts +56 -0
  117. package/dist/cjs/plugin/landingPage/default/types.d.ts.map +1 -0
  118. package/dist/cjs/plugin/landingPage/default/types.js +3 -0
  119. package/dist/cjs/plugin/landingPage/default/types.js.map +1 -0
  120. package/dist/cjs/plugin/schemaIsSubgraph.d.ts +3 -0
  121. package/dist/cjs/plugin/schemaIsSubgraph.d.ts.map +1 -0
  122. package/dist/cjs/plugin/schemaIsSubgraph.js +23 -0
  123. package/dist/cjs/plugin/schemaIsSubgraph.js.map +1 -0
  124. package/dist/cjs/plugin/schemaReporting/index.d.ts +10 -0
  125. package/dist/cjs/plugin/schemaReporting/index.d.ts.map +1 -0
  126. package/dist/cjs/plugin/schemaReporting/index.js +104 -0
  127. package/dist/cjs/plugin/schemaReporting/index.js.map +1 -0
  128. package/dist/cjs/plugin/schemaReporting/schemaReporter.d.ts +33 -0
  129. package/dist/cjs/plugin/schemaReporting/schemaReporter.d.ts.map +1 -0
  130. package/dist/cjs/plugin/schemaReporting/schemaReporter.js +147 -0
  131. package/dist/cjs/plugin/schemaReporting/schemaReporter.js.map +1 -0
  132. package/dist/cjs/plugin/subscriptionCallback/index.d.ts +12 -0
  133. package/dist/cjs/plugin/subscriptionCallback/index.d.ts.map +1 -0
  134. package/dist/cjs/plugin/subscriptionCallback/index.js +434 -0
  135. package/dist/cjs/plugin/subscriptionCallback/index.js.map +1 -0
  136. package/dist/cjs/plugin/traceTreeBuilder.d.ts +25 -0
  137. package/dist/cjs/plugin/traceTreeBuilder.d.ts.map +1 -0
  138. package/dist/cjs/plugin/traceTreeBuilder.js +201 -0
  139. package/dist/cjs/plugin/traceTreeBuilder.js.map +1 -0
  140. package/dist/cjs/plugin/usageReporting/defaultSendOperationsAsTrace.d.ts +3 -0
  141. package/dist/cjs/plugin/usageReporting/defaultSendOperationsAsTrace.d.ts.map +1 -0
  142. package/dist/cjs/plugin/usageReporting/defaultSendOperationsAsTrace.js +44 -0
  143. package/dist/cjs/plugin/usageReporting/defaultSendOperationsAsTrace.js.map +1 -0
  144. package/dist/cjs/plugin/usageReporting/durationHistogram.d.ts +16 -0
  145. package/dist/cjs/plugin/usageReporting/durationHistogram.d.ts.map +1 -0
  146. package/dist/cjs/plugin/usageReporting/durationHistogram.js +68 -0
  147. package/dist/cjs/plugin/usageReporting/durationHistogram.js.map +1 -0
  148. package/dist/cjs/plugin/usageReporting/index.d.ts +3 -0
  149. package/dist/cjs/plugin/usageReporting/index.d.ts.map +1 -0
  150. package/dist/cjs/plugin/usageReporting/index.js +6 -0
  151. package/dist/cjs/plugin/usageReporting/index.js.map +1 -0
  152. package/dist/cjs/plugin/usageReporting/iterateOverTrace.d.ts +7 -0
  153. package/dist/cjs/plugin/usageReporting/iterateOverTrace.d.ts.map +1 -0
  154. package/dist/cjs/plugin/usageReporting/iterateOverTrace.js +81 -0
  155. package/dist/cjs/plugin/usageReporting/iterateOverTrace.js.map +1 -0
  156. package/dist/cjs/plugin/usageReporting/operationDerivedDataCache.d.ts +12 -0
  157. package/dist/cjs/plugin/usageReporting/operationDerivedDataCache.d.ts.map +1 -0
  158. package/dist/cjs/plugin/usageReporting/operationDerivedDataCache.js +33 -0
  159. package/dist/cjs/plugin/usageReporting/operationDerivedDataCache.js.map +1 -0
  160. package/dist/cjs/plugin/usageReporting/options.d.ts +60 -0
  161. package/dist/cjs/plugin/usageReporting/options.d.ts.map +1 -0
  162. package/dist/cjs/plugin/usageReporting/options.js +3 -0
  163. package/dist/cjs/plugin/usageReporting/options.js.map +1 -0
  164. package/dist/cjs/plugin/usageReporting/plugin.d.ts +7 -0
  165. package/dist/cjs/plugin/usageReporting/plugin.d.ts.map +1 -0
  166. package/dist/cjs/plugin/usageReporting/plugin.js +494 -0
  167. package/dist/cjs/plugin/usageReporting/plugin.js.map +1 -0
  168. package/dist/cjs/plugin/usageReporting/stats.d.ts +96 -0
  169. package/dist/cjs/plugin/usageReporting/stats.d.ts.map +1 -0
  170. package/dist/cjs/plugin/usageReporting/stats.js +289 -0
  171. package/dist/cjs/plugin/usageReporting/stats.js.map +1 -0
  172. package/dist/cjs/plugin/usageReporting/traceDetails.d.ts +4 -0
  173. package/dist/cjs/plugin/usageReporting/traceDetails.d.ts.map +1 -0
  174. package/dist/cjs/plugin/usageReporting/traceDetails.js +63 -0
  175. package/dist/cjs/plugin/usageReporting/traceDetails.js.map +1 -0
  176. package/dist/cjs/preventCsrf.d.ts +4 -0
  177. package/dist/cjs/preventCsrf.d.ts.map +1 -0
  178. package/dist/cjs/preventCsrf.js +41 -0
  179. package/dist/cjs/preventCsrf.js.map +1 -0
  180. package/dist/cjs/requestPipeline.d.ts +9 -0
  181. package/dist/cjs/requestPipeline.d.ts.map +1 -0
  182. package/dist/cjs/requestPipeline.js +371 -0
  183. package/dist/cjs/requestPipeline.js.map +1 -0
  184. package/dist/cjs/runHttpQuery.d.ts +15 -0
  185. package/dist/cjs/runHttpQuery.d.ts.map +1 -0
  186. package/dist/cjs/runHttpQuery.js +230 -0
  187. package/dist/cjs/runHttpQuery.js.map +1 -0
  188. package/dist/cjs/standalone/index.d.ts +25 -0
  189. package/dist/cjs/standalone/index.d.ts.map +1 -0
  190. package/dist/cjs/standalone/index.js +97 -0
  191. package/dist/cjs/standalone/index.js.map +1 -0
  192. package/dist/cjs/utils/HeaderMap.d.ts +8 -0
  193. package/dist/cjs/utils/HeaderMap.d.ts.map +1 -0
  194. package/dist/cjs/utils/HeaderMap.js +20 -0
  195. package/dist/cjs/utils/HeaderMap.js.map +1 -0
  196. package/dist/cjs/utils/UnreachableCaseError.d.ts +4 -0
  197. package/dist/cjs/utils/UnreachableCaseError.d.ts.map +1 -0
  198. package/dist/cjs/utils/UnreachableCaseError.js +10 -0
  199. package/dist/cjs/utils/UnreachableCaseError.js.map +1 -0
  200. package/dist/cjs/utils/computeCoreSchemaHash.d.ts +2 -0
  201. package/dist/cjs/utils/computeCoreSchemaHash.d.ts.map +1 -0
  202. package/dist/cjs/utils/computeCoreSchemaHash.js +8 -0
  203. package/dist/cjs/utils/computeCoreSchemaHash.js.map +1 -0
  204. package/dist/cjs/utils/invokeHooks.d.ts +7 -0
  205. package/dist/cjs/utils/invokeHooks.d.ts.map +1 -0
  206. package/dist/cjs/utils/invokeHooks.js +36 -0
  207. package/dist/cjs/utils/invokeHooks.js.map +1 -0
  208. package/dist/cjs/utils/isDefined.d.ts +2 -0
  209. package/dist/cjs/utils/isDefined.d.ts.map +1 -0
  210. package/dist/cjs/utils/isDefined.js +7 -0
  211. package/dist/cjs/utils/isDefined.js.map +1 -0
  212. package/dist/cjs/utils/makeGatewayGraphQLRequestContext.d.ts +5 -0
  213. package/dist/cjs/utils/makeGatewayGraphQLRequestContext.d.ts.map +1 -0
  214. package/dist/cjs/utils/makeGatewayGraphQLRequestContext.js +96 -0
  215. package/dist/cjs/utils/makeGatewayGraphQLRequestContext.js.map +1 -0
  216. package/dist/cjs/utils/resolvable.d.ts +7 -0
  217. package/dist/cjs/utils/resolvable.d.ts.map +1 -0
  218. package/dist/cjs/utils/resolvable.js +14 -0
  219. package/dist/cjs/utils/resolvable.js.map +1 -0
  220. package/dist/cjs/utils/schemaInstrumentation.d.ts +16 -0
  221. package/dist/cjs/utils/schemaInstrumentation.d.ts.map +1 -0
  222. package/dist/cjs/utils/schemaInstrumentation.js +75 -0
  223. package/dist/cjs/utils/schemaInstrumentation.js.map +1 -0
  224. package/dist/cjs/utils/schemaManager.d.ts +31 -0
  225. package/dist/cjs/utils/schemaManager.d.ts.map +1 -0
  226. package/dist/cjs/utils/schemaManager.js +103 -0
  227. package/dist/cjs/utils/schemaManager.js.map +1 -0
  228. package/dist/cjs/utils/urlForHttpServer.d.ts +3 -0
  229. package/dist/cjs/utils/urlForHttpServer.d.ts.map +1 -0
  230. package/dist/cjs/utils/urlForHttpServer.js +15 -0
  231. package/dist/cjs/utils/urlForHttpServer.js.map +1 -0
  232. package/dist/cjs/validationRules/NoIntrospection.d.ts +3 -0
  233. package/dist/cjs/validationRules/NoIntrospection.d.ts.map +1 -0
  234. package/dist/cjs/validationRules/NoIntrospection.js +19 -0
  235. package/dist/cjs/validationRules/NoIntrospection.js.map +1 -0
  236. package/dist/cjs/validationRules/RecursiveSelectionsLimit.d.ts +4 -0
  237. package/dist/cjs/validationRules/RecursiveSelectionsLimit.d.ts.map +1 -0
  238. package/dist/cjs/validationRules/RecursiveSelectionsLimit.js +150 -0
  239. package/dist/cjs/validationRules/RecursiveSelectionsLimit.js.map +1 -0
  240. package/dist/cjs/validationRules/index.d.ts +3 -0
  241. package/dist/cjs/validationRules/index.d.ts.map +1 -0
  242. package/dist/cjs/validationRules/index.js +9 -0
  243. package/dist/cjs/validationRules/index.js.map +1 -0
  244. package/dist/esm/ApolloServer.d.ts +126 -0
  245. package/dist/esm/ApolloServer.d.ts.map +1 -0
  246. package/dist/esm/ApolloServer.js +683 -0
  247. package/dist/esm/ApolloServer.js.map +1 -0
  248. package/dist/esm/cachePolicy.d.ts +3 -0
  249. package/dist/esm/cachePolicy.d.ts.map +1 -0
  250. package/dist/esm/cachePolicy.js +30 -0
  251. package/dist/esm/cachePolicy.js.map +1 -0
  252. package/dist/esm/determineApolloConfig.d.ts +4 -0
  253. package/dist/esm/determineApolloConfig.d.ts.map +1 -0
  254. package/dist/esm/determineApolloConfig.js +55 -0
  255. package/dist/esm/determineApolloConfig.js.map +1 -0
  256. package/dist/esm/errorNormalize.d.ts +12 -0
  257. package/dist/esm/errorNormalize.d.ts.map +1 -0
  258. package/dist/esm/errorNormalize.js +66 -0
  259. package/dist/esm/errorNormalize.js.map +1 -0
  260. package/dist/esm/errors/index.d.ts +16 -0
  261. package/dist/esm/errors/index.d.ts.map +1 -0
  262. package/dist/esm/errors/index.js +24 -0
  263. package/dist/esm/errors/index.js.map +1 -0
  264. package/dist/esm/externalTypes/constructor.d.ts +78 -0
  265. package/dist/esm/externalTypes/constructor.d.ts.map +1 -0
  266. package/dist/esm/externalTypes/constructor.js +2 -0
  267. package/dist/esm/externalTypes/constructor.js.map +1 -0
  268. package/dist/esm/externalTypes/context.d.ts +4 -0
  269. package/dist/esm/externalTypes/context.d.ts.map +1 -0
  270. package/dist/esm/externalTypes/context.js +2 -0
  271. package/dist/esm/externalTypes/context.js.map +1 -0
  272. package/dist/esm/externalTypes/graphql.d.ts +41 -0
  273. package/dist/esm/externalTypes/graphql.d.ts.map +1 -0
  274. package/dist/esm/externalTypes/graphql.js +2 -0
  275. package/dist/esm/externalTypes/graphql.js.map +1 -0
  276. package/dist/esm/externalTypes/http.d.ts +22 -0
  277. package/dist/esm/externalTypes/http.d.ts.map +1 -0
  278. package/dist/esm/externalTypes/http.js +2 -0
  279. package/dist/esm/externalTypes/http.js.map +1 -0
  280. package/dist/esm/externalTypes/incrementalDeliveryPolyfillAlpha2.d.ts +28 -0
  281. package/dist/esm/externalTypes/incrementalDeliveryPolyfillAlpha2.d.ts.map +1 -0
  282. package/dist/esm/externalTypes/incrementalDeliveryPolyfillAlpha2.js +2 -0
  283. package/dist/esm/externalTypes/incrementalDeliveryPolyfillAlpha2.js.map +1 -0
  284. package/dist/esm/externalTypes/incrementalDeliveryPolyfillAlpha9.d.ts +43 -0
  285. package/dist/esm/externalTypes/incrementalDeliveryPolyfillAlpha9.d.ts.map +1 -0
  286. package/dist/esm/externalTypes/incrementalDeliveryPolyfillAlpha9.js +2 -0
  287. package/dist/esm/externalTypes/incrementalDeliveryPolyfillAlpha9.js.map +1 -0
  288. package/dist/esm/externalTypes/index.d.ts +9 -0
  289. package/dist/esm/externalTypes/index.d.ts.map +1 -0
  290. package/dist/esm/externalTypes/index.js +2 -0
  291. package/dist/esm/externalTypes/index.js.map +1 -0
  292. package/dist/esm/externalTypes/plugins.d.ts +75 -0
  293. package/dist/esm/externalTypes/plugins.d.ts.map +1 -0
  294. package/dist/esm/externalTypes/plugins.js +2 -0
  295. package/dist/esm/externalTypes/plugins.js.map +1 -0
  296. package/dist/esm/externalTypes/requestPipeline.d.ts +50 -0
  297. package/dist/esm/externalTypes/requestPipeline.d.ts.map +1 -0
  298. package/dist/esm/externalTypes/requestPipeline.js +2 -0
  299. package/dist/esm/externalTypes/requestPipeline.js.map +1 -0
  300. package/dist/esm/generated/packageVersion.d.ts +2 -0
  301. package/dist/esm/generated/packageVersion.d.ts.map +1 -0
  302. package/dist/esm/generated/packageVersion.js +2 -0
  303. package/dist/esm/generated/packageVersion.js.map +1 -0
  304. package/dist/esm/httpBatching.d.ts +4 -0
  305. package/dist/esm/httpBatching.d.ts.map +1 -0
  306. package/dist/esm/httpBatching.js +55 -0
  307. package/dist/esm/httpBatching.js.map +1 -0
  308. package/dist/esm/incrementalDeliveryPolyfill.d.ts +82 -0
  309. package/dist/esm/incrementalDeliveryPolyfill.d.ts.map +1 -0
  310. package/dist/esm/incrementalDeliveryPolyfill.js +38 -0
  311. package/dist/esm/incrementalDeliveryPolyfill.js.map +1 -0
  312. package/dist/esm/index.d.ts +4 -0
  313. package/dist/esm/index.d.ts.map +1 -0
  314. package/dist/esm/index.js +4 -0
  315. package/dist/esm/index.js.map +1 -0
  316. package/dist/esm/internalErrorClasses.d.ts +28 -0
  317. package/dist/esm/internalErrorClasses.d.ts.map +1 -0
  318. package/dist/esm/internalErrorClasses.js +81 -0
  319. package/dist/esm/internalErrorClasses.js.map +1 -0
  320. package/dist/esm/internalPlugin.d.ts +9 -0
  321. package/dist/esm/internalPlugin.d.ts.map +1 -0
  322. package/dist/esm/internalPlugin.js +7 -0
  323. package/dist/esm/internalPlugin.js.map +1 -0
  324. package/dist/esm/package.json +1 -0
  325. package/dist/esm/plugin/cacheControl/index.d.ts +9 -0
  326. package/dist/esm/plugin/cacheControl/index.d.ts.map +1 -0
  327. package/dist/esm/plugin/cacheControl/index.js +220 -0
  328. package/dist/esm/plugin/cacheControl/index.js.map +1 -0
  329. package/dist/esm/plugin/disableSuggestions/index.d.ts +3 -0
  330. package/dist/esm/plugin/disableSuggestions/index.d.ts.map +1 -0
  331. package/dist/esm/plugin/disableSuggestions/index.js +19 -0
  332. package/dist/esm/plugin/disableSuggestions/index.js.map +1 -0
  333. package/dist/esm/plugin/disabled/index.d.ts +7 -0
  334. package/dist/esm/plugin/disabled/index.d.ts.map +1 -0
  335. package/dist/esm/plugin/disabled/index.js +23 -0
  336. package/dist/esm/plugin/disabled/index.js.map +1 -0
  337. package/dist/esm/plugin/drainHttpServer/index.d.ts +8 -0
  338. package/dist/esm/plugin/drainHttpServer/index.d.ts.map +1 -0
  339. package/dist/esm/plugin/drainHttpServer/index.js +16 -0
  340. package/dist/esm/plugin/drainHttpServer/index.js.map +1 -0
  341. package/dist/esm/plugin/drainHttpServer/stoppable.d.ts +10 -0
  342. package/dist/esm/plugin/drainHttpServer/stoppable.d.ts.map +1 -0
  343. package/dist/esm/plugin/drainHttpServer/stoppable.js +47 -0
  344. package/dist/esm/plugin/drainHttpServer/stoppable.js.map +1 -0
  345. package/dist/esm/plugin/inlineTrace/index.d.ts +8 -0
  346. package/dist/esm/plugin/inlineTrace/index.d.ts.map +1 -0
  347. package/dist/esm/plugin/inlineTrace/index.js +67 -0
  348. package/dist/esm/plugin/inlineTrace/index.js.map +1 -0
  349. package/dist/esm/plugin/landingPage/default/getEmbeddedHTML.d.ts +4 -0
  350. package/dist/esm/plugin/landingPage/default/getEmbeddedHTML.d.ts.map +1 -0
  351. package/dist/esm/plugin/landingPage/default/getEmbeddedHTML.js +138 -0
  352. package/dist/esm/plugin/landingPage/default/getEmbeddedHTML.js.map +1 -0
  353. package/dist/esm/plugin/landingPage/default/index.d.ts +9 -0
  354. package/dist/esm/plugin/landingPage/default/index.d.ts.map +1 -0
  355. package/dist/esm/plugin/landingPage/default/index.js +141 -0
  356. package/dist/esm/plugin/landingPage/default/index.js.map +1 -0
  357. package/dist/esm/plugin/landingPage/default/types.d.ts +56 -0
  358. package/dist/esm/plugin/landingPage/default/types.d.ts.map +1 -0
  359. package/dist/esm/plugin/landingPage/default/types.js +2 -0
  360. package/dist/esm/plugin/landingPage/default/types.js.map +1 -0
  361. package/dist/esm/plugin/schemaIsSubgraph.d.ts +3 -0
  362. package/dist/esm/plugin/schemaIsSubgraph.d.ts.map +1 -0
  363. package/dist/esm/plugin/schemaIsSubgraph.js +20 -0
  364. package/dist/esm/plugin/schemaIsSubgraph.js.map +1 -0
  365. package/dist/esm/plugin/schemaReporting/index.d.ts +10 -0
  366. package/dist/esm/plugin/schemaReporting/index.d.ts.map +1 -0
  367. package/dist/esm/plugin/schemaReporting/index.js +98 -0
  368. package/dist/esm/plugin/schemaReporting/index.js.map +1 -0
  369. package/dist/esm/plugin/schemaReporting/schemaReporter.d.ts +33 -0
  370. package/dist/esm/plugin/schemaReporting/schemaReporter.d.ts.map +1 -0
  371. package/dist/esm/plugin/schemaReporting/schemaReporter.js +143 -0
  372. package/dist/esm/plugin/schemaReporting/schemaReporter.js.map +1 -0
  373. package/dist/esm/plugin/subscriptionCallback/index.d.ts +12 -0
  374. package/dist/esm/plugin/subscriptionCallback/index.d.ts.map +1 -0
  375. package/dist/esm/plugin/subscriptionCallback/index.js +428 -0
  376. package/dist/esm/plugin/subscriptionCallback/index.js.map +1 -0
  377. package/dist/esm/plugin/traceTreeBuilder.d.ts +25 -0
  378. package/dist/esm/plugin/traceTreeBuilder.d.ts.map +1 -0
  379. package/dist/esm/plugin/traceTreeBuilder.js +196 -0
  380. package/dist/esm/plugin/traceTreeBuilder.js.map +1 -0
  381. package/dist/esm/plugin/usageReporting/defaultSendOperationsAsTrace.d.ts +3 -0
  382. package/dist/esm/plugin/usageReporting/defaultSendOperationsAsTrace.d.ts.map +1 -0
  383. package/dist/esm/plugin/usageReporting/defaultSendOperationsAsTrace.js +41 -0
  384. package/dist/esm/plugin/usageReporting/defaultSendOperationsAsTrace.js.map +1 -0
  385. package/dist/esm/plugin/usageReporting/durationHistogram.d.ts +16 -0
  386. package/dist/esm/plugin/usageReporting/durationHistogram.d.ts.map +1 -0
  387. package/dist/esm/plugin/usageReporting/durationHistogram.js +64 -0
  388. package/dist/esm/plugin/usageReporting/durationHistogram.js.map +1 -0
  389. package/dist/esm/plugin/usageReporting/index.d.ts +3 -0
  390. package/dist/esm/plugin/usageReporting/index.d.ts.map +1 -0
  391. package/dist/esm/plugin/usageReporting/index.js +2 -0
  392. package/dist/esm/plugin/usageReporting/index.js.map +1 -0
  393. package/dist/esm/plugin/usageReporting/iterateOverTrace.d.ts +7 -0
  394. package/dist/esm/plugin/usageReporting/iterateOverTrace.d.ts.map +1 -0
  395. package/dist/esm/plugin/usageReporting/iterateOverTrace.js +78 -0
  396. package/dist/esm/plugin/usageReporting/iterateOverTrace.js.map +1 -0
  397. package/dist/esm/plugin/usageReporting/operationDerivedDataCache.d.ts +12 -0
  398. package/dist/esm/plugin/usageReporting/operationDerivedDataCache.d.ts.map +1 -0
  399. package/dist/esm/plugin/usageReporting/operationDerivedDataCache.js +29 -0
  400. package/dist/esm/plugin/usageReporting/operationDerivedDataCache.js.map +1 -0
  401. package/dist/esm/plugin/usageReporting/options.d.ts +60 -0
  402. package/dist/esm/plugin/usageReporting/options.d.ts.map +1 -0
  403. package/dist/esm/plugin/usageReporting/options.js +2 -0
  404. package/dist/esm/plugin/usageReporting/options.js.map +1 -0
  405. package/dist/esm/plugin/usageReporting/plugin.d.ts +7 -0
  406. package/dist/esm/plugin/usageReporting/plugin.d.ts.map +1 -0
  407. package/dist/esm/plugin/usageReporting/plugin.js +487 -0
  408. package/dist/esm/plugin/usageReporting/plugin.js.map +1 -0
  409. package/dist/esm/plugin/usageReporting/stats.d.ts +96 -0
  410. package/dist/esm/plugin/usageReporting/stats.d.ts.map +1 -0
  411. package/dist/esm/plugin/usageReporting/stats.js +283 -0
  412. package/dist/esm/plugin/usageReporting/stats.js.map +1 -0
  413. package/dist/esm/plugin/usageReporting/traceDetails.d.ts +4 -0
  414. package/dist/esm/plugin/usageReporting/traceDetails.d.ts.map +1 -0
  415. package/dist/esm/plugin/usageReporting/traceDetails.js +60 -0
  416. package/dist/esm/plugin/usageReporting/traceDetails.js.map +1 -0
  417. package/dist/esm/preventCsrf.d.ts +4 -0
  418. package/dist/esm/preventCsrf.d.ts.map +1 -0
  419. package/dist/esm/preventCsrf.js +34 -0
  420. package/dist/esm/preventCsrf.js.map +1 -0
  421. package/dist/esm/requestPipeline.d.ts +9 -0
  422. package/dist/esm/requestPipeline.d.ts.map +1 -0
  423. package/dist/esm/requestPipeline.js +364 -0
  424. package/dist/esm/requestPipeline.js.map +1 -0
  425. package/dist/esm/runHttpQuery.d.ts +15 -0
  426. package/dist/esm/runHttpQuery.d.ts.map +1 -0
  427. package/dist/esm/runHttpQuery.js +221 -0
  428. package/dist/esm/runHttpQuery.js.map +1 -0
  429. package/dist/esm/standalone/index.d.ts +25 -0
  430. package/dist/esm/standalone/index.d.ts.map +1 -0
  431. package/dist/esm/standalone/index.js +91 -0
  432. package/dist/esm/standalone/index.js.map +1 -0
  433. package/dist/esm/utils/HeaderMap.d.ts +8 -0
  434. package/dist/esm/utils/HeaderMap.d.ts.map +1 -0
  435. package/dist/esm/utils/HeaderMap.js +16 -0
  436. package/dist/esm/utils/HeaderMap.js.map +1 -0
  437. package/dist/esm/utils/UnreachableCaseError.d.ts +4 -0
  438. package/dist/esm/utils/UnreachableCaseError.d.ts.map +1 -0
  439. package/dist/esm/utils/UnreachableCaseError.js +6 -0
  440. package/dist/esm/utils/UnreachableCaseError.js.map +1 -0
  441. package/dist/esm/utils/computeCoreSchemaHash.d.ts +2 -0
  442. package/dist/esm/utils/computeCoreSchemaHash.d.ts.map +1 -0
  443. package/dist/esm/utils/computeCoreSchemaHash.js +5 -0
  444. package/dist/esm/utils/computeCoreSchemaHash.js.map +1 -0
  445. package/dist/esm/utils/invokeHooks.d.ts +7 -0
  446. package/dist/esm/utils/invokeHooks.d.ts.map +1 -0
  447. package/dist/esm/utils/invokeHooks.js +31 -0
  448. package/dist/esm/utils/invokeHooks.js.map +1 -0
  449. package/dist/esm/utils/isDefined.d.ts +2 -0
  450. package/dist/esm/utils/isDefined.d.ts.map +1 -0
  451. package/dist/esm/utils/isDefined.js +4 -0
  452. package/dist/esm/utils/isDefined.js.map +1 -0
  453. package/dist/esm/utils/makeGatewayGraphQLRequestContext.d.ts +5 -0
  454. package/dist/esm/utils/makeGatewayGraphQLRequestContext.d.ts.map +1 -0
  455. package/dist/esm/utils/makeGatewayGraphQLRequestContext.js +93 -0
  456. package/dist/esm/utils/makeGatewayGraphQLRequestContext.js.map +1 -0
  457. package/dist/esm/utils/resolvable.d.ts +7 -0
  458. package/dist/esm/utils/resolvable.d.ts.map +1 -0
  459. package/dist/esm/utils/resolvable.js +12 -0
  460. package/dist/esm/utils/resolvable.js.map +1 -0
  461. package/dist/esm/utils/schemaInstrumentation.d.ts +16 -0
  462. package/dist/esm/utils/schemaInstrumentation.d.ts.map +1 -0
  463. package/dist/esm/utils/schemaInstrumentation.js +69 -0
  464. package/dist/esm/utils/schemaInstrumentation.js.map +1 -0
  465. package/dist/esm/utils/schemaManager.d.ts +31 -0
  466. package/dist/esm/utils/schemaManager.d.ts.map +1 -0
  467. package/dist/esm/utils/schemaManager.js +99 -0
  468. package/dist/esm/utils/schemaManager.js.map +1 -0
  469. package/dist/esm/utils/urlForHttpServer.d.ts +3 -0
  470. package/dist/esm/utils/urlForHttpServer.d.ts.map +1 -0
  471. package/dist/esm/utils/urlForHttpServer.js +12 -0
  472. package/dist/esm/utils/urlForHttpServer.js.map +1 -0
  473. package/dist/esm/validationRules/NoIntrospection.d.ts +3 -0
  474. package/dist/esm/validationRules/NoIntrospection.d.ts.map +1 -0
  475. package/dist/esm/validationRules/NoIntrospection.js +15 -0
  476. package/dist/esm/validationRules/NoIntrospection.js.map +1 -0
  477. package/dist/esm/validationRules/RecursiveSelectionsLimit.d.ts +4 -0
  478. package/dist/esm/validationRules/RecursiveSelectionsLimit.d.ts.map +1 -0
  479. package/dist/esm/validationRules/RecursiveSelectionsLimit.js +146 -0
  480. package/dist/esm/validationRules/RecursiveSelectionsLimit.js.map +1 -0
  481. package/dist/esm/validationRules/index.d.ts +3 -0
  482. package/dist/esm/validationRules/index.d.ts.map +1 -0
  483. package/dist/esm/validationRules/index.js +3 -0
  484. package/dist/esm/validationRules/index.js.map +1 -0
  485. package/errors/package.json +8 -0
  486. package/package.json +208 -0
  487. package/plugin/cacheControl/package.json +8 -0
  488. package/plugin/disableSuggestions/package.json +8 -0
  489. package/plugin/disabled/package.json +8 -0
  490. package/plugin/drainHttpServer/package.json +8 -0
  491. package/plugin/inlineTrace/package.json +8 -0
  492. package/plugin/landingPage/default/package.json +8 -0
  493. package/plugin/schemaReporting/package.json +8 -0
  494. package/plugin/subscriptionCallback/package.json +8 -0
  495. package/plugin/usageReporting/package.json +8 -0
  496. package/src/ApolloServer.ts +1456 -0
  497. package/src/cachePolicy.ts +33 -0
  498. package/src/determineApolloConfig.ts +95 -0
  499. package/src/errorNormalize.ts +114 -0
  500. package/src/errors/index.ts +33 -0
  501. package/src/externalTypes/constructor.ts +174 -0
  502. package/src/externalTypes/context.ts +18 -0
  503. package/src/externalTypes/graphql.ts +81 -0
  504. package/src/externalTypes/http.ts +44 -0
  505. package/src/externalTypes/incrementalDeliveryPolyfillAlpha2.ts +63 -0
  506. package/src/externalTypes/incrementalDeliveryPolyfillAlpha9.ts +82 -0
  507. package/src/externalTypes/index.ts +73 -0
  508. package/src/externalTypes/plugins.ts +222 -0
  509. package/src/externalTypes/requestPipeline.ts +123 -0
  510. package/src/generated/packageVersion.ts +1 -0
  511. package/src/httpBatching.ts +105 -0
  512. package/src/incrementalDeliveryPolyfill.ts +253 -0
  513. package/src/index.ts +4 -0
  514. package/src/internalErrorClasses.ts +123 -0
  515. package/src/internalPlugin.ts +42 -0
  516. package/src/plugin/cacheControl/index.ts +453 -0
  517. package/src/plugin/disableSuggestions/index.ts +23 -0
  518. package/src/plugin/disabled/index.ts +41 -0
  519. package/src/plugin/drainHttpServer/index.ts +42 -0
  520. package/src/plugin/drainHttpServer/stoppable.ts +109 -0
  521. package/src/plugin/inlineTrace/index.ts +156 -0
  522. package/src/plugin/landingPage/default/getEmbeddedHTML.ts +204 -0
  523. package/src/plugin/landingPage/default/index.ts +219 -0
  524. package/src/plugin/landingPage/default/types.ts +198 -0
  525. package/src/plugin/schemaIsSubgraph.ts +41 -0
  526. package/src/plugin/schemaReporting/generated/operations.d.ts +18359 -0
  527. package/src/plugin/schemaReporting/index.ts +198 -0
  528. package/src/plugin/schemaReporting/schemaReporter.ts +207 -0
  529. package/src/plugin/subscriptionCallback/index.ts +724 -0
  530. package/src/plugin/traceTreeBuilder.ts +356 -0
  531. package/src/plugin/usageReporting/defaultSendOperationsAsTrace.ts +74 -0
  532. package/src/plugin/usageReporting/durationHistogram.ts +87 -0
  533. package/src/plugin/usageReporting/index.ts +9 -0
  534. package/src/plugin/usageReporting/iterateOverTrace.ts +140 -0
  535. package/src/plugin/usageReporting/operationDerivedDataCache.ts +61 -0
  536. package/src/plugin/usageReporting/options.ts +414 -0
  537. package/src/plugin/usageReporting/plugin.ts +871 -0
  538. package/src/plugin/usageReporting/stats.ts +492 -0
  539. package/src/plugin/usageReporting/traceDetails.ts +96 -0
  540. package/src/preventCsrf.ts +99 -0
  541. package/src/requestPipeline.ts +821 -0
  542. package/src/runHttpQuery.ts +408 -0
  543. package/src/standalone/index.ts +155 -0
  544. package/src/utils/HeaderMap.ts +22 -0
  545. package/src/utils/UnreachableCaseError.ts +10 -0
  546. package/src/utils/computeCoreSchemaHash.ts +9 -0
  547. package/src/utils/invokeHooks.ts +53 -0
  548. package/src/utils/isDefined.ts +3 -0
  549. package/src/utils/makeGatewayGraphQLRequestContext.ts +197 -0
  550. package/src/utils/resolvable.ts +30 -0
  551. package/src/utils/schemaInstrumentation.ts +132 -0
  552. package/src/utils/schemaManager.ts +212 -0
  553. package/src/utils/urlForHttpServer.ts +21 -0
  554. package/src/validationRules/NoIntrospection.ts +27 -0
  555. package/src/validationRules/RecursiveSelectionsLimit.ts +198 -0
  556. package/src/validationRules/index.ts +5 -0
  557. package/standalone/package.json +8 -0
@@ -0,0 +1,724 @@
1
+ import { type FetcherResponse, type Fetcher } from '@apollo/utils.fetcher';
2
+ import type { Logger } from '@apollo/utils.logger';
3
+ import retry from 'async-retry';
4
+ import { subscribe, type ExecutionResult, type GraphQLError } from 'graphql';
5
+ import { setImmediate } from 'node:timers/promises';
6
+ import { ensureError, ensureGraphQLError } from '../../errorNormalize.js';
7
+ import type { ApolloServerPlugin } from '../../externalTypes/index.js';
8
+ import { HeaderMap } from '../../utils/HeaderMap.js';
9
+
10
+ export interface ApolloServerPluginSubscriptionCallbackOptions {
11
+ maxConsecutiveHeartbeatFailures?: number;
12
+ logger?: Logger;
13
+ retry?: retry.Options;
14
+ /**
15
+ * Specifies which Fetch API implementation to use for the callback URL.
16
+ */
17
+ fetcher?: Fetcher;
18
+ }
19
+
20
+ export function ApolloServerPluginSubscriptionCallback(
21
+ options: ApolloServerPluginSubscriptionCallbackOptions = Object.create(null),
22
+ ): ApolloServerPlugin {
23
+ const subscriptionManager = new SubscriptionManager(options);
24
+ const logger = options.logger
25
+ ? prefixedLogger(options.logger, 'SubscriptionCallback')
26
+ : undefined;
27
+
28
+ return {
29
+ async requestDidStart({ request }) {
30
+ const subscriptionExtension = request?.extensions?.subscription;
31
+ // If it's not a callback subscription, ignore the request.
32
+ if (!subscriptionExtension) return;
33
+ let {
34
+ callbackUrl,
35
+ subscriptionId: id,
36
+ verifier,
37
+ heartbeatIntervalMs,
38
+ } = subscriptionExtension;
39
+ // The GA version of callback protocol use camelCase, this is to keep backward compatibility
40
+ callbackUrl = callbackUrl || subscriptionExtension.callback_url;
41
+ id = id || subscriptionExtension.subscription_id;
42
+ heartbeatIntervalMs =
43
+ heartbeatIntervalMs ??
44
+ subscriptionExtension.heartbeat_interval_ms ??
45
+ 5000;
46
+
47
+ return {
48
+ // Implementing `responseForOperation` is the only hook that allows us
49
+ // to bypass normal execution by returning our own response. We don't
50
+ // want Apollo Server to actually handle this subscription request, we
51
+ // want to handle everything ourselves. The actual subscription handling
52
+ // will be done in `willSendResponse`.
53
+ async responseForOperation() {
54
+ logger?.debug('Received new subscription request', id);
55
+
56
+ return {
57
+ http: {
58
+ status: 200,
59
+ headers: new HeaderMap([['content-type', 'application/json']]),
60
+ },
61
+ body: {
62
+ kind: 'single',
63
+ singleResult: {
64
+ data: null,
65
+ },
66
+ },
67
+ };
68
+ },
69
+ // The majority of the subscription work is implemented in this hook.
70
+ // This can _almost_ all be implemented in `responseForOperation`,
71
+ // however in the case of GraphQL validation errors,
72
+ // `responseForOperation` won't actually be called, but
73
+ // `willSendResponse` will.
74
+ async willSendResponse({
75
+ request,
76
+ schema,
77
+ document,
78
+ contextValue,
79
+ operationName,
80
+ response,
81
+ }) {
82
+ try {
83
+ // Before responding to the original request, we need to complete a
84
+ // roundtrip `check` request to the router, so we `await` this
85
+ // request.
86
+ await subscriptionManager.checkRequest({
87
+ callbackUrl,
88
+ id,
89
+ verifier,
90
+ });
91
+ } catch (e) {
92
+ const graphqlError = ensureGraphQLError(e);
93
+ logger?.error(
94
+ `\`check\` request failed: ${graphqlError.message}`,
95
+ id,
96
+ );
97
+ // In the event of a check failure, we respond to the original
98
+ // request with a >=400 status code.
99
+ if (response.body.kind === 'single') {
100
+ response.body.singleResult.errors = [graphqlError];
101
+ response.http.status = 500;
102
+ }
103
+ return;
104
+ }
105
+
106
+ // We're about to `await` the subscription, which could have some
107
+ // nontrivial asynchronous work to do before returning the generator.
108
+ // We set up the heartbeat first so the router knows we're alive
109
+ // during that wait period.
110
+ subscriptionManager.initHeartbeat({
111
+ callbackUrl,
112
+ id,
113
+ verifier,
114
+ heartbeatIntervalMs,
115
+ });
116
+
117
+ // The `check` request was successful, so we can initialize the actual
118
+ // `graphql-js` subscription. We don't expect `subscribe` to throw,
119
+ // but rather return an object with `errors` on it (if there are any).
120
+ logger?.debug(`Starting graphql-js subscription`, id);
121
+ let subscription: Awaited<ReturnType<typeof subscribe>>;
122
+ try {
123
+ subscription = await subscribe({
124
+ schema,
125
+ document: document!,
126
+ variableValues: request.variables,
127
+ contextValue: contextValue,
128
+ operationName: operationName,
129
+ });
130
+ } catch (e) {
131
+ // While we don't expect this scenario, we should still handle it
132
+ // gracefully (in the same way that we do below, when the
133
+ // subscription object has `errors` on it).
134
+ const graphqlError = ensureGraphQLError(e);
135
+ logger?.error(
136
+ `Programming error: graphql-js subscribe() threw unexpectedly! Please report this bug to Apollo. The error was: ${e}`,
137
+ id,
138
+ );
139
+ subscriptionManager.completeRequest({
140
+ errors: [graphqlError],
141
+ callbackUrl,
142
+ id,
143
+ verifier,
144
+ });
145
+ return;
146
+ }
147
+
148
+ // In the case of errors, send a `complete` request to the router with
149
+ // the errors.
150
+ if ('errors' in subscription) {
151
+ logger?.error(
152
+ `graphql-js subscription unsuccessful: [\n\t${subscription.errors
153
+ ?.map((e) => e.message)
154
+ .join(',\n\t')}\n]`,
155
+ id,
156
+ );
157
+
158
+ try {
159
+ subscriptionManager.completeRequest({
160
+ errors: subscription.errors,
161
+ callbackUrl,
162
+ id,
163
+ verifier,
164
+ });
165
+ } catch (e) {
166
+ // TODO: not sure how to best handle a failed "completion with
167
+ // errors" request outside of retrying.
168
+ logger?.error(`\`complete\` request failed: ${e}`, id);
169
+ }
170
+ } else if (isAsyncIterable(subscription)) {
171
+ // We have a real subscription - now we can consume the
172
+ // AsyncIterable on the `subscription` object.
173
+ logger?.debug('graphql-js subscription successful', id);
174
+
175
+ subscriptionManager.startConsumingSubscription({
176
+ subscription,
177
+ callbackUrl,
178
+ id,
179
+ verifier,
180
+ });
181
+ }
182
+
183
+ logger?.debug(`Responding to original subscription request`, id);
184
+ },
185
+ };
186
+ },
187
+ async serverWillStart() {
188
+ return {
189
+ async drainServer() {
190
+ logger?.debug(
191
+ 'Server is shutting down. Cleaning up outstanding subscriptions and heartbeat intervals',
192
+ );
193
+ await subscriptionManager.cleanup();
194
+ // This setImmediate makes the precise timing of the log line below
195
+ // consistent between when we run our test suite with GraphQL.js v16
196
+ // and v17.0.0-alpha.9.
197
+ await setImmediate();
198
+ logger?.debug(
199
+ 'Successfully cleaned up outstanding subscriptions and heartbeat intervals.',
200
+ );
201
+ },
202
+ };
203
+ },
204
+ };
205
+ }
206
+
207
+ function isAsyncIterable<T>(value: any): value is AsyncIterable<T> {
208
+ return value && typeof value[Symbol.asyncIterator] === 'function';
209
+ }
210
+
211
+ interface SubscriptionObject {
212
+ cancelled: boolean;
213
+ asyncIter: AsyncGenerator<ExecutionResult, void, void>;
214
+ startConsumingSubscription: () => Promise<void>;
215
+ completeSubscription: () => Promise<void>;
216
+ }
217
+ // This class manages the state of subscriptions, heartbeat intervals, and
218
+ // router requests. It keeps track of in flight requests so we can await them
219
+ // during server cleanup.
220
+ class SubscriptionManager {
221
+ private maxConsecutiveHeartbeatFailures: number;
222
+ private logger?: ReturnType<typeof prefixedLogger>;
223
+ private retryConfig?: retry.Options;
224
+ private requestsInFlight: Set<Promise<any>> = new Set();
225
+ // A map of information about subscription for a given callback url including the subscription id.
226
+ private subscriptionInfoByCallbackUrl: Map<
227
+ string,
228
+ {
229
+ heartbeat?: {
230
+ id: string;
231
+ verifier: string;
232
+ interval: NodeJS.Timeout;
233
+ queue: Promise<void>[];
234
+ };
235
+ subscription?: SubscriptionObject;
236
+ }
237
+ > = new Map();
238
+ private fetcher: Fetcher;
239
+
240
+ constructor(options: ApolloServerPluginSubscriptionCallbackOptions) {
241
+ this.maxConsecutiveHeartbeatFailures =
242
+ options.maxConsecutiveHeartbeatFailures ?? 5;
243
+ this.retryConfig = {
244
+ retries: 5,
245
+ minTimeout: 100,
246
+ maxTimeout: 1000,
247
+ ...options.retry,
248
+ };
249
+ this.logger = options.logger
250
+ ? prefixedLogger(options.logger, 'SubscriptionManager')
251
+ : undefined;
252
+ this.fetcher = options.fetcher ?? fetch;
253
+ }
254
+
255
+ async retryFetch({
256
+ url,
257
+ action,
258
+ id,
259
+ verifier,
260
+ payload,
261
+ errors,
262
+ headers,
263
+ }: {
264
+ url: string;
265
+ action: 'check' | 'next' | 'complete';
266
+ id: string;
267
+ verifier: string;
268
+ payload?: ExecutionResult;
269
+ errors?: readonly GraphQLError[];
270
+ headers?: Record<string, string>;
271
+ }) {
272
+ let response: Promise<FetcherResponse> | undefined;
273
+ try {
274
+ const maybeWithErrors = errors?.length ? ` with errors` : '';
275
+ this.logger?.debug(
276
+ `Sending \`${action}\` request to router` + maybeWithErrors,
277
+ id,
278
+ );
279
+ return retry<FetcherResponse, Error>(
280
+ async (bail) => {
281
+ response = this.fetcher(url, {
282
+ method: 'POST',
283
+ headers: {
284
+ 'content-type': 'application/json',
285
+ ...headers,
286
+ },
287
+ body: JSON.stringify({
288
+ kind: 'subscription',
289
+ action,
290
+ id,
291
+ verifier,
292
+ ...(payload && { payload }),
293
+ ...(errors?.length && { errors }),
294
+ }),
295
+ });
296
+ this.requestsInFlight.add(response);
297
+ const result = await response;
298
+
299
+ if (!result.ok) {
300
+ if (result.status >= 500) {
301
+ // Throwing here triggers a retry, which seems reasonable for 5xx
302
+ // (i.e. an internal server error).
303
+ throw new Error(
304
+ `\`${action}\` request failed with unexpected status code: ${result.status}`,
305
+ );
306
+ } else {
307
+ // For 4xx, we don't want to retry. These errors carry a semantic
308
+ // meaning (terminate), so we bail. This will reject the promise and
309
+ // should be handled by the caller. Specifically, 404 from the
310
+ // router means terminate, but the protocol says that in other error
311
+ // cases the subscription should be terminated due to an unexpected
312
+ // error.
313
+ if (result.status === 404) {
314
+ this.logger?.debug(
315
+ `\`${action}\` request received 404, terminating subscription`,
316
+ id,
317
+ );
318
+ } else {
319
+ const errMsg = `\`${action}\` request failed with unexpected status code: ${result.status}, terminating subscription`;
320
+ this.logger?.debug(errMsg, id);
321
+ bail(new Error(errMsg));
322
+ }
323
+ this.terminateSubscription(id, url);
324
+ return result;
325
+ }
326
+ }
327
+ this.logger?.debug(`\`${action}\` request successful`, id);
328
+ return result;
329
+ },
330
+ {
331
+ ...this.retryConfig,
332
+ onRetry: (e, attempt) => {
333
+ this.requestsInFlight.delete(response!);
334
+ this.logger?.warn(
335
+ `Retrying \`${action}\` request (attempt ${attempt}) due to error: ${e.message}`,
336
+ id,
337
+ );
338
+ this.retryConfig?.onRetry?.(e, attempt);
339
+ },
340
+ },
341
+ );
342
+ } finally {
343
+ this.requestsInFlight.delete(response!);
344
+ }
345
+ }
346
+
347
+ // Implements sending the `check` request to the router. Fetch errors are
348
+ // thrown and expected to be handled by the caller.
349
+ async checkRequest({
350
+ callbackUrl,
351
+ id,
352
+ verifier,
353
+ }: {
354
+ callbackUrl: string;
355
+ id: string;
356
+ verifier: string;
357
+ }) {
358
+ return this.retryFetch({
359
+ url: callbackUrl,
360
+ action: 'check',
361
+ id,
362
+ verifier,
363
+ headers: { 'subscription-protocol': 'callback/1.0' },
364
+ });
365
+ }
366
+
367
+ // Kicks off an interval that sends `heartbeat` requests to the router. If an
368
+ // interval already exists for the callback url, we just add the new ID to its
369
+ // list of IDs that it's sending a heartbeat for. This allows us to send one
370
+ // batched heartbeat per interval per callback url.
371
+ initHeartbeat({
372
+ callbackUrl,
373
+ id,
374
+ verifier,
375
+ heartbeatIntervalMs,
376
+ }: {
377
+ callbackUrl: string;
378
+ id: string;
379
+ verifier: string;
380
+ heartbeatIntervalMs: number;
381
+ }) {
382
+ if (!this.subscriptionInfoByCallbackUrl.has(callbackUrl)) {
383
+ this.subscriptionInfoByCallbackUrl.set(callbackUrl, {});
384
+ }
385
+
386
+ if (heartbeatIntervalMs === 0) {
387
+ // Heartbeat has been disabled on the router
388
+ this.logger?.debug(`Heartbeat disabled for ${callbackUrl}`, id);
389
+ return;
390
+ }
391
+
392
+ // Kickoff heartbeat interval since there isn't one already
393
+ this.logger?.debug(
394
+ `Starting new heartbeat interval for ${callbackUrl}`,
395
+ id,
396
+ );
397
+
398
+ let consecutiveHeartbeatFailureCount = 0;
399
+ const heartbeatInterval = setInterval(async () => {
400
+ let heartbeatRequest: Promise<FetcherResponse> | undefined;
401
+
402
+ // XXX since we're on an interval, it's possible a heartbeat goes out
403
+ // before the previous heartbeat has finished. It seems reasonable to
404
+ // queue them and await the previous heartbeat if there is one. It might
405
+ // also be reasonable to just bail / skip this heartbeat if there's
406
+ // already one in flight. I'm not sure which is better. This Promise and
407
+ // all of the queue stuff try to address this. Maybe this would be better
408
+ // off chaining timeouts instead of using an interval?
409
+ let resolveHeartbeatPromise: () => void;
410
+ const heartbeatPromise = new Promise<void>((r) => {
411
+ resolveHeartbeatPromise = r;
412
+ });
413
+ const existingSubscriptionInfo =
414
+ this.subscriptionInfoByCallbackUrl.get(callbackUrl);
415
+
416
+ if (!existingSubscriptionInfo?.heartbeat) {
417
+ // This is unexpected - if the interval is still running we should have
418
+ // an entry in the map for it. But if we do end up here, there's no
419
+ // reason to let the interval continue to run.
420
+ clearInterval(heartbeatInterval);
421
+ this.logger?.error(
422
+ `Programming error: Heartbeat interval unexpectedly missing for ${callbackUrl}. This is probably a bug in Apollo Server.`,
423
+ );
424
+ return;
425
+ }
426
+ const existingHeartbeat = existingSubscriptionInfo.heartbeat;
427
+ const { queue } = existingHeartbeat;
428
+ queue.push(heartbeatPromise);
429
+ if (queue.length > 1) {
430
+ const requestBeforeMe = queue[existingHeartbeat?.queue.length - 2];
431
+ await requestBeforeMe;
432
+ }
433
+
434
+ // Send the heartbeat request
435
+ try {
436
+ this.logger?.debug(
437
+ `Sending \`check\` request to ${callbackUrl} for ID: ${id}`,
438
+ );
439
+
440
+ heartbeatRequest = this.fetcher(callbackUrl, {
441
+ method: 'POST',
442
+ body: JSON.stringify({
443
+ kind: 'subscription',
444
+ action: 'check',
445
+ id,
446
+ verifier,
447
+ }),
448
+ headers: {
449
+ 'content-type': 'application/json',
450
+ 'subscription-protocol': 'callback/1.0',
451
+ },
452
+ });
453
+ this.requestsInFlight.add(heartbeatRequest);
454
+
455
+ // heartbeat response might be a 4xx, in which case we'd need to
456
+ // terminate the subscription, so we need to await it
457
+ const result = await heartbeatRequest;
458
+
459
+ this.logger?.debug(`Heartbeat received response for ID: ${id}`);
460
+ if (result.ok) {
461
+ this.logger?.debug(`Heartbeat request successful, ID: ${id}`);
462
+ } else if (result.status === 400) {
463
+ this.logger?.debug(`Heartbeat request received invalid ID: ${id}`);
464
+
465
+ this.terminateSubscription(id, callbackUrl);
466
+ } else if (result.status === 404) {
467
+ // the id we sent is invalid
468
+ this.logger?.debug(`Heartbeat request received invalid ID: ${id}`);
469
+ // This will also handle cleaning up the heartbeat interval
470
+ this.terminateSubscription(id, callbackUrl);
471
+ } else {
472
+ // We'll catch this below and log it with the expectation that we'll
473
+ // retry this request some number of times before giving up
474
+ throw new Error(`Unexpected status code: ${result.status}`);
475
+ }
476
+
477
+ // If we make it here, there wasn't some transient error with the
478
+ // request and it had an expected status code (2xx, 400, 404).
479
+ consecutiveHeartbeatFailureCount = 0;
480
+ } catch (e) {
481
+ const err = ensureError(e);
482
+ // The heartbeat request failed.
483
+ this.logger?.error(
484
+ `Heartbeat request failed (${++consecutiveHeartbeatFailureCount} consecutive): ${
485
+ err.message
486
+ }`,
487
+ existingHeartbeat.id,
488
+ );
489
+
490
+ if (
491
+ consecutiveHeartbeatFailureCount >=
492
+ this.maxConsecutiveHeartbeatFailures
493
+ ) {
494
+ this.logger?.error(
495
+ `Heartbeat request failed ${consecutiveHeartbeatFailureCount} times, terminating subscriptions and heartbeat interval: ${err.message}`,
496
+ existingHeartbeat.id,
497
+ );
498
+ // If we've failed 5 times in a row, we should terminate all
499
+ // subscriptions for this callback url. This will also handle
500
+ // cleaning up the heartbeat interval.
501
+ this.terminateSubscription(id, callbackUrl);
502
+ }
503
+ return;
504
+ } finally {
505
+ if (heartbeatRequest) {
506
+ this.requestsInFlight.delete(heartbeatRequest);
507
+ }
508
+ // remove itself from the queue and resolve the promise
509
+ existingHeartbeat?.queue.shift();
510
+ resolveHeartbeatPromise!();
511
+ }
512
+ }, heartbeatIntervalMs);
513
+
514
+ // Add the heartbeat interval to the map of intervals
515
+ const subscriptionInfo =
516
+ this.subscriptionInfoByCallbackUrl.get(callbackUrl)!;
517
+ subscriptionInfo.heartbeat = {
518
+ interval: heartbeatInterval,
519
+ id,
520
+ verifier,
521
+ queue: [],
522
+ };
523
+ }
524
+
525
+ // Cancels and cleans up the subscriptions for given IDs and callback url. If
526
+ // there are no active subscriptions after this, we also clean up the
527
+ // heartbeat interval. This does not handle sending the `complete` request to
528
+ // the router.
529
+ private terminateSubscription(id: string, callbackUrl: string) {
530
+ this.logger?.debug(`Terminating subscriptions for ID: ${id}`);
531
+ const subscriptionInfo =
532
+ this.subscriptionInfoByCallbackUrl.get(callbackUrl);
533
+ if (!subscriptionInfo) {
534
+ this.logger?.error(
535
+ `No subscriptions found for ${callbackUrl}, skipping termination`,
536
+ );
537
+ return;
538
+ }
539
+ const { subscription, heartbeat } = subscriptionInfo;
540
+ if (subscription) {
541
+ subscription.cancelled = true;
542
+ subscription.asyncIter?.return();
543
+ }
544
+ // cleanup heartbeat for subscription
545
+ if (heartbeat) {
546
+ this.logger?.debug(`Terminating heartbeat interval for ${callbackUrl}`);
547
+ clearInterval(heartbeat.interval);
548
+ }
549
+ this.subscriptionInfoByCallbackUrl.delete(callbackUrl);
550
+ }
551
+
552
+ // Consumes the AsyncIterable returned by `graphql-js`'s `subscribe` function.
553
+ // This handles sending the `next` requests to the router as well as the
554
+ // `complete` request when the subscription is finished.
555
+ startConsumingSubscription({
556
+ subscription,
557
+ callbackUrl,
558
+ id,
559
+ verifier,
560
+ }: {
561
+ subscription: AsyncGenerator<ExecutionResult, void, void>;
562
+ callbackUrl: string;
563
+ id: string;
564
+ verifier: string;
565
+ }) {
566
+ // For each subscription we need to manage a bit of state. We need to be
567
+ // able to cancel the subscription externally. Setting `cancelled` to true
568
+ // allows us to break out of the `for await` and ignore future payloads.
569
+ const self = this;
570
+ const subscriptionObject = {
571
+ asyncIter: subscription,
572
+ cancelled: false,
573
+ async startConsumingSubscription() {
574
+ self.logger?.debug(`Listening to graphql-js subscription`, id);
575
+ try {
576
+ for await (const payload of subscription) {
577
+ if (this.cancelled) {
578
+ self.logger?.debug(
579
+ `Subscription already cancelled, ignoring current and future payloads`,
580
+ id,
581
+ );
582
+ // It's already been cancelled - something else has already handled
583
+ // sending the `complete` request so we don't want to `break` here
584
+ // and send it again after the loop.
585
+ return;
586
+ }
587
+
588
+ try {
589
+ await self.retryFetch({
590
+ url: callbackUrl,
591
+ action: 'next',
592
+ id,
593
+ verifier,
594
+ payload,
595
+ });
596
+ } catch (e) {
597
+ const originalError = ensureError(e);
598
+ self.logger?.error(
599
+ `\`next\` request failed, terminating subscription: ${originalError.message}`,
600
+ id,
601
+ );
602
+ self.terminateSubscription(id, callbackUrl);
603
+ }
604
+ }
605
+ // The subscription ended without errors, send the `complete` request to
606
+ // the router
607
+ self.logger?.debug(`Subscription completed without errors`, id);
608
+ await this.completeSubscription();
609
+ } catch (e) {
610
+ const error = ensureGraphQLError(e);
611
+ self.logger?.error(
612
+ `Generator threw an error, terminating subscription: ${error.message}`,
613
+ id,
614
+ );
615
+ this.completeSubscription([error]);
616
+ }
617
+ },
618
+ async completeSubscription(errors?: readonly GraphQLError[]) {
619
+ if (this.cancelled) return;
620
+ this.cancelled = true;
621
+
622
+ try {
623
+ await self.completeRequest({
624
+ callbackUrl,
625
+ id,
626
+ verifier,
627
+ ...(errors && { errors }),
628
+ });
629
+ } catch (e) {
630
+ const error = ensureError(e);
631
+ // This is just the `complete` request. If we fail to get this message
632
+ // to the router, it should just invalidate the subscription after the
633
+ // next heartbeat fails.
634
+ self.logger?.error(
635
+ `\`complete\` request failed: ${error.message}`,
636
+ id,
637
+ );
638
+ } finally {
639
+ self.terminateSubscription(id, callbackUrl);
640
+ }
641
+ },
642
+ };
643
+
644
+ subscriptionObject.startConsumingSubscription();
645
+ const subscriptionInfo =
646
+ this.subscriptionInfoByCallbackUrl.get(callbackUrl);
647
+ if (!subscriptionInfo) {
648
+ this.logger?.error(
649
+ `No existing heartbeat found for ${callbackUrl}, skipping subscription`,
650
+ );
651
+ } else {
652
+ subscriptionInfo.subscription = subscriptionObject;
653
+ }
654
+ }
655
+
656
+ // Sends the `complete` request to the router.
657
+ async completeRequest({
658
+ errors,
659
+ callbackUrl,
660
+ id,
661
+ verifier,
662
+ }: {
663
+ errors?: readonly GraphQLError[];
664
+ callbackUrl: string;
665
+ id: string;
666
+ verifier: string;
667
+ }) {
668
+ return this.retryFetch({
669
+ url: callbackUrl,
670
+ action: 'complete',
671
+ id,
672
+ verifier,
673
+ errors,
674
+ });
675
+ }
676
+
677
+ collectAllSubscriptions() {
678
+ return Array.from(this.subscriptionInfoByCallbackUrl.values()).reduce(
679
+ (subscriptions, { subscription }) => {
680
+ if (subscription) {
681
+ subscriptions.push(subscription);
682
+ }
683
+ return subscriptions;
684
+ },
685
+ [] as SubscriptionObject[],
686
+ );
687
+ }
688
+
689
+ async cleanup() {
690
+ // Wait for our inflight heartbeats to finish - they might handle cancelling
691
+ // some subscriptions
692
+ await Promise.allSettled(
693
+ Array.from(this.subscriptionInfoByCallbackUrl.values()).map(
694
+ async ({ heartbeat }) => {
695
+ clearInterval(heartbeat?.interval);
696
+ await heartbeat?.queue[heartbeat.queue.length - 1];
697
+ },
698
+ ),
699
+ );
700
+ // Cancel / complete any still-active subscriptions
701
+ await Promise.allSettled(
702
+ this.collectAllSubscriptions()
703
+ .filter((s) => !s.cancelled)
704
+ .map((s) => s.completeSubscription()),
705
+ );
706
+ // Wait for any remaining requests to finish
707
+ await Promise.allSettled(this.requestsInFlight.values());
708
+ }
709
+ }
710
+
711
+ // Simple prefixing logger to curry class name and request IDs into log messages
712
+ function prefixedLogger(logger: Logger, prefix: string) {
713
+ function log(level: keyof Logger) {
714
+ return function (message: string, id?: string) {
715
+ logger[level](`${prefix}${id ? `[${id}]` : ''}: ${message}`);
716
+ };
717
+ }
718
+ return {
719
+ debug: log('debug'),
720
+ error: log('error'),
721
+ info: log('info'),
722
+ warn: log('warn'),
723
+ };
724
+ }