@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.
- package/README.md +40 -0
- package/changes.json +46 -0
- package/dist/cjs/ApolloServer.d.ts +126 -0
- package/dist/cjs/ApolloServer.d.ts.map +1 -0
- package/dist/cjs/ApolloServer.js +726 -0
- package/dist/cjs/ApolloServer.js.map +1 -0
- package/dist/cjs/cachePolicy.d.ts +3 -0
- package/dist/cjs/cachePolicy.d.ts.map +1 -0
- package/dist/cjs/cachePolicy.js +33 -0
- package/dist/cjs/cachePolicy.js.map +1 -0
- package/dist/cjs/determineApolloConfig.d.ts +4 -0
- package/dist/cjs/determineApolloConfig.d.ts.map +1 -0
- package/dist/cjs/determineApolloConfig.js +58 -0
- package/dist/cjs/determineApolloConfig.js.map +1 -0
- package/dist/cjs/errorNormalize.d.ts +12 -0
- package/dist/cjs/errorNormalize.d.ts.map +1 -0
- package/dist/cjs/errorNormalize.js +71 -0
- package/dist/cjs/errorNormalize.js.map +1 -0
- package/dist/cjs/errors/index.d.ts +16 -0
- package/dist/cjs/errors/index.d.ts.map +1 -0
- package/dist/cjs/errors/index.js +28 -0
- package/dist/cjs/errors/index.js.map +1 -0
- package/dist/cjs/externalTypes/constructor.d.ts +78 -0
- package/dist/cjs/externalTypes/constructor.d.ts.map +1 -0
- package/dist/cjs/externalTypes/constructor.js +3 -0
- package/dist/cjs/externalTypes/constructor.js.map +1 -0
- package/dist/cjs/externalTypes/context.d.ts +4 -0
- package/dist/cjs/externalTypes/context.d.ts.map +1 -0
- package/dist/cjs/externalTypes/context.js +3 -0
- package/dist/cjs/externalTypes/context.js.map +1 -0
- package/dist/cjs/externalTypes/graphql.d.ts +41 -0
- package/dist/cjs/externalTypes/graphql.d.ts.map +1 -0
- package/dist/cjs/externalTypes/graphql.js +3 -0
- package/dist/cjs/externalTypes/graphql.js.map +1 -0
- package/dist/cjs/externalTypes/http.d.ts +22 -0
- package/dist/cjs/externalTypes/http.d.ts.map +1 -0
- package/dist/cjs/externalTypes/http.js +3 -0
- package/dist/cjs/externalTypes/http.js.map +1 -0
- package/dist/cjs/externalTypes/incrementalDeliveryPolyfillAlpha2.d.ts +28 -0
- package/dist/cjs/externalTypes/incrementalDeliveryPolyfillAlpha2.d.ts.map +1 -0
- package/dist/cjs/externalTypes/incrementalDeliveryPolyfillAlpha2.js +3 -0
- package/dist/cjs/externalTypes/incrementalDeliveryPolyfillAlpha2.js.map +1 -0
- package/dist/cjs/externalTypes/incrementalDeliveryPolyfillAlpha9.d.ts +43 -0
- package/dist/cjs/externalTypes/incrementalDeliveryPolyfillAlpha9.d.ts.map +1 -0
- package/dist/cjs/externalTypes/incrementalDeliveryPolyfillAlpha9.js +3 -0
- package/dist/cjs/externalTypes/incrementalDeliveryPolyfillAlpha9.js.map +1 -0
- package/dist/cjs/externalTypes/index.d.ts +9 -0
- package/dist/cjs/externalTypes/index.d.ts.map +1 -0
- package/dist/cjs/externalTypes/index.js +3 -0
- package/dist/cjs/externalTypes/index.js.map +1 -0
- package/dist/cjs/externalTypes/plugins.d.ts +75 -0
- package/dist/cjs/externalTypes/plugins.d.ts.map +1 -0
- package/dist/cjs/externalTypes/plugins.js +3 -0
- package/dist/cjs/externalTypes/plugins.js.map +1 -0
- package/dist/cjs/externalTypes/requestPipeline.d.ts +50 -0
- package/dist/cjs/externalTypes/requestPipeline.d.ts.map +1 -0
- package/dist/cjs/externalTypes/requestPipeline.js +3 -0
- package/dist/cjs/externalTypes/requestPipeline.js.map +1 -0
- package/dist/cjs/generated/packageVersion.d.ts +2 -0
- package/dist/cjs/generated/packageVersion.d.ts.map +1 -0
- package/dist/cjs/generated/packageVersion.js +5 -0
- package/dist/cjs/generated/packageVersion.js.map +1 -0
- package/dist/cjs/httpBatching.d.ts +4 -0
- package/dist/cjs/httpBatching.d.ts.map +1 -0
- package/dist/cjs/httpBatching.js +58 -0
- package/dist/cjs/httpBatching.js.map +1 -0
- package/dist/cjs/incrementalDeliveryPolyfill.d.ts +82 -0
- package/dist/cjs/incrementalDeliveryPolyfill.d.ts.map +1 -0
- package/dist/cjs/incrementalDeliveryPolyfill.js +74 -0
- package/dist/cjs/incrementalDeliveryPolyfill.js.map +1 -0
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +23 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/internalErrorClasses.d.ts +28 -0
- package/dist/cjs/internalErrorClasses.d.ts.map +1 -0
- package/dist/cjs/internalErrorClasses.js +91 -0
- package/dist/cjs/internalErrorClasses.js.map +1 -0
- package/dist/cjs/internalPlugin.d.ts +9 -0
- package/dist/cjs/internalPlugin.d.ts.map +1 -0
- package/dist/cjs/internalPlugin.js +11 -0
- package/dist/cjs/internalPlugin.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/plugin/cacheControl/index.d.ts +9 -0
- package/dist/cjs/plugin/cacheControl/index.d.ts.map +1 -0
- package/dist/cjs/plugin/cacheControl/index.js +223 -0
- package/dist/cjs/plugin/cacheControl/index.js.map +1 -0
- package/dist/cjs/plugin/disableSuggestions/index.d.ts +3 -0
- package/dist/cjs/plugin/disableSuggestions/index.d.ts.map +1 -0
- package/dist/cjs/plugin/disableSuggestions/index.js +22 -0
- package/dist/cjs/plugin/disableSuggestions/index.js.map +1 -0
- package/dist/cjs/plugin/disabled/index.d.ts +7 -0
- package/dist/cjs/plugin/disabled/index.d.ts.map +1 -0
- package/dist/cjs/plugin/disabled/index.js +30 -0
- package/dist/cjs/plugin/disabled/index.js.map +1 -0
- package/dist/cjs/plugin/drainHttpServer/index.d.ts +8 -0
- package/dist/cjs/plugin/drainHttpServer/index.d.ts.map +1 -0
- package/dist/cjs/plugin/drainHttpServer/index.js +19 -0
- package/dist/cjs/plugin/drainHttpServer/index.js.map +1 -0
- package/dist/cjs/plugin/drainHttpServer/stoppable.d.ts +10 -0
- package/dist/cjs/plugin/drainHttpServer/stoppable.d.ts.map +1 -0
- package/dist/cjs/plugin/drainHttpServer/stoppable.js +54 -0
- package/dist/cjs/plugin/drainHttpServer/stoppable.js.map +1 -0
- package/dist/cjs/plugin/inlineTrace/index.d.ts +8 -0
- package/dist/cjs/plugin/inlineTrace/index.d.ts.map +1 -0
- package/dist/cjs/plugin/inlineTrace/index.js +70 -0
- package/dist/cjs/plugin/inlineTrace/index.js.map +1 -0
- package/dist/cjs/plugin/landingPage/default/getEmbeddedHTML.d.ts +4 -0
- package/dist/cjs/plugin/landingPage/default/getEmbeddedHTML.d.ts.map +1 -0
- package/dist/cjs/plugin/landingPage/default/getEmbeddedHTML.js +143 -0
- package/dist/cjs/plugin/landingPage/default/getEmbeddedHTML.js.map +1 -0
- package/dist/cjs/plugin/landingPage/default/index.d.ts +9 -0
- package/dist/cjs/plugin/landingPage/default/index.d.ts.map +1 -0
- package/dist/cjs/plugin/landingPage/default/index.js +146 -0
- package/dist/cjs/plugin/landingPage/default/index.js.map +1 -0
- package/dist/cjs/plugin/landingPage/default/types.d.ts +56 -0
- package/dist/cjs/plugin/landingPage/default/types.d.ts.map +1 -0
- package/dist/cjs/plugin/landingPage/default/types.js +3 -0
- package/dist/cjs/plugin/landingPage/default/types.js.map +1 -0
- package/dist/cjs/plugin/schemaIsSubgraph.d.ts +3 -0
- package/dist/cjs/plugin/schemaIsSubgraph.d.ts.map +1 -0
- package/dist/cjs/plugin/schemaIsSubgraph.js +23 -0
- package/dist/cjs/plugin/schemaIsSubgraph.js.map +1 -0
- package/dist/cjs/plugin/schemaReporting/index.d.ts +10 -0
- package/dist/cjs/plugin/schemaReporting/index.d.ts.map +1 -0
- package/dist/cjs/plugin/schemaReporting/index.js +104 -0
- package/dist/cjs/plugin/schemaReporting/index.js.map +1 -0
- package/dist/cjs/plugin/schemaReporting/schemaReporter.d.ts +33 -0
- package/dist/cjs/plugin/schemaReporting/schemaReporter.d.ts.map +1 -0
- package/dist/cjs/plugin/schemaReporting/schemaReporter.js +147 -0
- package/dist/cjs/plugin/schemaReporting/schemaReporter.js.map +1 -0
- package/dist/cjs/plugin/subscriptionCallback/index.d.ts +12 -0
- package/dist/cjs/plugin/subscriptionCallback/index.d.ts.map +1 -0
- package/dist/cjs/plugin/subscriptionCallback/index.js +434 -0
- package/dist/cjs/plugin/subscriptionCallback/index.js.map +1 -0
- package/dist/cjs/plugin/traceTreeBuilder.d.ts +25 -0
- package/dist/cjs/plugin/traceTreeBuilder.d.ts.map +1 -0
- package/dist/cjs/plugin/traceTreeBuilder.js +201 -0
- package/dist/cjs/plugin/traceTreeBuilder.js.map +1 -0
- package/dist/cjs/plugin/usageReporting/defaultSendOperationsAsTrace.d.ts +3 -0
- package/dist/cjs/plugin/usageReporting/defaultSendOperationsAsTrace.d.ts.map +1 -0
- package/dist/cjs/plugin/usageReporting/defaultSendOperationsAsTrace.js +44 -0
- package/dist/cjs/plugin/usageReporting/defaultSendOperationsAsTrace.js.map +1 -0
- package/dist/cjs/plugin/usageReporting/durationHistogram.d.ts +16 -0
- package/dist/cjs/plugin/usageReporting/durationHistogram.d.ts.map +1 -0
- package/dist/cjs/plugin/usageReporting/durationHistogram.js +68 -0
- package/dist/cjs/plugin/usageReporting/durationHistogram.js.map +1 -0
- package/dist/cjs/plugin/usageReporting/index.d.ts +3 -0
- package/dist/cjs/plugin/usageReporting/index.d.ts.map +1 -0
- package/dist/cjs/plugin/usageReporting/index.js +6 -0
- package/dist/cjs/plugin/usageReporting/index.js.map +1 -0
- package/dist/cjs/plugin/usageReporting/iterateOverTrace.d.ts +7 -0
- package/dist/cjs/plugin/usageReporting/iterateOverTrace.d.ts.map +1 -0
- package/dist/cjs/plugin/usageReporting/iterateOverTrace.js +81 -0
- package/dist/cjs/plugin/usageReporting/iterateOverTrace.js.map +1 -0
- package/dist/cjs/plugin/usageReporting/operationDerivedDataCache.d.ts +12 -0
- package/dist/cjs/plugin/usageReporting/operationDerivedDataCache.d.ts.map +1 -0
- package/dist/cjs/plugin/usageReporting/operationDerivedDataCache.js +33 -0
- package/dist/cjs/plugin/usageReporting/operationDerivedDataCache.js.map +1 -0
- package/dist/cjs/plugin/usageReporting/options.d.ts +60 -0
- package/dist/cjs/plugin/usageReporting/options.d.ts.map +1 -0
- package/dist/cjs/plugin/usageReporting/options.js +3 -0
- package/dist/cjs/plugin/usageReporting/options.js.map +1 -0
- package/dist/cjs/plugin/usageReporting/plugin.d.ts +7 -0
- package/dist/cjs/plugin/usageReporting/plugin.d.ts.map +1 -0
- package/dist/cjs/plugin/usageReporting/plugin.js +494 -0
- package/dist/cjs/plugin/usageReporting/plugin.js.map +1 -0
- package/dist/cjs/plugin/usageReporting/stats.d.ts +96 -0
- package/dist/cjs/plugin/usageReporting/stats.d.ts.map +1 -0
- package/dist/cjs/plugin/usageReporting/stats.js +289 -0
- package/dist/cjs/plugin/usageReporting/stats.js.map +1 -0
- package/dist/cjs/plugin/usageReporting/traceDetails.d.ts +4 -0
- package/dist/cjs/plugin/usageReporting/traceDetails.d.ts.map +1 -0
- package/dist/cjs/plugin/usageReporting/traceDetails.js +63 -0
- package/dist/cjs/plugin/usageReporting/traceDetails.js.map +1 -0
- package/dist/cjs/preventCsrf.d.ts +4 -0
- package/dist/cjs/preventCsrf.d.ts.map +1 -0
- package/dist/cjs/preventCsrf.js +41 -0
- package/dist/cjs/preventCsrf.js.map +1 -0
- package/dist/cjs/requestPipeline.d.ts +9 -0
- package/dist/cjs/requestPipeline.d.ts.map +1 -0
- package/dist/cjs/requestPipeline.js +371 -0
- package/dist/cjs/requestPipeline.js.map +1 -0
- package/dist/cjs/runHttpQuery.d.ts +15 -0
- package/dist/cjs/runHttpQuery.d.ts.map +1 -0
- package/dist/cjs/runHttpQuery.js +230 -0
- package/dist/cjs/runHttpQuery.js.map +1 -0
- package/dist/cjs/standalone/index.d.ts +25 -0
- package/dist/cjs/standalone/index.d.ts.map +1 -0
- package/dist/cjs/standalone/index.js +97 -0
- package/dist/cjs/standalone/index.js.map +1 -0
- package/dist/cjs/utils/HeaderMap.d.ts +8 -0
- package/dist/cjs/utils/HeaderMap.d.ts.map +1 -0
- package/dist/cjs/utils/HeaderMap.js +20 -0
- package/dist/cjs/utils/HeaderMap.js.map +1 -0
- package/dist/cjs/utils/UnreachableCaseError.d.ts +4 -0
- package/dist/cjs/utils/UnreachableCaseError.d.ts.map +1 -0
- package/dist/cjs/utils/UnreachableCaseError.js +10 -0
- package/dist/cjs/utils/UnreachableCaseError.js.map +1 -0
- package/dist/cjs/utils/computeCoreSchemaHash.d.ts +2 -0
- package/dist/cjs/utils/computeCoreSchemaHash.d.ts.map +1 -0
- package/dist/cjs/utils/computeCoreSchemaHash.js +8 -0
- package/dist/cjs/utils/computeCoreSchemaHash.js.map +1 -0
- package/dist/cjs/utils/invokeHooks.d.ts +7 -0
- package/dist/cjs/utils/invokeHooks.d.ts.map +1 -0
- package/dist/cjs/utils/invokeHooks.js +36 -0
- package/dist/cjs/utils/invokeHooks.js.map +1 -0
- package/dist/cjs/utils/isDefined.d.ts +2 -0
- package/dist/cjs/utils/isDefined.d.ts.map +1 -0
- package/dist/cjs/utils/isDefined.js +7 -0
- package/dist/cjs/utils/isDefined.js.map +1 -0
- package/dist/cjs/utils/makeGatewayGraphQLRequestContext.d.ts +5 -0
- package/dist/cjs/utils/makeGatewayGraphQLRequestContext.d.ts.map +1 -0
- package/dist/cjs/utils/makeGatewayGraphQLRequestContext.js +96 -0
- package/dist/cjs/utils/makeGatewayGraphQLRequestContext.js.map +1 -0
- package/dist/cjs/utils/resolvable.d.ts +7 -0
- package/dist/cjs/utils/resolvable.d.ts.map +1 -0
- package/dist/cjs/utils/resolvable.js +14 -0
- package/dist/cjs/utils/resolvable.js.map +1 -0
- package/dist/cjs/utils/schemaInstrumentation.d.ts +16 -0
- package/dist/cjs/utils/schemaInstrumentation.d.ts.map +1 -0
- package/dist/cjs/utils/schemaInstrumentation.js +75 -0
- package/dist/cjs/utils/schemaInstrumentation.js.map +1 -0
- package/dist/cjs/utils/schemaManager.d.ts +31 -0
- package/dist/cjs/utils/schemaManager.d.ts.map +1 -0
- package/dist/cjs/utils/schemaManager.js +103 -0
- package/dist/cjs/utils/schemaManager.js.map +1 -0
- package/dist/cjs/utils/urlForHttpServer.d.ts +3 -0
- package/dist/cjs/utils/urlForHttpServer.d.ts.map +1 -0
- package/dist/cjs/utils/urlForHttpServer.js +15 -0
- package/dist/cjs/utils/urlForHttpServer.js.map +1 -0
- package/dist/cjs/validationRules/NoIntrospection.d.ts +3 -0
- package/dist/cjs/validationRules/NoIntrospection.d.ts.map +1 -0
- package/dist/cjs/validationRules/NoIntrospection.js +19 -0
- package/dist/cjs/validationRules/NoIntrospection.js.map +1 -0
- package/dist/cjs/validationRules/RecursiveSelectionsLimit.d.ts +4 -0
- package/dist/cjs/validationRules/RecursiveSelectionsLimit.d.ts.map +1 -0
- package/dist/cjs/validationRules/RecursiveSelectionsLimit.js +150 -0
- package/dist/cjs/validationRules/RecursiveSelectionsLimit.js.map +1 -0
- package/dist/cjs/validationRules/index.d.ts +3 -0
- package/dist/cjs/validationRules/index.d.ts.map +1 -0
- package/dist/cjs/validationRules/index.js +9 -0
- package/dist/cjs/validationRules/index.js.map +1 -0
- package/dist/esm/ApolloServer.d.ts +126 -0
- package/dist/esm/ApolloServer.d.ts.map +1 -0
- package/dist/esm/ApolloServer.js +683 -0
- package/dist/esm/ApolloServer.js.map +1 -0
- package/dist/esm/cachePolicy.d.ts +3 -0
- package/dist/esm/cachePolicy.d.ts.map +1 -0
- package/dist/esm/cachePolicy.js +30 -0
- package/dist/esm/cachePolicy.js.map +1 -0
- package/dist/esm/determineApolloConfig.d.ts +4 -0
- package/dist/esm/determineApolloConfig.d.ts.map +1 -0
- package/dist/esm/determineApolloConfig.js +55 -0
- package/dist/esm/determineApolloConfig.js.map +1 -0
- package/dist/esm/errorNormalize.d.ts +12 -0
- package/dist/esm/errorNormalize.d.ts.map +1 -0
- package/dist/esm/errorNormalize.js +66 -0
- package/dist/esm/errorNormalize.js.map +1 -0
- package/dist/esm/errors/index.d.ts +16 -0
- package/dist/esm/errors/index.d.ts.map +1 -0
- package/dist/esm/errors/index.js +24 -0
- package/dist/esm/errors/index.js.map +1 -0
- package/dist/esm/externalTypes/constructor.d.ts +78 -0
- package/dist/esm/externalTypes/constructor.d.ts.map +1 -0
- package/dist/esm/externalTypes/constructor.js +2 -0
- package/dist/esm/externalTypes/constructor.js.map +1 -0
- package/dist/esm/externalTypes/context.d.ts +4 -0
- package/dist/esm/externalTypes/context.d.ts.map +1 -0
- package/dist/esm/externalTypes/context.js +2 -0
- package/dist/esm/externalTypes/context.js.map +1 -0
- package/dist/esm/externalTypes/graphql.d.ts +41 -0
- package/dist/esm/externalTypes/graphql.d.ts.map +1 -0
- package/dist/esm/externalTypes/graphql.js +2 -0
- package/dist/esm/externalTypes/graphql.js.map +1 -0
- package/dist/esm/externalTypes/http.d.ts +22 -0
- package/dist/esm/externalTypes/http.d.ts.map +1 -0
- package/dist/esm/externalTypes/http.js +2 -0
- package/dist/esm/externalTypes/http.js.map +1 -0
- package/dist/esm/externalTypes/incrementalDeliveryPolyfillAlpha2.d.ts +28 -0
- package/dist/esm/externalTypes/incrementalDeliveryPolyfillAlpha2.d.ts.map +1 -0
- package/dist/esm/externalTypes/incrementalDeliveryPolyfillAlpha2.js +2 -0
- package/dist/esm/externalTypes/incrementalDeliveryPolyfillAlpha2.js.map +1 -0
- package/dist/esm/externalTypes/incrementalDeliveryPolyfillAlpha9.d.ts +43 -0
- package/dist/esm/externalTypes/incrementalDeliveryPolyfillAlpha9.d.ts.map +1 -0
- package/dist/esm/externalTypes/incrementalDeliveryPolyfillAlpha9.js +2 -0
- package/dist/esm/externalTypes/incrementalDeliveryPolyfillAlpha9.js.map +1 -0
- package/dist/esm/externalTypes/index.d.ts +9 -0
- package/dist/esm/externalTypes/index.d.ts.map +1 -0
- package/dist/esm/externalTypes/index.js +2 -0
- package/dist/esm/externalTypes/index.js.map +1 -0
- package/dist/esm/externalTypes/plugins.d.ts +75 -0
- package/dist/esm/externalTypes/plugins.d.ts.map +1 -0
- package/dist/esm/externalTypes/plugins.js +2 -0
- package/dist/esm/externalTypes/plugins.js.map +1 -0
- package/dist/esm/externalTypes/requestPipeline.d.ts +50 -0
- package/dist/esm/externalTypes/requestPipeline.d.ts.map +1 -0
- package/dist/esm/externalTypes/requestPipeline.js +2 -0
- package/dist/esm/externalTypes/requestPipeline.js.map +1 -0
- package/dist/esm/generated/packageVersion.d.ts +2 -0
- package/dist/esm/generated/packageVersion.d.ts.map +1 -0
- package/dist/esm/generated/packageVersion.js +2 -0
- package/dist/esm/generated/packageVersion.js.map +1 -0
- package/dist/esm/httpBatching.d.ts +4 -0
- package/dist/esm/httpBatching.d.ts.map +1 -0
- package/dist/esm/httpBatching.js +55 -0
- package/dist/esm/httpBatching.js.map +1 -0
- package/dist/esm/incrementalDeliveryPolyfill.d.ts +82 -0
- package/dist/esm/incrementalDeliveryPolyfill.d.ts.map +1 -0
- package/dist/esm/incrementalDeliveryPolyfill.js +38 -0
- package/dist/esm/incrementalDeliveryPolyfill.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internalErrorClasses.d.ts +28 -0
- package/dist/esm/internalErrorClasses.d.ts.map +1 -0
- package/dist/esm/internalErrorClasses.js +81 -0
- package/dist/esm/internalErrorClasses.js.map +1 -0
- package/dist/esm/internalPlugin.d.ts +9 -0
- package/dist/esm/internalPlugin.d.ts.map +1 -0
- package/dist/esm/internalPlugin.js +7 -0
- package/dist/esm/internalPlugin.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/plugin/cacheControl/index.d.ts +9 -0
- package/dist/esm/plugin/cacheControl/index.d.ts.map +1 -0
- package/dist/esm/plugin/cacheControl/index.js +220 -0
- package/dist/esm/plugin/cacheControl/index.js.map +1 -0
- package/dist/esm/plugin/disableSuggestions/index.d.ts +3 -0
- package/dist/esm/plugin/disableSuggestions/index.d.ts.map +1 -0
- package/dist/esm/plugin/disableSuggestions/index.js +19 -0
- package/dist/esm/plugin/disableSuggestions/index.js.map +1 -0
- package/dist/esm/plugin/disabled/index.d.ts +7 -0
- package/dist/esm/plugin/disabled/index.d.ts.map +1 -0
- package/dist/esm/plugin/disabled/index.js +23 -0
- package/dist/esm/plugin/disabled/index.js.map +1 -0
- package/dist/esm/plugin/drainHttpServer/index.d.ts +8 -0
- package/dist/esm/plugin/drainHttpServer/index.d.ts.map +1 -0
- package/dist/esm/plugin/drainHttpServer/index.js +16 -0
- package/dist/esm/plugin/drainHttpServer/index.js.map +1 -0
- package/dist/esm/plugin/drainHttpServer/stoppable.d.ts +10 -0
- package/dist/esm/plugin/drainHttpServer/stoppable.d.ts.map +1 -0
- package/dist/esm/plugin/drainHttpServer/stoppable.js +47 -0
- package/dist/esm/plugin/drainHttpServer/stoppable.js.map +1 -0
- package/dist/esm/plugin/inlineTrace/index.d.ts +8 -0
- package/dist/esm/plugin/inlineTrace/index.d.ts.map +1 -0
- package/dist/esm/plugin/inlineTrace/index.js +67 -0
- package/dist/esm/plugin/inlineTrace/index.js.map +1 -0
- package/dist/esm/plugin/landingPage/default/getEmbeddedHTML.d.ts +4 -0
- package/dist/esm/plugin/landingPage/default/getEmbeddedHTML.d.ts.map +1 -0
- package/dist/esm/plugin/landingPage/default/getEmbeddedHTML.js +138 -0
- package/dist/esm/plugin/landingPage/default/getEmbeddedHTML.js.map +1 -0
- package/dist/esm/plugin/landingPage/default/index.d.ts +9 -0
- package/dist/esm/plugin/landingPage/default/index.d.ts.map +1 -0
- package/dist/esm/plugin/landingPage/default/index.js +141 -0
- package/dist/esm/plugin/landingPage/default/index.js.map +1 -0
- package/dist/esm/plugin/landingPage/default/types.d.ts +56 -0
- package/dist/esm/plugin/landingPage/default/types.d.ts.map +1 -0
- package/dist/esm/plugin/landingPage/default/types.js +2 -0
- package/dist/esm/plugin/landingPage/default/types.js.map +1 -0
- package/dist/esm/plugin/schemaIsSubgraph.d.ts +3 -0
- package/dist/esm/plugin/schemaIsSubgraph.d.ts.map +1 -0
- package/dist/esm/plugin/schemaIsSubgraph.js +20 -0
- package/dist/esm/plugin/schemaIsSubgraph.js.map +1 -0
- package/dist/esm/plugin/schemaReporting/index.d.ts +10 -0
- package/dist/esm/plugin/schemaReporting/index.d.ts.map +1 -0
- package/dist/esm/plugin/schemaReporting/index.js +98 -0
- package/dist/esm/plugin/schemaReporting/index.js.map +1 -0
- package/dist/esm/plugin/schemaReporting/schemaReporter.d.ts +33 -0
- package/dist/esm/plugin/schemaReporting/schemaReporter.d.ts.map +1 -0
- package/dist/esm/plugin/schemaReporting/schemaReporter.js +143 -0
- package/dist/esm/plugin/schemaReporting/schemaReporter.js.map +1 -0
- package/dist/esm/plugin/subscriptionCallback/index.d.ts +12 -0
- package/dist/esm/plugin/subscriptionCallback/index.d.ts.map +1 -0
- package/dist/esm/plugin/subscriptionCallback/index.js +428 -0
- package/dist/esm/plugin/subscriptionCallback/index.js.map +1 -0
- package/dist/esm/plugin/traceTreeBuilder.d.ts +25 -0
- package/dist/esm/plugin/traceTreeBuilder.d.ts.map +1 -0
- package/dist/esm/plugin/traceTreeBuilder.js +196 -0
- package/dist/esm/plugin/traceTreeBuilder.js.map +1 -0
- package/dist/esm/plugin/usageReporting/defaultSendOperationsAsTrace.d.ts +3 -0
- package/dist/esm/plugin/usageReporting/defaultSendOperationsAsTrace.d.ts.map +1 -0
- package/dist/esm/plugin/usageReporting/defaultSendOperationsAsTrace.js +41 -0
- package/dist/esm/plugin/usageReporting/defaultSendOperationsAsTrace.js.map +1 -0
- package/dist/esm/plugin/usageReporting/durationHistogram.d.ts +16 -0
- package/dist/esm/plugin/usageReporting/durationHistogram.d.ts.map +1 -0
- package/dist/esm/plugin/usageReporting/durationHistogram.js +64 -0
- package/dist/esm/plugin/usageReporting/durationHistogram.js.map +1 -0
- package/dist/esm/plugin/usageReporting/index.d.ts +3 -0
- package/dist/esm/plugin/usageReporting/index.d.ts.map +1 -0
- package/dist/esm/plugin/usageReporting/index.js +2 -0
- package/dist/esm/plugin/usageReporting/index.js.map +1 -0
- package/dist/esm/plugin/usageReporting/iterateOverTrace.d.ts +7 -0
- package/dist/esm/plugin/usageReporting/iterateOverTrace.d.ts.map +1 -0
- package/dist/esm/plugin/usageReporting/iterateOverTrace.js +78 -0
- package/dist/esm/plugin/usageReporting/iterateOverTrace.js.map +1 -0
- package/dist/esm/plugin/usageReporting/operationDerivedDataCache.d.ts +12 -0
- package/dist/esm/plugin/usageReporting/operationDerivedDataCache.d.ts.map +1 -0
- package/dist/esm/plugin/usageReporting/operationDerivedDataCache.js +29 -0
- package/dist/esm/plugin/usageReporting/operationDerivedDataCache.js.map +1 -0
- package/dist/esm/plugin/usageReporting/options.d.ts +60 -0
- package/dist/esm/plugin/usageReporting/options.d.ts.map +1 -0
- package/dist/esm/plugin/usageReporting/options.js +2 -0
- package/dist/esm/plugin/usageReporting/options.js.map +1 -0
- package/dist/esm/plugin/usageReporting/plugin.d.ts +7 -0
- package/dist/esm/plugin/usageReporting/plugin.d.ts.map +1 -0
- package/dist/esm/plugin/usageReporting/plugin.js +487 -0
- package/dist/esm/plugin/usageReporting/plugin.js.map +1 -0
- package/dist/esm/plugin/usageReporting/stats.d.ts +96 -0
- package/dist/esm/plugin/usageReporting/stats.d.ts.map +1 -0
- package/dist/esm/plugin/usageReporting/stats.js +283 -0
- package/dist/esm/plugin/usageReporting/stats.js.map +1 -0
- package/dist/esm/plugin/usageReporting/traceDetails.d.ts +4 -0
- package/dist/esm/plugin/usageReporting/traceDetails.d.ts.map +1 -0
- package/dist/esm/plugin/usageReporting/traceDetails.js +60 -0
- package/dist/esm/plugin/usageReporting/traceDetails.js.map +1 -0
- package/dist/esm/preventCsrf.d.ts +4 -0
- package/dist/esm/preventCsrf.d.ts.map +1 -0
- package/dist/esm/preventCsrf.js +34 -0
- package/dist/esm/preventCsrf.js.map +1 -0
- package/dist/esm/requestPipeline.d.ts +9 -0
- package/dist/esm/requestPipeline.d.ts.map +1 -0
- package/dist/esm/requestPipeline.js +364 -0
- package/dist/esm/requestPipeline.js.map +1 -0
- package/dist/esm/runHttpQuery.d.ts +15 -0
- package/dist/esm/runHttpQuery.d.ts.map +1 -0
- package/dist/esm/runHttpQuery.js +221 -0
- package/dist/esm/runHttpQuery.js.map +1 -0
- package/dist/esm/standalone/index.d.ts +25 -0
- package/dist/esm/standalone/index.d.ts.map +1 -0
- package/dist/esm/standalone/index.js +91 -0
- package/dist/esm/standalone/index.js.map +1 -0
- package/dist/esm/utils/HeaderMap.d.ts +8 -0
- package/dist/esm/utils/HeaderMap.d.ts.map +1 -0
- package/dist/esm/utils/HeaderMap.js +16 -0
- package/dist/esm/utils/HeaderMap.js.map +1 -0
- package/dist/esm/utils/UnreachableCaseError.d.ts +4 -0
- package/dist/esm/utils/UnreachableCaseError.d.ts.map +1 -0
- package/dist/esm/utils/UnreachableCaseError.js +6 -0
- package/dist/esm/utils/UnreachableCaseError.js.map +1 -0
- package/dist/esm/utils/computeCoreSchemaHash.d.ts +2 -0
- package/dist/esm/utils/computeCoreSchemaHash.d.ts.map +1 -0
- package/dist/esm/utils/computeCoreSchemaHash.js +5 -0
- package/dist/esm/utils/computeCoreSchemaHash.js.map +1 -0
- package/dist/esm/utils/invokeHooks.d.ts +7 -0
- package/dist/esm/utils/invokeHooks.d.ts.map +1 -0
- package/dist/esm/utils/invokeHooks.js +31 -0
- package/dist/esm/utils/invokeHooks.js.map +1 -0
- package/dist/esm/utils/isDefined.d.ts +2 -0
- package/dist/esm/utils/isDefined.d.ts.map +1 -0
- package/dist/esm/utils/isDefined.js +4 -0
- package/dist/esm/utils/isDefined.js.map +1 -0
- package/dist/esm/utils/makeGatewayGraphQLRequestContext.d.ts +5 -0
- package/dist/esm/utils/makeGatewayGraphQLRequestContext.d.ts.map +1 -0
- package/dist/esm/utils/makeGatewayGraphQLRequestContext.js +93 -0
- package/dist/esm/utils/makeGatewayGraphQLRequestContext.js.map +1 -0
- package/dist/esm/utils/resolvable.d.ts +7 -0
- package/dist/esm/utils/resolvable.d.ts.map +1 -0
- package/dist/esm/utils/resolvable.js +12 -0
- package/dist/esm/utils/resolvable.js.map +1 -0
- package/dist/esm/utils/schemaInstrumentation.d.ts +16 -0
- package/dist/esm/utils/schemaInstrumentation.d.ts.map +1 -0
- package/dist/esm/utils/schemaInstrumentation.js +69 -0
- package/dist/esm/utils/schemaInstrumentation.js.map +1 -0
- package/dist/esm/utils/schemaManager.d.ts +31 -0
- package/dist/esm/utils/schemaManager.d.ts.map +1 -0
- package/dist/esm/utils/schemaManager.js +99 -0
- package/dist/esm/utils/schemaManager.js.map +1 -0
- package/dist/esm/utils/urlForHttpServer.d.ts +3 -0
- package/dist/esm/utils/urlForHttpServer.d.ts.map +1 -0
- package/dist/esm/utils/urlForHttpServer.js +12 -0
- package/dist/esm/utils/urlForHttpServer.js.map +1 -0
- package/dist/esm/validationRules/NoIntrospection.d.ts +3 -0
- package/dist/esm/validationRules/NoIntrospection.d.ts.map +1 -0
- package/dist/esm/validationRules/NoIntrospection.js +15 -0
- package/dist/esm/validationRules/NoIntrospection.js.map +1 -0
- package/dist/esm/validationRules/RecursiveSelectionsLimit.d.ts +4 -0
- package/dist/esm/validationRules/RecursiveSelectionsLimit.d.ts.map +1 -0
- package/dist/esm/validationRules/RecursiveSelectionsLimit.js +146 -0
- package/dist/esm/validationRules/RecursiveSelectionsLimit.js.map +1 -0
- package/dist/esm/validationRules/index.d.ts +3 -0
- package/dist/esm/validationRules/index.d.ts.map +1 -0
- package/dist/esm/validationRules/index.js +3 -0
- package/dist/esm/validationRules/index.js.map +1 -0
- package/errors/package.json +8 -0
- package/package.json +208 -0
- package/plugin/cacheControl/package.json +8 -0
- package/plugin/disableSuggestions/package.json +8 -0
- package/plugin/disabled/package.json +8 -0
- package/plugin/drainHttpServer/package.json +8 -0
- package/plugin/inlineTrace/package.json +8 -0
- package/plugin/landingPage/default/package.json +8 -0
- package/plugin/schemaReporting/package.json +8 -0
- package/plugin/subscriptionCallback/package.json +8 -0
- package/plugin/usageReporting/package.json +8 -0
- package/src/ApolloServer.ts +1456 -0
- package/src/cachePolicy.ts +33 -0
- package/src/determineApolloConfig.ts +95 -0
- package/src/errorNormalize.ts +114 -0
- package/src/errors/index.ts +33 -0
- package/src/externalTypes/constructor.ts +174 -0
- package/src/externalTypes/context.ts +18 -0
- package/src/externalTypes/graphql.ts +81 -0
- package/src/externalTypes/http.ts +44 -0
- package/src/externalTypes/incrementalDeliveryPolyfillAlpha2.ts +63 -0
- package/src/externalTypes/incrementalDeliveryPolyfillAlpha9.ts +82 -0
- package/src/externalTypes/index.ts +73 -0
- package/src/externalTypes/plugins.ts +222 -0
- package/src/externalTypes/requestPipeline.ts +123 -0
- package/src/generated/packageVersion.ts +1 -0
- package/src/httpBatching.ts +105 -0
- package/src/incrementalDeliveryPolyfill.ts +253 -0
- package/src/index.ts +4 -0
- package/src/internalErrorClasses.ts +123 -0
- package/src/internalPlugin.ts +42 -0
- package/src/plugin/cacheControl/index.ts +453 -0
- package/src/plugin/disableSuggestions/index.ts +23 -0
- package/src/plugin/disabled/index.ts +41 -0
- package/src/plugin/drainHttpServer/index.ts +42 -0
- package/src/plugin/drainHttpServer/stoppable.ts +109 -0
- package/src/plugin/inlineTrace/index.ts +156 -0
- package/src/plugin/landingPage/default/getEmbeddedHTML.ts +204 -0
- package/src/plugin/landingPage/default/index.ts +219 -0
- package/src/plugin/landingPage/default/types.ts +198 -0
- package/src/plugin/schemaIsSubgraph.ts +41 -0
- package/src/plugin/schemaReporting/generated/operations.d.ts +18359 -0
- package/src/plugin/schemaReporting/index.ts +198 -0
- package/src/plugin/schemaReporting/schemaReporter.ts +207 -0
- package/src/plugin/subscriptionCallback/index.ts +724 -0
- package/src/plugin/traceTreeBuilder.ts +356 -0
- package/src/plugin/usageReporting/defaultSendOperationsAsTrace.ts +74 -0
- package/src/plugin/usageReporting/durationHistogram.ts +87 -0
- package/src/plugin/usageReporting/index.ts +9 -0
- package/src/plugin/usageReporting/iterateOverTrace.ts +140 -0
- package/src/plugin/usageReporting/operationDerivedDataCache.ts +61 -0
- package/src/plugin/usageReporting/options.ts +414 -0
- package/src/plugin/usageReporting/plugin.ts +871 -0
- package/src/plugin/usageReporting/stats.ts +492 -0
- package/src/plugin/usageReporting/traceDetails.ts +96 -0
- package/src/preventCsrf.ts +99 -0
- package/src/requestPipeline.ts +821 -0
- package/src/runHttpQuery.ts +408 -0
- package/src/standalone/index.ts +155 -0
- package/src/utils/HeaderMap.ts +22 -0
- package/src/utils/UnreachableCaseError.ts +10 -0
- package/src/utils/computeCoreSchemaHash.ts +9 -0
- package/src/utils/invokeHooks.ts +53 -0
- package/src/utils/isDefined.ts +3 -0
- package/src/utils/makeGatewayGraphQLRequestContext.ts +197 -0
- package/src/utils/resolvable.ts +30 -0
- package/src/utils/schemaInstrumentation.ts +132 -0
- package/src/utils/schemaManager.ts +212 -0
- package/src/utils/urlForHttpServer.ts +21 -0
- package/src/validationRules/NoIntrospection.ts +27 -0
- package/src/validationRules/RecursiveSelectionsLimit.ts +198 -0
- package/src/validationRules/index.ts +5 -0
- package/standalone/package.json +8 -0
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
import type { ApolloServerPlugin } from '../../externalTypes/index.js';
|
|
2
|
+
import {
|
|
3
|
+
type DirectiveNode,
|
|
4
|
+
getNamedType,
|
|
5
|
+
type GraphQLCompositeType,
|
|
6
|
+
type GraphQLField,
|
|
7
|
+
isCompositeType,
|
|
8
|
+
isInterfaceType,
|
|
9
|
+
isObjectType,
|
|
10
|
+
responsePathAsArray,
|
|
11
|
+
} from 'graphql';
|
|
12
|
+
import { newCachePolicy } from '../../cachePolicy.js';
|
|
13
|
+
import { internalPlugin } from '../../internalPlugin.js';
|
|
14
|
+
import { LRUCache } from 'lru-cache';
|
|
15
|
+
import type {
|
|
16
|
+
CacheHint,
|
|
17
|
+
CacheScope,
|
|
18
|
+
GraphQLResolveInfoWithCacheControl,
|
|
19
|
+
} from '@apollo/cache-control-types';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* CacheAnnotation represents the contents of a `@cacheControl` directive.
|
|
23
|
+
* (`inheritMaxAge` is part of this interface and not CacheHint, because
|
|
24
|
+
* `inheritMaxAge` isn't a contributing piece of a cache policy: it just means
|
|
25
|
+
* to not apply default values in some contexts.)
|
|
26
|
+
*/
|
|
27
|
+
interface CacheAnnotation extends CacheHint {
|
|
28
|
+
inheritMaxAge?: true;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface ApolloServerPluginCacheControlOptions {
|
|
32
|
+
/**
|
|
33
|
+
* All root fields and fields returning objects or interfaces have this value
|
|
34
|
+
* for `maxAge` unless they set a cache hint with a non-undefined `maxAge`
|
|
35
|
+
* using `@cacheControl` or `setCacheHint`. The default is 0, which means "not
|
|
36
|
+
* cacheable". (That is: if you don't set `defaultMaxAge`, then every root
|
|
37
|
+
* field in your operation and every field with sub-fields must have a cache
|
|
38
|
+
* hint or the overall operation will not be cacheable.)
|
|
39
|
+
*/
|
|
40
|
+
defaultMaxAge?: number;
|
|
41
|
+
/**
|
|
42
|
+
* Determines whether to set the `Cache-Control` HTTP header. If true (the
|
|
43
|
+
* default), the header is written on all responses (with a value of
|
|
44
|
+
* `no-store` for non-cacheable responses). If `'if-cacheable'`, the header is
|
|
45
|
+
* only written for cacheable responses. If false, the header is never
|
|
46
|
+
* written. A response is cacheable if its overall cache policy has a non-zero
|
|
47
|
+
* `maxAge`, and the body is a single result rather than an incremental
|
|
48
|
+
* delivery response, and the body contains no errors.
|
|
49
|
+
*/
|
|
50
|
+
calculateHttpHeaders?: boolean | 'if-cacheable';
|
|
51
|
+
// For testing only.
|
|
52
|
+
__testing__cacheHints?: Map<string, CacheHint>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function ApolloServerPluginCacheControl(
|
|
56
|
+
options: ApolloServerPluginCacheControlOptions = Object.create(null),
|
|
57
|
+
): ApolloServerPlugin {
|
|
58
|
+
let typeAnnotationCache: LRUCache<GraphQLCompositeType, CacheAnnotation>;
|
|
59
|
+
|
|
60
|
+
let fieldAnnotationCache: LRUCache<
|
|
61
|
+
GraphQLField<unknown, unknown>,
|
|
62
|
+
CacheAnnotation
|
|
63
|
+
>;
|
|
64
|
+
|
|
65
|
+
return internalPlugin({
|
|
66
|
+
__internal_plugin_id__: 'CacheControl',
|
|
67
|
+
__is_disabled_plugin__: false,
|
|
68
|
+
|
|
69
|
+
async serverWillStart({ schema }) {
|
|
70
|
+
// Set the size of the caches to be equal to the number of composite types
|
|
71
|
+
// and fields in the schema respectively. This generally means that the
|
|
72
|
+
// cache will always have room for all the cache hints in the active
|
|
73
|
+
// schema but we won't have a memory leak as schemas are replaced in a
|
|
74
|
+
// gateway. (Once we're comfortable breaking compatibility with
|
|
75
|
+
// versions of Gateway older than 0.35.0, we should also run this code
|
|
76
|
+
// from a schemaDidLoadOrUpdate instead of serverWillStart. Using
|
|
77
|
+
// schemaDidLoadOrUpdate throws when combined with old gateways.)
|
|
78
|
+
typeAnnotationCache = new LRUCache<GraphQLCompositeType, CacheAnnotation>(
|
|
79
|
+
{
|
|
80
|
+
max: Object.values(schema.getTypeMap()).filter(isCompositeType)
|
|
81
|
+
.length,
|
|
82
|
+
},
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
fieldAnnotationCache = new LRUCache<
|
|
86
|
+
GraphQLField<unknown, unknown>,
|
|
87
|
+
CacheAnnotation
|
|
88
|
+
>({
|
|
89
|
+
max:
|
|
90
|
+
Object.values(schema.getTypeMap())
|
|
91
|
+
.filter(isObjectType)
|
|
92
|
+
.flatMap((t) => Object.values(t.getFields())).length +
|
|
93
|
+
Object.values(schema.getTypeMap())
|
|
94
|
+
.filter(isInterfaceType)
|
|
95
|
+
.flatMap((t) => Object.values(t.getFields())).length,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
return undefined;
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
async requestDidStart(requestContext) {
|
|
102
|
+
function memoizedCacheAnnotationFromType(
|
|
103
|
+
t: GraphQLCompositeType,
|
|
104
|
+
): CacheAnnotation {
|
|
105
|
+
const existing = typeAnnotationCache.get(t);
|
|
106
|
+
if (existing) {
|
|
107
|
+
return existing;
|
|
108
|
+
}
|
|
109
|
+
const annotation = cacheAnnotationFromType(t);
|
|
110
|
+
typeAnnotationCache.set(t, annotation);
|
|
111
|
+
return annotation;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function memoizedCacheAnnotationFromField(
|
|
115
|
+
field: GraphQLField<unknown, unknown>,
|
|
116
|
+
): CacheAnnotation {
|
|
117
|
+
const existing = fieldAnnotationCache.get(field);
|
|
118
|
+
if (existing) {
|
|
119
|
+
return existing;
|
|
120
|
+
}
|
|
121
|
+
const annotation = cacheAnnotationFromField(field);
|
|
122
|
+
fieldAnnotationCache.set(field, annotation);
|
|
123
|
+
return annotation;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const defaultMaxAge: number = options.defaultMaxAge ?? 0;
|
|
127
|
+
const calculateHttpHeaders = options.calculateHttpHeaders ?? true;
|
|
128
|
+
const { __testing__cacheHints } = options;
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
async executionDidStart() {
|
|
132
|
+
// Did something set the overall cache policy before we've even
|
|
133
|
+
// started? If so, consider that as an override and don't touch it.
|
|
134
|
+
// Just put set up fake `info.cacheControl` objects and otherwise
|
|
135
|
+
// don't track cache policy.
|
|
136
|
+
//
|
|
137
|
+
// (This doesn't happen in practice using the core plugins: the main
|
|
138
|
+
// use case for restricting overallCachePolicy outside of this plugin
|
|
139
|
+
// is apollo-server-plugin-response-cache, but when it sets the policy
|
|
140
|
+
// we never get to execution at all.)
|
|
141
|
+
if (isRestricted(requestContext.overallCachePolicy)) {
|
|
142
|
+
// This is "fake" in the sense that it never actually affects
|
|
143
|
+
// requestContext.overallCachePolicy.
|
|
144
|
+
const fakeFieldPolicy = newCachePolicy();
|
|
145
|
+
return {
|
|
146
|
+
willResolveField({ info }) {
|
|
147
|
+
// This `as` is "safe" in the sense that this is the statement
|
|
148
|
+
// that makes a GraphQLResolveInfo into a
|
|
149
|
+
// GraphQLResolveInfoWithCacheControl.
|
|
150
|
+
(info as GraphQLResolveInfoWithCacheControl).cacheControl = {
|
|
151
|
+
setCacheHint: (dynamicHint: CacheHint) => {
|
|
152
|
+
fakeFieldPolicy.replace(dynamicHint);
|
|
153
|
+
},
|
|
154
|
+
cacheHint: fakeFieldPolicy,
|
|
155
|
+
cacheHintFromType: memoizedCacheAnnotationFromType,
|
|
156
|
+
};
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
willResolveField({ info }) {
|
|
163
|
+
const fieldPolicy = newCachePolicy();
|
|
164
|
+
|
|
165
|
+
let inheritMaxAge = false;
|
|
166
|
+
|
|
167
|
+
// If this field's resolver returns an object/interface/union
|
|
168
|
+
// (maybe wrapped in list/non-null), look for hints on that return
|
|
169
|
+
// type.
|
|
170
|
+
const targetType = getNamedType(info.returnType);
|
|
171
|
+
if (isCompositeType(targetType)) {
|
|
172
|
+
const typeAnnotation =
|
|
173
|
+
memoizedCacheAnnotationFromType(targetType);
|
|
174
|
+
fieldPolicy.replace(typeAnnotation);
|
|
175
|
+
inheritMaxAge = !!typeAnnotation.inheritMaxAge;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Look for hints on the field itself (on its parent type), taking
|
|
179
|
+
// precedence over previously calculated hints.
|
|
180
|
+
const fieldAnnotation = memoizedCacheAnnotationFromField(
|
|
181
|
+
info.parentType.getFields()[info.fieldName],
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
// Note that specifying `@cacheControl(inheritMaxAge: true)` on a
|
|
185
|
+
// field whose return type defines a `maxAge` gives precedence to
|
|
186
|
+
// the type's `maxAge`. (Perhaps this should be some sort of
|
|
187
|
+
// error.)
|
|
188
|
+
if (
|
|
189
|
+
fieldAnnotation.inheritMaxAge &&
|
|
190
|
+
fieldPolicy.maxAge === undefined
|
|
191
|
+
) {
|
|
192
|
+
inheritMaxAge = true;
|
|
193
|
+
// Handle `@cacheControl(inheritMaxAge: true, scope: PRIVATE)`.
|
|
194
|
+
// (We ignore any specified `maxAge`; perhaps it should be some
|
|
195
|
+
// sort of error.)
|
|
196
|
+
if (fieldAnnotation.scope) {
|
|
197
|
+
fieldPolicy.replace({ scope: fieldAnnotation.scope });
|
|
198
|
+
}
|
|
199
|
+
} else {
|
|
200
|
+
fieldPolicy.replace(fieldAnnotation);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// This `as` is "safe" in the sense that this is the statement
|
|
204
|
+
// that makes a GraphQLResolveInfo into a
|
|
205
|
+
// GraphQLResolveInfoWithCacheControl.
|
|
206
|
+
(info as GraphQLResolveInfoWithCacheControl).cacheControl = {
|
|
207
|
+
setCacheHint: (dynamicHint: CacheHint) => {
|
|
208
|
+
fieldPolicy.replace(dynamicHint);
|
|
209
|
+
},
|
|
210
|
+
cacheHint: fieldPolicy,
|
|
211
|
+
cacheHintFromType: memoizedCacheAnnotationFromType,
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
// When the resolver is done, call restrict once. By calling
|
|
215
|
+
// restrict after the resolver instead of before, we don't need to
|
|
216
|
+
// "undo" the effect on overallCachePolicy of a static hint that
|
|
217
|
+
// gets refined by a dynamic hint.
|
|
218
|
+
return () => {
|
|
219
|
+
// If this field returns a composite type or is a root field and
|
|
220
|
+
// we haven't seen an explicit maxAge hint, set the maxAge to 0
|
|
221
|
+
// (uncached) or the default if specified in the constructor.
|
|
222
|
+
// (Non-object fields by default are assumed to inherit their
|
|
223
|
+
// cacheability from their parents. But on the other hand, while
|
|
224
|
+
// root non-object fields can get explicit hints from their
|
|
225
|
+
// definition on the Query/Mutation object, if that doesn't
|
|
226
|
+
// exist then there's no parent field that would assign the
|
|
227
|
+
// default maxAge, so we do it here.)
|
|
228
|
+
//
|
|
229
|
+
// You can disable this on a non-root field by writing
|
|
230
|
+
// `@cacheControl(inheritMaxAge: true)` on it. If you do this,
|
|
231
|
+
// then its children will be treated like root paths, since
|
|
232
|
+
// there is no parent maxAge to inherit.
|
|
233
|
+
//
|
|
234
|
+
// We do this in the end hook so that dynamic cache control
|
|
235
|
+
// prevents it from happening (eg,
|
|
236
|
+
// `info.cacheControl.cacheHint.restrict({maxAge: 60})` should
|
|
237
|
+
// work rather than doing nothing because we've already set the
|
|
238
|
+
// max age to the default of 0). This also lets resolvers assume
|
|
239
|
+
// any hint in `info.cacheControl.cacheHint` was explicitly set.
|
|
240
|
+
if (
|
|
241
|
+
fieldPolicy.maxAge === undefined &&
|
|
242
|
+
((isCompositeType(targetType) && !inheritMaxAge) ||
|
|
243
|
+
!info.path.prev)
|
|
244
|
+
) {
|
|
245
|
+
fieldPolicy.restrict({ maxAge: defaultMaxAge });
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (__testing__cacheHints && isRestricted(fieldPolicy)) {
|
|
249
|
+
const path = responsePathAsArray(info.path).join('.');
|
|
250
|
+
if (__testing__cacheHints.has(path)) {
|
|
251
|
+
throw Error(
|
|
252
|
+
"shouldn't happen: addHint should only be called once per path",
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
__testing__cacheHints.set(path, {
|
|
256
|
+
maxAge: fieldPolicy.maxAge,
|
|
257
|
+
scope: fieldPolicy.scope,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
requestContext.overallCachePolicy.restrict(fieldPolicy);
|
|
261
|
+
};
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
},
|
|
265
|
+
|
|
266
|
+
async willSendResponse(requestContext) {
|
|
267
|
+
// This hook is just for setting response headers, so make sure that
|
|
268
|
+
// hasn't been disabled.
|
|
269
|
+
if (!calculateHttpHeaders) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const { response, overallCachePolicy } = requestContext;
|
|
274
|
+
|
|
275
|
+
// Look to see if something has already set the cache-control header.
|
|
276
|
+
// This could be a different plugin... or it could be this very plugin
|
|
277
|
+
// operating on a different operation in the same batched HTTP
|
|
278
|
+
// request.
|
|
279
|
+
const existingCacheControlHeader = parseExistingCacheControlHeader(
|
|
280
|
+
response.http.headers.get('cache-control'),
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
// If the header contains something other than a value that this
|
|
284
|
+
// plugin sets, then we leave it alone. We don't want to mangle
|
|
285
|
+
// something important that you set! That said, it's probably best to
|
|
286
|
+
// have only one piece of code that writes to a given header, so you
|
|
287
|
+
// should probably set `calculateHttpHeaders: false` on this plugin.
|
|
288
|
+
if (existingCacheControlHeader.kind === 'unparsable') {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const cachePolicy = newCachePolicy();
|
|
293
|
+
cachePolicy.replace(overallCachePolicy);
|
|
294
|
+
if (existingCacheControlHeader.kind === 'parsable-and-cacheable') {
|
|
295
|
+
cachePolicy.restrict(existingCacheControlHeader.hint);
|
|
296
|
+
}
|
|
297
|
+
const policyIfCacheable = cachePolicy.policyIfCacheable();
|
|
298
|
+
|
|
299
|
+
if (
|
|
300
|
+
// This code path is only for if we believe it is cacheable.
|
|
301
|
+
policyIfCacheable &&
|
|
302
|
+
// Either there wasn't a cache-control header already, or we've
|
|
303
|
+
// already incorporated it into policyIfCacheable. (If we couldn't
|
|
304
|
+
// parse it, that means some other plugin or mechanism set the
|
|
305
|
+
// header. This is confusing, so we just don't make any more
|
|
306
|
+
// changes. You should probably set `calculateHttpHeaders` to false
|
|
307
|
+
// in that case and only set the header from one place.)
|
|
308
|
+
existingCacheControlHeader.kind !== 'uncacheable' &&
|
|
309
|
+
// At least for now, we don't set cache-control headers for
|
|
310
|
+
// incremental delivery responses, since we don't know if a later
|
|
311
|
+
// part of the execution will affect the cache policy (perhaps
|
|
312
|
+
// dynamically). (Note that willSendResponse is called when the
|
|
313
|
+
// initial payload is sent, not the final payload.)
|
|
314
|
+
response.body.kind === 'single' &&
|
|
315
|
+
!response.body.singleResult.errors
|
|
316
|
+
) {
|
|
317
|
+
response.http.headers.set(
|
|
318
|
+
'cache-control',
|
|
319
|
+
`max-age=${
|
|
320
|
+
policyIfCacheable.maxAge
|
|
321
|
+
}, ${policyIfCacheable.scope.toLowerCase()}`,
|
|
322
|
+
);
|
|
323
|
+
} else if (calculateHttpHeaders !== 'if-cacheable') {
|
|
324
|
+
// The response is not cacheable, so make sure it doesn't get
|
|
325
|
+
// cached. This is especially important for GET requests, because
|
|
326
|
+
// browsers and other agents cache many GET requests by default.
|
|
327
|
+
// (But if some other plugin set the header to a value that this
|
|
328
|
+
// plugin does not produce, we don't do anything.)
|
|
329
|
+
response.http.headers.set(
|
|
330
|
+
'cache-control',
|
|
331
|
+
CACHE_CONTROL_HEADER_UNCACHEABLE,
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
},
|
|
335
|
+
};
|
|
336
|
+
},
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const CACHE_CONTROL_HEADER_CACHEABLE_REGEXP =
|
|
341
|
+
/^max-age=(\d+), (public|private)$/;
|
|
342
|
+
const CACHE_CONTROL_HEADER_UNCACHEABLE = 'no-store';
|
|
343
|
+
|
|
344
|
+
type ExistingCacheControlHeader =
|
|
345
|
+
| { kind: 'no-header' }
|
|
346
|
+
| { kind: 'uncacheable' }
|
|
347
|
+
| { kind: 'parsable-and-cacheable'; hint: CacheHint }
|
|
348
|
+
| { kind: 'unparsable' };
|
|
349
|
+
|
|
350
|
+
function parseExistingCacheControlHeader(
|
|
351
|
+
header: string | undefined,
|
|
352
|
+
): ExistingCacheControlHeader {
|
|
353
|
+
if (!header) {
|
|
354
|
+
return { kind: 'no-header' };
|
|
355
|
+
}
|
|
356
|
+
if (header === CACHE_CONTROL_HEADER_UNCACHEABLE) {
|
|
357
|
+
return { kind: 'uncacheable' };
|
|
358
|
+
}
|
|
359
|
+
const match = CACHE_CONTROL_HEADER_CACHEABLE_REGEXP.exec(header);
|
|
360
|
+
if (!match) {
|
|
361
|
+
return { kind: 'unparsable' };
|
|
362
|
+
}
|
|
363
|
+
return {
|
|
364
|
+
kind: 'parsable-and-cacheable',
|
|
365
|
+
hint: {
|
|
366
|
+
maxAge: +match[1],
|
|
367
|
+
scope: match[2] === 'public' ? 'PUBLIC' : 'PRIVATE',
|
|
368
|
+
},
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function cacheAnnotationFromDirectives(
|
|
373
|
+
directives: ReadonlyArray<DirectiveNode> | undefined,
|
|
374
|
+
): CacheAnnotation | undefined {
|
|
375
|
+
if (!directives) return undefined;
|
|
376
|
+
|
|
377
|
+
const cacheControlDirective = directives.find(
|
|
378
|
+
(directive) => directive.name.value === 'cacheControl',
|
|
379
|
+
);
|
|
380
|
+
if (!cacheControlDirective) return undefined;
|
|
381
|
+
|
|
382
|
+
if (!cacheControlDirective.arguments) return undefined;
|
|
383
|
+
|
|
384
|
+
const maxAgeArgument = cacheControlDirective.arguments.find(
|
|
385
|
+
(argument) => argument.name.value === 'maxAge',
|
|
386
|
+
);
|
|
387
|
+
const scopeArgument = cacheControlDirective.arguments.find(
|
|
388
|
+
(argument) => argument.name.value === 'scope',
|
|
389
|
+
);
|
|
390
|
+
const inheritMaxAgeArgument = cacheControlDirective.arguments.find(
|
|
391
|
+
(argument) => argument.name.value === 'inheritMaxAge',
|
|
392
|
+
);
|
|
393
|
+
|
|
394
|
+
const scopeString =
|
|
395
|
+
scopeArgument?.value?.kind === 'EnumValue'
|
|
396
|
+
? scopeArgument.value.value
|
|
397
|
+
: undefined;
|
|
398
|
+
|
|
399
|
+
const scope: CacheScope | undefined =
|
|
400
|
+
scopeString === 'PUBLIC' || scopeString === 'PRIVATE'
|
|
401
|
+
? scopeString
|
|
402
|
+
: undefined;
|
|
403
|
+
|
|
404
|
+
if (
|
|
405
|
+
inheritMaxAgeArgument?.value?.kind === 'BooleanValue' &&
|
|
406
|
+
inheritMaxAgeArgument.value.value
|
|
407
|
+
) {
|
|
408
|
+
// We ignore maxAge if it is also specified.
|
|
409
|
+
return { inheritMaxAge: true, scope };
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
return {
|
|
413
|
+
maxAge:
|
|
414
|
+
maxAgeArgument?.value?.kind === 'IntValue'
|
|
415
|
+
? parseInt(maxAgeArgument.value.value)
|
|
416
|
+
: undefined,
|
|
417
|
+
scope,
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function cacheAnnotationFromType(t: GraphQLCompositeType): CacheAnnotation {
|
|
422
|
+
if (t.astNode) {
|
|
423
|
+
const hint = cacheAnnotationFromDirectives(t.astNode.directives);
|
|
424
|
+
if (hint) {
|
|
425
|
+
return hint;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
if (t.extensionASTNodes) {
|
|
429
|
+
for (const node of t.extensionASTNodes) {
|
|
430
|
+
const hint = cacheAnnotationFromDirectives(node.directives);
|
|
431
|
+
if (hint) {
|
|
432
|
+
return hint;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
return {};
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
function cacheAnnotationFromField(
|
|
440
|
+
field: GraphQLField<unknown, unknown>,
|
|
441
|
+
): CacheAnnotation {
|
|
442
|
+
if (field.astNode) {
|
|
443
|
+
const hint = cacheAnnotationFromDirectives(field.astNode.directives);
|
|
444
|
+
if (hint) {
|
|
445
|
+
return hint;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
return {};
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
function isRestricted(hint: CacheHint) {
|
|
452
|
+
return hint.maxAge !== undefined || hint.scope !== undefined;
|
|
453
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ApolloServerPlugin } from '../../externalTypes/index.js';
|
|
2
|
+
import { internalPlugin } from '../../internalPlugin.js';
|
|
3
|
+
|
|
4
|
+
export function ApolloServerPluginDisableSuggestions(): ApolloServerPlugin {
|
|
5
|
+
return internalPlugin({
|
|
6
|
+
__internal_plugin_id__: 'DisableSuggestions',
|
|
7
|
+
__is_disabled_plugin__: false,
|
|
8
|
+
async requestDidStart() {
|
|
9
|
+
return {
|
|
10
|
+
async validationDidStart() {
|
|
11
|
+
return async (validationErrors) => {
|
|
12
|
+
validationErrors?.forEach((error) => {
|
|
13
|
+
error.message = error.message.replace(
|
|
14
|
+
/ ?Did you mean(.+?)\?$/,
|
|
15
|
+
'',
|
|
16
|
+
);
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// This file exports the "disabled" version of various plugins which are
|
|
2
|
+
// installed by default under certain circumstances. This lets users explicitly
|
|
3
|
+
// choose not to enable these plugins. Note that we explicitly keep these tiny
|
|
4
|
+
// plugins separate from the plugins they are enabling; this means that we don't
|
|
5
|
+
// have to load (say) the entire `plugin/usageReporting` entry point (which
|
|
6
|
+
// includes the whole generated protobuf library, etc) just in order to disable
|
|
7
|
+
// usage reporting.
|
|
8
|
+
|
|
9
|
+
import type { BaseContext, ApolloServerPlugin } from '../../index.js';
|
|
10
|
+
import type {
|
|
11
|
+
InternalApolloServerPlugin,
|
|
12
|
+
InternalPluginId,
|
|
13
|
+
} from '../../internalPlugin.js';
|
|
14
|
+
|
|
15
|
+
function disabledPlugin(id: InternalPluginId): ApolloServerPlugin {
|
|
16
|
+
const plugin: InternalApolloServerPlugin<BaseContext> = {
|
|
17
|
+
__internal_plugin_id__: id,
|
|
18
|
+
__is_disabled_plugin__: true,
|
|
19
|
+
};
|
|
20
|
+
return plugin;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function ApolloServerPluginCacheControlDisabled(): ApolloServerPlugin<BaseContext> {
|
|
24
|
+
return disabledPlugin('CacheControl');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function ApolloServerPluginInlineTraceDisabled(): ApolloServerPlugin<BaseContext> {
|
|
28
|
+
return disabledPlugin('InlineTrace');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function ApolloServerPluginLandingPageDisabled(): ApolloServerPlugin<BaseContext> {
|
|
32
|
+
return disabledPlugin('LandingPageDisabled');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function ApolloServerPluginSchemaReportingDisabled(): ApolloServerPlugin<BaseContext> {
|
|
36
|
+
return disabledPlugin('SchemaReporting');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function ApolloServerPluginUsageReportingDisabled(): ApolloServerPlugin<BaseContext> {
|
|
40
|
+
return disabledPlugin('UsageReporting');
|
|
41
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type http from 'http';
|
|
2
|
+
import type { ApolloServerPlugin } from '../../externalTypes/index.js';
|
|
3
|
+
import { Stopper } from './stoppable.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Options for ApolloServerPluginDrainHttpServer.
|
|
7
|
+
*/
|
|
8
|
+
export interface ApolloServerPluginDrainHttpServerOptions {
|
|
9
|
+
/**
|
|
10
|
+
* The http.Server (or https.Server, etc) to drain. Required.
|
|
11
|
+
*/
|
|
12
|
+
httpServer: http.Server;
|
|
13
|
+
/**
|
|
14
|
+
* How long to wait before forcefully closing non-idle connections.
|
|
15
|
+
* Defaults to 10_000 (ten seconds).
|
|
16
|
+
*/
|
|
17
|
+
stopGracePeriodMillis?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* This plugin is used with frameworks built on Node's http.Server
|
|
22
|
+
* (`startStandaloneServer`, Express, etc) to drain your HTTP server on
|
|
23
|
+
* shutdown. See
|
|
24
|
+
* https://www.apollographql.com/docs/apollo-server/api/plugin/drain-http-server/
|
|
25
|
+
* for details.
|
|
26
|
+
*/
|
|
27
|
+
export function ApolloServerPluginDrainHttpServer(
|
|
28
|
+
options: ApolloServerPluginDrainHttpServerOptions,
|
|
29
|
+
): ApolloServerPlugin {
|
|
30
|
+
const stopper = new Stopper(options.httpServer);
|
|
31
|
+
return {
|
|
32
|
+
async serverWillStart() {
|
|
33
|
+
return {
|
|
34
|
+
async drainServer() {
|
|
35
|
+
const stopGracePeriodMillis = options.stopGracePeriodMillis ?? 10_000;
|
|
36
|
+
const signal = AbortSignal.timeout(stopGracePeriodMillis);
|
|
37
|
+
await stopper.stop(signal);
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// This file is adapted from the stoppable npm package:
|
|
2
|
+
// https://github.com/hunterloftis/stoppable
|
|
3
|
+
//
|
|
4
|
+
// We've ported it to TypeScript and simplified the API and fixed some bugs.
|
|
5
|
+
// Here's the license of the original code:
|
|
6
|
+
//
|
|
7
|
+
// The MIT License (MIT)
|
|
8
|
+
//
|
|
9
|
+
// Copyright (c) 2017 Hunter Loftis <hunter@hunterloftis.com>
|
|
10
|
+
//
|
|
11
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
// in the Software without restriction, including without limitation the rights
|
|
14
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
// furnished to do so, subject to the following conditions:
|
|
17
|
+
//
|
|
18
|
+
// The above copyright notice and this permission notice shall be included in
|
|
19
|
+
// all copies or substantial portions of the Software.
|
|
20
|
+
//
|
|
21
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
27
|
+
// THE SOFTWARE.
|
|
28
|
+
|
|
29
|
+
import type http from 'http';
|
|
30
|
+
import https from 'https';
|
|
31
|
+
import type { Socket } from 'net';
|
|
32
|
+
|
|
33
|
+
export class Stopper {
|
|
34
|
+
private requestCountPerSocket = new Map<Socket, number>();
|
|
35
|
+
private stopped = false;
|
|
36
|
+
|
|
37
|
+
constructor(private server: http.Server | https.Server) {
|
|
38
|
+
// Keep a number in requestCountPerSocket for each current connection.
|
|
39
|
+
server.on(
|
|
40
|
+
server instanceof https.Server ? 'secureConnection' : 'connection',
|
|
41
|
+
(socket: Socket) => {
|
|
42
|
+
this.requestCountPerSocket.set(socket, 0);
|
|
43
|
+
socket.once('close', () => this.requestCountPerSocket.delete(socket));
|
|
44
|
+
},
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
// Track how many HTTP requests are active on the socket.
|
|
48
|
+
server.on(
|
|
49
|
+
'request',
|
|
50
|
+
(req: http.IncomingMessage, res: http.ServerResponse) => {
|
|
51
|
+
this.requestCountPerSocket.set(
|
|
52
|
+
req.socket,
|
|
53
|
+
(this.requestCountPerSocket.get(req.socket) ?? 0) + 1,
|
|
54
|
+
);
|
|
55
|
+
res.once('finish', () => {
|
|
56
|
+
const pending = (this.requestCountPerSocket.get(req.socket) ?? 0) - 1;
|
|
57
|
+
this.requestCountPerSocket.set(req.socket, pending);
|
|
58
|
+
// If we're in the process of stopping and it's gone idle, close the
|
|
59
|
+
// socket.
|
|
60
|
+
if (this.stopped && pending === 0) {
|
|
61
|
+
req.socket.end();
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
},
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async stop(hardDestroyAbortSignal?: AbortSignal): Promise<boolean> {
|
|
69
|
+
let gracefully = true;
|
|
70
|
+
|
|
71
|
+
// In the off-chance that we are calling `stop` directly from within the
|
|
72
|
+
// HTTP server's request handler (and so we haven't gotten to the
|
|
73
|
+
// `connection` event yet), wait a moment so that `connection` can be called
|
|
74
|
+
// and this request can actually count.
|
|
75
|
+
await new Promise<void>((resolve) => setImmediate(resolve));
|
|
76
|
+
this.stopped = true;
|
|
77
|
+
|
|
78
|
+
// When told to, hard-destroy everything.
|
|
79
|
+
const onAbort = () => {
|
|
80
|
+
gracefully = false;
|
|
81
|
+
this.requestCountPerSocket.forEach((_, socket) => socket.end());
|
|
82
|
+
// (FYI, this setImmediate was cargo-culted from the original
|
|
83
|
+
// implementation, but we don't understand why it's here.)
|
|
84
|
+
setImmediate(() => {
|
|
85
|
+
this.requestCountPerSocket.forEach((_, socket) => socket.destroy());
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
hardDestroyAbortSignal?.addEventListener('abort', onAbort);
|
|
89
|
+
|
|
90
|
+
// Close the server and create a Promise that resolves when all connections
|
|
91
|
+
// are closed. Note that we ignore any error from `close` here.
|
|
92
|
+
const closePromise = new Promise<void>((resolve) =>
|
|
93
|
+
this.server.close(() => {
|
|
94
|
+
hardDestroyAbortSignal?.removeEventListener('abort', onAbort);
|
|
95
|
+
resolve();
|
|
96
|
+
}),
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
// Immediately close any idle sockets.
|
|
100
|
+
this.requestCountPerSocket.forEach((requests, socket) => {
|
|
101
|
+
if (requests === 0) socket.end();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Wait for all connections to be closed.
|
|
105
|
+
await closePromise;
|
|
106
|
+
|
|
107
|
+
return gracefully;
|
|
108
|
+
}
|
|
109
|
+
}
|