@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,356 @@
|
|
|
1
|
+
// This class is a helper for ApolloServerPluginUsageReporting and
|
|
2
|
+
// ApolloServerPluginInlineTrace.
|
|
3
|
+
import {
|
|
4
|
+
GraphQLError,
|
|
5
|
+
type GraphQLResolveInfo,
|
|
6
|
+
type ResponsePath,
|
|
7
|
+
} from 'graphql';
|
|
8
|
+
import { Trace, google } from '@apollo/usage-reporting-protobuf';
|
|
9
|
+
import type { SendErrorsOptions } from './usageReporting';
|
|
10
|
+
import { UnreachableCaseError } from '../utils/UnreachableCaseError.js';
|
|
11
|
+
|
|
12
|
+
function internalError(message: string) {
|
|
13
|
+
return new Error(`[internal apollo-server error] ${message}`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class TraceTreeBuilder {
|
|
17
|
+
private rootNode = new Trace.Node();
|
|
18
|
+
public trace = new Trace({
|
|
19
|
+
root: this.rootNode,
|
|
20
|
+
// By default, each trace counts as one operation for the sake of field
|
|
21
|
+
// execution counts. If we end up calling the fieldLevelInstrumentation
|
|
22
|
+
// callback (once we've successfully resolved the operation) then we
|
|
23
|
+
// may set this to a higher number; but we'll start it at 1 so that traces
|
|
24
|
+
// that don't successfully resolve the operation (eg parse failures) or
|
|
25
|
+
// where we don't call the callback because a plugin set captureTraces to
|
|
26
|
+
// true have a reasonable default.
|
|
27
|
+
fieldExecutionWeight: 1,
|
|
28
|
+
});
|
|
29
|
+
public startHrTime?: [number, number];
|
|
30
|
+
private stopped = false;
|
|
31
|
+
private nodes = new Map<string, Trace.Node>([
|
|
32
|
+
[responsePathAsString(), this.rootNode],
|
|
33
|
+
]);
|
|
34
|
+
private readonly transformError:
|
|
35
|
+
| ((err: GraphQLError) => GraphQLError | null)
|
|
36
|
+
| null;
|
|
37
|
+
|
|
38
|
+
public constructor(options: {
|
|
39
|
+
maskedBy: string;
|
|
40
|
+
sendErrors?: SendErrorsOptions;
|
|
41
|
+
}) {
|
|
42
|
+
const { sendErrors, maskedBy } = options;
|
|
43
|
+
if (!sendErrors || 'masked' in sendErrors) {
|
|
44
|
+
this.transformError = () =>
|
|
45
|
+
new GraphQLError('<masked>', {
|
|
46
|
+
extensions: { maskedBy },
|
|
47
|
+
});
|
|
48
|
+
} else if ('transform' in sendErrors) {
|
|
49
|
+
this.transformError = sendErrors.transform;
|
|
50
|
+
} else if ('unmodified' in sendErrors) {
|
|
51
|
+
this.transformError = null;
|
|
52
|
+
} else {
|
|
53
|
+
throw new UnreachableCaseError(sendErrors);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public startTiming() {
|
|
58
|
+
if (this.startHrTime) {
|
|
59
|
+
throw internalError('startTiming called twice!');
|
|
60
|
+
}
|
|
61
|
+
if (this.stopped) {
|
|
62
|
+
throw internalError('startTiming called after stopTiming!');
|
|
63
|
+
}
|
|
64
|
+
this.trace.startTime = dateToProtoTimestamp(new Date());
|
|
65
|
+
this.startHrTime = process.hrtime();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public stopTiming() {
|
|
69
|
+
if (!this.startHrTime) {
|
|
70
|
+
throw internalError('stopTiming called before startTiming!');
|
|
71
|
+
}
|
|
72
|
+
if (this.stopped) {
|
|
73
|
+
throw internalError('stopTiming called twice!');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
this.trace.durationNs = durationHrTimeToNanos(
|
|
77
|
+
process.hrtime(this.startHrTime),
|
|
78
|
+
);
|
|
79
|
+
this.trace.endTime = dateToProtoTimestamp(new Date());
|
|
80
|
+
this.stopped = true;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public willResolveField(info: GraphQLResolveInfo): () => void {
|
|
84
|
+
if (!this.startHrTime) {
|
|
85
|
+
throw internalError('willResolveField called before startTiming!');
|
|
86
|
+
}
|
|
87
|
+
if (this.stopped) {
|
|
88
|
+
// We've been stopped, which means execution is done... and yet we're
|
|
89
|
+
// still resolving more fields? How can that be? Shouldn't we throw an
|
|
90
|
+
// error or something?
|
|
91
|
+
//
|
|
92
|
+
// Well... we used to do exactly that. But this "shouldn't happen" error
|
|
93
|
+
// showed up in practice! Turns out that graphql-js can actually continue
|
|
94
|
+
// to execute more fields indefinitely long after `execute()` resolves!
|
|
95
|
+
// That's because parallelism on a selection set is implemented using
|
|
96
|
+
// `Promise.all`, and as soon as one of its arguments (ie, one field)
|
|
97
|
+
// throws an error, the combined Promise resolves, but there's no
|
|
98
|
+
// "cancellation" of the Promises that are the other arguments to
|
|
99
|
+
// `Promise.all`. So the code contributing to those Promises keeps on
|
|
100
|
+
// chugging away indefinitely.
|
|
101
|
+
//
|
|
102
|
+
// Concrete example: let’s say you have
|
|
103
|
+
//
|
|
104
|
+
// { x y { ARBITRARY_SELECTION_SET } }
|
|
105
|
+
//
|
|
106
|
+
// where x has a non-null return type, and x and y both have resolvers
|
|
107
|
+
// that return Promises. And let’s say that x returns a Promise that
|
|
108
|
+
// rejects (or resolves to null). What this means is that we’re going to
|
|
109
|
+
// eventually end up with `data: null` (nothing under y will actually
|
|
110
|
+
// matter), but graphql-js execution will continue running whatever is
|
|
111
|
+
// under ARBITRARY_SELECTION_SET without any sort of short circuiting. In
|
|
112
|
+
// fact, the Promise returned from execute itself can happily resolve
|
|
113
|
+
// while execution is still chugging away on an arbitrary amount of fields
|
|
114
|
+
// under that ARBITRARY_SELECTION_SET. There’s no way to detect from the
|
|
115
|
+
// outside "all the execution related to this operation is done", nor to
|
|
116
|
+
// "short-circuit" execution so that it stops going.
|
|
117
|
+
//
|
|
118
|
+
// So, um. We will record any field whose execution we manage to observe
|
|
119
|
+
// before we "stop" the TraceTreeBuilder (whether it is one that actually
|
|
120
|
+
// ends up in the response or whether it gets thrown away due to null
|
|
121
|
+
// bubbling), but if we get any more fields afterwards, we just ignore
|
|
122
|
+
// them rather than throwing a confusing error.
|
|
123
|
+
//
|
|
124
|
+
// (That said, the error we used to throw here generally was hidden
|
|
125
|
+
// anyway, for the same reason: it comes from a branch of execution that
|
|
126
|
+
// ends up not being included in the response. But
|
|
127
|
+
// https://github.com/graphql/graphql-js/pull/3529 means that this
|
|
128
|
+
// sometimes crashed execution anyway. Our error never caught any actual
|
|
129
|
+
// problematic cases, so keeping it around doesn't really help.)
|
|
130
|
+
return () => {};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const path = info.path;
|
|
134
|
+
const node = this.newNode(path);
|
|
135
|
+
node.type = info.returnType.toString();
|
|
136
|
+
node.parentType = info.parentType.toString();
|
|
137
|
+
node.startTime = durationHrTimeToNanos(process.hrtime(this.startHrTime));
|
|
138
|
+
if (typeof path.key === 'string' && path.key !== info.fieldName) {
|
|
139
|
+
// This field was aliased; send the original field name too (for FieldStats).
|
|
140
|
+
node.originalFieldName = info.fieldName;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return () => {
|
|
144
|
+
node.endTime = durationHrTimeToNanos(process.hrtime(this.startHrTime));
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
public didEncounterErrors(errors: readonly GraphQLError[]) {
|
|
149
|
+
errors.forEach((err) => {
|
|
150
|
+
// This is an error from a federated service. We will already be reporting
|
|
151
|
+
// it in the nested Trace in the query plan.
|
|
152
|
+
//
|
|
153
|
+
// XXX This probably shouldn't skip query or validation errors, which are
|
|
154
|
+
// not in nested Traces because format() isn't called in this case! Or
|
|
155
|
+
// maybe format() should be called in that case?
|
|
156
|
+
if (err.extensions?.serviceName) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// In terms of reporting, errors can be re-written by the user by
|
|
161
|
+
// utilizing the `transformError` parameter. This allows changing
|
|
162
|
+
// the message or stack to remove potentially sensitive information.
|
|
163
|
+
// Returning `null` will result in the error not being reported at all.
|
|
164
|
+
const errorForReporting = this.transformAndNormalizeError(err);
|
|
165
|
+
|
|
166
|
+
if (errorForReporting === null) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
this.addProtobufError(
|
|
171
|
+
errorForReporting.path,
|
|
172
|
+
errorToProtobufError(errorForReporting),
|
|
173
|
+
);
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private addProtobufError(
|
|
178
|
+
path: ReadonlyArray<string | number> | undefined,
|
|
179
|
+
error: Trace.Error,
|
|
180
|
+
) {
|
|
181
|
+
if (!this.startHrTime) {
|
|
182
|
+
throw internalError('addProtobufError called before startTiming!');
|
|
183
|
+
}
|
|
184
|
+
if (this.stopped) {
|
|
185
|
+
throw internalError('addProtobufError called after stopTiming!');
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// By default, put errors on the root node.
|
|
189
|
+
let node = this.rootNode;
|
|
190
|
+
// If a non-GraphQLError Error sneaks in here somehow with a non-array
|
|
191
|
+
// path, don't crash.
|
|
192
|
+
if (Array.isArray(path)) {
|
|
193
|
+
const specificNode = this.nodes.get(path.join('.'));
|
|
194
|
+
if (specificNode) {
|
|
195
|
+
node = specificNode;
|
|
196
|
+
} else {
|
|
197
|
+
const responsePath = responsePathFromArray(path, this.rootNode);
|
|
198
|
+
if (!responsePath) {
|
|
199
|
+
throw internalError('addProtobufError called with invalid path!');
|
|
200
|
+
}
|
|
201
|
+
node = this.newNode(responsePath);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
node.error.push(error);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
private newNode(path: ResponsePath): Trace.Node {
|
|
209
|
+
const node = new Trace.Node();
|
|
210
|
+
const id = path.key;
|
|
211
|
+
if (typeof id === 'number') {
|
|
212
|
+
node.index = id;
|
|
213
|
+
} else {
|
|
214
|
+
node.responseName = id;
|
|
215
|
+
}
|
|
216
|
+
this.nodes.set(responsePathAsString(path), node);
|
|
217
|
+
const parentNode = this.ensureParentNode(path);
|
|
218
|
+
parentNode.child.push(node);
|
|
219
|
+
return node;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
private ensureParentNode(path: ResponsePath): Trace.Node {
|
|
223
|
+
const parentPath = responsePathAsString(path.prev);
|
|
224
|
+
const parentNode = this.nodes.get(parentPath);
|
|
225
|
+
if (parentNode) {
|
|
226
|
+
return parentNode;
|
|
227
|
+
}
|
|
228
|
+
// Because we set up the root path when creating this.nodes, we now know
|
|
229
|
+
// that path.prev isn't undefined.
|
|
230
|
+
return this.newNode(path.prev!);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
private transformAndNormalizeError(err: GraphQLError): GraphQLError | null {
|
|
234
|
+
if (this.transformError) {
|
|
235
|
+
// Before passing the error to the user-provided `transformError` function,
|
|
236
|
+
// we'll make a shadow copy of the error so the user is free to change
|
|
237
|
+
// the object as they see fit.
|
|
238
|
+
|
|
239
|
+
// At this stage, this error is only for the purposes of reporting, but
|
|
240
|
+
// this is even more important since this is still a reference to the
|
|
241
|
+
// original error object and changing it would also change the error which
|
|
242
|
+
// is returned in the response to the client.
|
|
243
|
+
|
|
244
|
+
// For the clone, we'll create a new object which utilizes the exact same
|
|
245
|
+
// prototype of the error being reported.
|
|
246
|
+
const clonedError = Object.assign(
|
|
247
|
+
Object.create(Object.getPrototypeOf(err)),
|
|
248
|
+
err,
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
const rewrittenError = this.transformError(clonedError);
|
|
252
|
+
|
|
253
|
+
// Returning an explicit `null` means the user is requesting that the error
|
|
254
|
+
// not be reported to Apollo.
|
|
255
|
+
if (rewrittenError === null) {
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// We don't want users to be inadvertently not reporting errors, so if
|
|
260
|
+
// they haven't returned an explicit `GraphQLError` (or `null`, handled
|
|
261
|
+
// above), then we'll report the error as usual.
|
|
262
|
+
if (!(rewrittenError instanceof GraphQLError)) {
|
|
263
|
+
return err;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// We only allow transformError to change the message and extensions of the
|
|
267
|
+
// error; we keep everything else the same. That way people don't have to
|
|
268
|
+
// do extra work to keep the error on the same trace node. We also keep
|
|
269
|
+
// extensions the same if it isn't explicitly changed (to, eg, {}). (Note
|
|
270
|
+
// that many of the fields of GraphQLError are not enumerable and won't
|
|
271
|
+
// show up in the trace (even in the json field) anyway.)
|
|
272
|
+
return new GraphQLError(rewrittenError.message, {
|
|
273
|
+
nodes: err.nodes,
|
|
274
|
+
source: err.source,
|
|
275
|
+
positions: err.positions,
|
|
276
|
+
path: err.path,
|
|
277
|
+
originalError: err.originalError,
|
|
278
|
+
extensions: rewrittenError.extensions || err.extensions,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
return err;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Converts an hrtime array (as returned from process.hrtime) to nanoseconds.
|
|
286
|
+
//
|
|
287
|
+
// ONLY CALL THIS ON VALUES REPRESENTING DELTAS, NOT ON THE RAW RETURN VALUE
|
|
288
|
+
// FROM process.hrtime() WITH NO ARGUMENTS.
|
|
289
|
+
//
|
|
290
|
+
// The entire point of the hrtime data structure is that the JavaScript Number
|
|
291
|
+
// type can't represent all int64 values without loss of precision:
|
|
292
|
+
// Number.MAX_SAFE_INTEGER nanoseconds is about 104 days. Calling this function
|
|
293
|
+
// on a duration that represents a value less than 104 days is fine. Calling
|
|
294
|
+
// this function on an absolute time (which is generally roughly time since
|
|
295
|
+
// system boot) is not a good idea.
|
|
296
|
+
//
|
|
297
|
+
// XXX We should probably use google.protobuf.Duration on the wire instead of
|
|
298
|
+
// ever trying to store durations in a single number.
|
|
299
|
+
function durationHrTimeToNanos(hrtime: [number, number]) {
|
|
300
|
+
return hrtime[0] * 1e9 + hrtime[1];
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Convert from the linked-list ResponsePath format to a dot-joined
|
|
304
|
+
// string. Includes the full path (field names and array indices).
|
|
305
|
+
function responsePathAsString(p?: ResponsePath): string {
|
|
306
|
+
if (p === undefined) {
|
|
307
|
+
return '';
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// A previous implementation used `responsePathAsArray` from `graphql-js/execution`,
|
|
311
|
+
// however, that employed an approach that created new arrays unnecessarily.
|
|
312
|
+
let res = String(p.key);
|
|
313
|
+
|
|
314
|
+
while ((p = p.prev) !== undefined) {
|
|
315
|
+
res = `${p.key}.${res}`;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return res;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function responsePathFromArray(
|
|
322
|
+
path: ReadonlyArray<string | number>,
|
|
323
|
+
node: Trace.Node,
|
|
324
|
+
): ResponsePath | undefined {
|
|
325
|
+
let responsePath: ResponsePath | undefined;
|
|
326
|
+
let nodePtr: Trace.INode | undefined = node;
|
|
327
|
+
for (const key of path) {
|
|
328
|
+
nodePtr = nodePtr?.child?.find((child) => child.responseName === key);
|
|
329
|
+
responsePath = {
|
|
330
|
+
key,
|
|
331
|
+
prev: responsePath,
|
|
332
|
+
typename: nodePtr?.type ?? undefined,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
return responsePath;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function errorToProtobufError(error: GraphQLError): Trace.Error {
|
|
339
|
+
return new Trace.Error({
|
|
340
|
+
message: error.message,
|
|
341
|
+
location: (error.locations || []).map(
|
|
342
|
+
({ line, column }) => new Trace.Location({ line, column }),
|
|
343
|
+
),
|
|
344
|
+
json: JSON.stringify(error),
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Converts a JS Date into a Timestamp.
|
|
349
|
+
export function dateToProtoTimestamp(date: Date): google.protobuf.Timestamp {
|
|
350
|
+
const totalMillis = +date;
|
|
351
|
+
const millis = totalMillis % 1000;
|
|
352
|
+
return new google.protobuf.Timestamp({
|
|
353
|
+
seconds: (totalMillis - millis) / 1000,
|
|
354
|
+
nanos: millis * 1e6,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { LRUCache } from 'lru-cache';
|
|
2
|
+
import type { Trace } from '@apollo/usage-reporting-protobuf';
|
|
3
|
+
import { iterateOverTrace } from './iterateOverTrace.js';
|
|
4
|
+
import { DurationHistogram } from './durationHistogram.js';
|
|
5
|
+
|
|
6
|
+
export function defaultSendOperationsAsTrace() {
|
|
7
|
+
// We keep an LRU cache mapping from a trace key (which consists of the
|
|
8
|
+
// operation as defined by statsReportKey, the rough duration of the
|
|
9
|
+
// operation, what minute the operation ended at, etc) to `true` if we've seen
|
|
10
|
+
// it recently. We actually split this into one cache per minute so we can
|
|
11
|
+
// throw away a full minute's worth of cache at once; we keep only the last
|
|
12
|
+
// three minutes.
|
|
13
|
+
// Note that if a trace is over a certain size, we will always send it as
|
|
14
|
+
// stats. We check this within the addTrace function of the OurReport class so
|
|
15
|
+
// that we don't have to encode these large traces twice.
|
|
16
|
+
const cache = new LRUCache<string, true>({
|
|
17
|
+
// 3MiB limit, very much approximately since we can't be sure how V8 might
|
|
18
|
+
// be storing these strings internally. Though this should be enough to
|
|
19
|
+
// store a fair amount of trace keys.
|
|
20
|
+
|
|
21
|
+
// A future version of this might expose some
|
|
22
|
+
// configuration option to grow the cache, but ideally, we could do that
|
|
23
|
+
// dynamically based on the resources available to the server, and not add
|
|
24
|
+
// more configuration surface area. Hopefully the warning message will allow
|
|
25
|
+
// us to evaluate the need with more validated input from those that receive
|
|
26
|
+
// it.
|
|
27
|
+
maxSize: Math.pow(2, 20),
|
|
28
|
+
sizeCalculation: (_val, key) => {
|
|
29
|
+
return (key && Buffer.byteLength(key)) || 0;
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
return (trace: Trace, statsReportKey: string): boolean => {
|
|
34
|
+
const endTimeSeconds = trace.endTime?.seconds;
|
|
35
|
+
if (endTimeSeconds == null) {
|
|
36
|
+
throw Error('programming error: endTime not set on trace');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const hasErrors = traceHasErrors(trace);
|
|
40
|
+
const cacheKey = JSON.stringify([
|
|
41
|
+
statsReportKey,
|
|
42
|
+
DurationHistogram.durationToBucket(trace.durationNs),
|
|
43
|
+
// What minute it started at
|
|
44
|
+
Math.floor(endTimeSeconds / 60),
|
|
45
|
+
// If the trace has an error, send one errored trace per 5 second interval
|
|
46
|
+
// instead of the normal minutely bucket a non-errored trace takes.
|
|
47
|
+
hasErrors ? Math.floor(endTimeSeconds / 5) : '',
|
|
48
|
+
]);
|
|
49
|
+
|
|
50
|
+
// If we've already seen something roughly like this, don't send as a trace.
|
|
51
|
+
if (cache.get(cacheKey)) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
cache.set(cacheKey, true);
|
|
56
|
+
return true;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Returns true if any node on the trace has errors. (If this ends up being a
|
|
61
|
+
// hot spot, we can precalculate it in TraceTreeBuilder.)
|
|
62
|
+
function traceHasErrors(trace: Trace): boolean {
|
|
63
|
+
let hasErrors = false;
|
|
64
|
+
|
|
65
|
+
function traceNodeStats(node: Trace.INode): boolean {
|
|
66
|
+
if ((node.error?.length ?? 0) > 0) {
|
|
67
|
+
hasErrors = true;
|
|
68
|
+
}
|
|
69
|
+
return hasErrors;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
iterateOverTrace(trace, traceNodeStats, false);
|
|
73
|
+
return hasErrors;
|
|
74
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
export interface DurationHistogramOptions {
|
|
2
|
+
initSize?: number;
|
|
3
|
+
buckets?: number[];
|
|
4
|
+
}
|
|
5
|
+
export class DurationHistogram {
|
|
6
|
+
// Note that it's legal for the values in "buckets" to be non-integers; they
|
|
7
|
+
// will be floored by toArray (which is called by the protobuf encoder).
|
|
8
|
+
// (We take advantage of this for field latencies specifically, because
|
|
9
|
+
// the ability to return a non-1 weight from fieldLevelInstrumentation
|
|
10
|
+
// means we want to build up our histograms as floating-point rather than
|
|
11
|
+
// rounding after every operation.)
|
|
12
|
+
private readonly buckets: number[];
|
|
13
|
+
static readonly BUCKET_COUNT = 384;
|
|
14
|
+
static readonly EXPONENT_LOG = Math.log(1.1);
|
|
15
|
+
|
|
16
|
+
toArray(): number[] {
|
|
17
|
+
let bufferedZeroes = 0;
|
|
18
|
+
const outputArray: number[] = [];
|
|
19
|
+
|
|
20
|
+
for (const value of this.buckets) {
|
|
21
|
+
if (value === 0) {
|
|
22
|
+
bufferedZeroes++;
|
|
23
|
+
} else {
|
|
24
|
+
if (bufferedZeroes === 1) {
|
|
25
|
+
outputArray.push(0);
|
|
26
|
+
} else if (bufferedZeroes !== 0) {
|
|
27
|
+
outputArray.push(-bufferedZeroes);
|
|
28
|
+
}
|
|
29
|
+
outputArray.push(Math.floor(value));
|
|
30
|
+
bufferedZeroes = 0;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return outputArray;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static durationToBucket(durationNs: number): number {
|
|
37
|
+
const log = Math.log(durationNs / 1000.0);
|
|
38
|
+
const unboundedBucket = Math.ceil(log / DurationHistogram.EXPONENT_LOG);
|
|
39
|
+
|
|
40
|
+
// Compare <= 0 to catch -0 and -infinity
|
|
41
|
+
return unboundedBucket <= 0 || Number.isNaN(unboundedBucket)
|
|
42
|
+
? 0
|
|
43
|
+
: unboundedBucket >= DurationHistogram.BUCKET_COUNT
|
|
44
|
+
? DurationHistogram.BUCKET_COUNT - 1
|
|
45
|
+
: unboundedBucket;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
incrementDuration(durationNs: number, value = 1): DurationHistogram {
|
|
49
|
+
this.incrementBucket(DurationHistogram.durationToBucket(durationNs), value);
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
incrementBucket(bucket: number, value = 1) {
|
|
54
|
+
if (bucket >= DurationHistogram.BUCKET_COUNT) {
|
|
55
|
+
// Since we don't have fixed size arrays I'd rather throw the error manually
|
|
56
|
+
throw Error('Bucket is out of bounds of the buckets array');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Extend the array if we haven't gotten it long enough to handle the new bucket
|
|
60
|
+
if (bucket >= this.buckets.length) {
|
|
61
|
+
const oldLength = this.buckets.length;
|
|
62
|
+
this.buckets.length = bucket + 1;
|
|
63
|
+
this.buckets.fill(0, oldLength);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
this.buckets[bucket] += value;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
combine(otherHistogram: DurationHistogram) {
|
|
70
|
+
for (let i = 0; i < otherHistogram.buckets.length; i++) {
|
|
71
|
+
this.incrementBucket(i, otherHistogram.buckets[i]);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
constructor(options?: DurationHistogramOptions) {
|
|
76
|
+
const initSize = options?.initSize || 74;
|
|
77
|
+
const buckets = options?.buckets;
|
|
78
|
+
|
|
79
|
+
const arrayInitSize = Math.max(buckets?.length || 0, initSize);
|
|
80
|
+
|
|
81
|
+
this.buckets = Array<number>(arrayInitSize).fill(0);
|
|
82
|
+
|
|
83
|
+
if (buckets) {
|
|
84
|
+
buckets.forEach((val, index) => (this.buckets[index] = val));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import type { Trace } from '@apollo/usage-reporting-protobuf';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Iterates over the entire trace, calling `f` on each Trace.Node found. It
|
|
5
|
+
* looks under the "root" node as well as any inside the query plan. If any `f`
|
|
6
|
+
* returns true, it stops walking the tree.
|
|
7
|
+
*
|
|
8
|
+
* Each call to `f` will receive an object that implements ResponseNamePath. If
|
|
9
|
+
* `includePath` is true, `f` can call `toArray()` on it to convert the
|
|
10
|
+
* linked-list representation to an array of the response name (field name)
|
|
11
|
+
* nodes that you navigate to get to the node (including a "service:subgraph"
|
|
12
|
+
* top-level node if this is a federated trace). Note that we don't add anything
|
|
13
|
+
* to the path for index (list element) nodes. This is because the only use case
|
|
14
|
+
* we have (error path statistics) does not care about list indexes (it's not
|
|
15
|
+
* that interesting to know that sometimes an error was at foo.3.bar and
|
|
16
|
+
* sometimes foo.5.bar, vs just generally foo.bar).
|
|
17
|
+
*
|
|
18
|
+
* If `includePath` is false, we don't bother to build up the linked lists, and
|
|
19
|
+
* calling `toArray()` will throw.
|
|
20
|
+
*/
|
|
21
|
+
export function iterateOverTrace(
|
|
22
|
+
trace: Trace,
|
|
23
|
+
f: (node: Trace.INode, path: ResponseNamePath) => boolean,
|
|
24
|
+
includePath: boolean,
|
|
25
|
+
) {
|
|
26
|
+
const rootPath = includePath
|
|
27
|
+
? new RootCollectingPathsResponseNamePath()
|
|
28
|
+
: notCollectingPathsResponseNamePath;
|
|
29
|
+
if (trace.root) {
|
|
30
|
+
if (iterateOverTraceNode(trace.root, rootPath, f)) return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (trace.queryPlan) {
|
|
34
|
+
if (iterateOverQueryPlan(trace.queryPlan, rootPath, f)) return;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Helper for iterateOverTrace; returns true to stop the overall walk.
|
|
39
|
+
function iterateOverQueryPlan(
|
|
40
|
+
node: Trace.IQueryPlanNode,
|
|
41
|
+
rootPath: ResponseNamePath,
|
|
42
|
+
f: (node: Trace.INode, path: ResponseNamePath) => boolean,
|
|
43
|
+
): boolean {
|
|
44
|
+
if (!node) return false;
|
|
45
|
+
|
|
46
|
+
if (node.fetch?.trace?.root && node.fetch.serviceName) {
|
|
47
|
+
return iterateOverTraceNode(
|
|
48
|
+
node.fetch.trace.root,
|
|
49
|
+
rootPath.child(`service:${node.fetch.serviceName}`),
|
|
50
|
+
f,
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
if (node.flatten?.node) {
|
|
54
|
+
return iterateOverQueryPlan(node.flatten.node, rootPath, f);
|
|
55
|
+
}
|
|
56
|
+
if (node.parallel?.nodes) {
|
|
57
|
+
// We want to stop as soon as some call returns true, which happens to be
|
|
58
|
+
// exactly what 'some' does.
|
|
59
|
+
return node.parallel.nodes.some((node) =>
|
|
60
|
+
iterateOverQueryPlan(node, rootPath, f),
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
if (node.sequence?.nodes) {
|
|
64
|
+
// We want to stop as soon as some call returns true, which happens to be
|
|
65
|
+
// exactly what 'some' does.
|
|
66
|
+
return node.sequence.nodes.some((node) =>
|
|
67
|
+
iterateOverQueryPlan(node, rootPath, f),
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Helper for iterateOverTrace; returns true to stop the overall walk.
|
|
75
|
+
function iterateOverTraceNode(
|
|
76
|
+
node: Trace.INode,
|
|
77
|
+
path: ResponseNamePath,
|
|
78
|
+
f: (node: Trace.INode, path: ResponseNamePath) => boolean,
|
|
79
|
+
): boolean {
|
|
80
|
+
// Invoke the function; if it returns true, don't descend and tell callers to
|
|
81
|
+
// stop walking.
|
|
82
|
+
if (f(node, path)) {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
// We want to stop as soon as some call returns true, which happens to be
|
|
88
|
+
// exactly what 'some' does.
|
|
89
|
+
node.child?.some((child) => {
|
|
90
|
+
const childPath = child.responseName
|
|
91
|
+
? path.child(child.responseName)
|
|
92
|
+
: path;
|
|
93
|
+
return iterateOverTraceNode(child, childPath, f);
|
|
94
|
+
}) ?? false
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface ResponseNamePath {
|
|
99
|
+
toArray(): string[];
|
|
100
|
+
child(responseName: string): ResponseNamePath;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const notCollectingPathsResponseNamePath: ResponseNamePath = {
|
|
104
|
+
toArray() {
|
|
105
|
+
throw Error('not collecting paths!');
|
|
106
|
+
},
|
|
107
|
+
child() {
|
|
108
|
+
return this;
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
type CollectingPathsResponseNamePath =
|
|
113
|
+
| RootCollectingPathsResponseNamePath
|
|
114
|
+
| ChildCollectingPathsResponseNamePath;
|
|
115
|
+
class RootCollectingPathsResponseNamePath implements ResponseNamePath {
|
|
116
|
+
toArray() {
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
child(responseName: string) {
|
|
120
|
+
return new ChildCollectingPathsResponseNamePath(responseName, this);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
class ChildCollectingPathsResponseNamePath implements ResponseNamePath {
|
|
124
|
+
constructor(
|
|
125
|
+
readonly responseName: string,
|
|
126
|
+
readonly prev: CollectingPathsResponseNamePath,
|
|
127
|
+
) {}
|
|
128
|
+
toArray() {
|
|
129
|
+
const out = [];
|
|
130
|
+
let curr: CollectingPathsResponseNamePath = this;
|
|
131
|
+
while (curr instanceof ChildCollectingPathsResponseNamePath) {
|
|
132
|
+
out.push(curr.responseName);
|
|
133
|
+
curr = curr.prev;
|
|
134
|
+
}
|
|
135
|
+
return out.reverse();
|
|
136
|
+
}
|
|
137
|
+
child(responseName: string) {
|
|
138
|
+
return new ChildCollectingPathsResponseNamePath(responseName, this);
|
|
139
|
+
}
|
|
140
|
+
}
|