apollo-server-core
Advanced tools
Comparing version 3.6.2 to 3.6.3
@@ -22,3 +22,3 @@ "use strict"; | ||
}, | ||
async requestDidStart({ request: { http } }) { | ||
async requestDidStart({ request: { http }, metrics }) { | ||
if (!enabled) { | ||
@@ -33,2 +33,6 @@ return; | ||
} | ||
if (metrics.captureTraces === false) { | ||
return; | ||
} | ||
metrics.captureTraces = true; | ||
treeBuilder.startTiming(); | ||
@@ -48,2 +52,5 @@ return { | ||
treeBuilder.stopTiming(); | ||
if (metrics.queryPlanTrace) { | ||
treeBuilder.trace.queryPlan = metrics.queryPlanTrace; | ||
} | ||
const encodedUint8Array = apollo_reporting_protobuf_1.Trace.encode(treeBuilder.trace).finish(); | ||
@@ -50,0 +57,0 @@ const encodedBuffer = Buffer.from(encodedUint8Array, encodedUint8Array.byteOffset, encodedUint8Array.byteLength); |
@@ -8,2 +8,3 @@ import type { ImplicitlyInstallablePlugin } from '../../../ApolloServer'; | ||
headers?: Record<string, string>; | ||
includeCookies?: boolean; | ||
__internal_apolloStudioEnv__?: 'staging' | 'prod'; | ||
@@ -10,0 +11,0 @@ } |
@@ -5,3 +5,3 @@ "use strict"; | ||
function ApolloServerPluginLandingPageLocalDefault(options = {}) { | ||
const { version, __internal_apolloStudioEnv__, footer, ...rest } = options; | ||
const { version, __internal_apolloStudioEnv__, footer, document, variables, headers, includeCookies, ...rest } = options; | ||
return ApolloServerPluginLandingPageDefault(version, encodeConfig({ | ||
@@ -11,2 +11,6 @@ isProd: false, | ||
footer, | ||
document, | ||
variables, | ||
headers, | ||
includeCookies, | ||
...rest, | ||
@@ -17,3 +21,3 @@ })); | ||
function ApolloServerPluginLandingPageProductionDefault(options = {}) { | ||
const { version, __internal_apolloStudioEnv__, footer, graphRef, ...rest } = options; | ||
const { version, __internal_apolloStudioEnv__, footer, document, variables, headers, includeCookies, graphRef, ...rest } = options; | ||
return ApolloServerPluginLandingPageDefault(version, encodeConfig({ | ||
@@ -23,2 +27,6 @@ isProd: true, | ||
footer, | ||
document, | ||
variables, | ||
headers, | ||
includeCookies, | ||
graphRef, | ||
@@ -25,0 +33,0 @@ ...rest, |
@@ -274,6 +274,12 @@ "use strict"; | ||
!graphqlUnknownOperationName) { | ||
const rawWeight = await fieldLevelInstrumentation(requestContext); | ||
treeBuilder.trace.fieldExecutionWeight = | ||
typeof rawWeight === 'number' ? rawWeight : rawWeight ? 1 : 0; | ||
metrics.captureTraces = !!treeBuilder.trace.fieldExecutionWeight; | ||
if (metrics.captureTraces === undefined) { | ||
const rawWeight = await fieldLevelInstrumentation(requestContext); | ||
treeBuilder.trace.fieldExecutionWeight = | ||
typeof rawWeight === 'number' ? rawWeight : rawWeight ? 1 : 0; | ||
metrics.captureTraces = | ||
!!treeBuilder.trace.fieldExecutionWeight; | ||
} | ||
else if (metrics.captureTraces) { | ||
treeBuilder.trace.fieldExecutionWeight = 1; | ||
} | ||
} | ||
@@ -280,0 +286,0 @@ }, |
@@ -19,2 +19,10 @@ "use strict"; | ||
} | ||
function isBadUserInputGraphQLError(error) { | ||
var _a; | ||
return (((_a = error.nodes) === null || _a === void 0 ? void 0 : _a.length) === 1 && | ||
error.nodes[0].kind === graphql_1.Kind.VARIABLE_DEFINITION && | ||
(error.message.startsWith(`Variable "$${error.nodes[0].variable.name.value}" got invalid value `) || | ||
error.message.startsWith(`Variable "$${error.nodes[0].variable.name.value}" of required type `) || | ||
error.message.startsWith(`Variable "$${error.nodes[0].variable.name.value}" of non-null type `))); | ||
} | ||
async function processGraphQLRequest(config, requestContext) { | ||
@@ -143,12 +151,3 @@ var _a, _b, _c; | ||
const resultErrors = (_c = result.errors) === null || _c === void 0 ? void 0 : _c.map((e) => { | ||
var _a; | ||
if (((_a = e.nodes) === null || _a === void 0 ? void 0 : _a.length) === 1 && | ||
e.nodes[0].kind === graphql_1.Kind.VARIABLE_DEFINITION && | ||
(e.message.startsWith(`Variable "$${e.nodes[0].variable.name.value}" got invalid value `) || | ||
(e.nodes[0].type.kind === graphql_1.Kind.NON_NULL_TYPE && | ||
e.nodes[0].type.type.kind === graphql_1.Kind.NAMED_TYPE && | ||
(e.message.startsWith(`Variable "$${e.nodes[0].variable.name.value}" of required ` + | ||
`type "${e.nodes[0].type.type.name.value}!" was not provided.`) || | ||
e.message.startsWith(`Variable "$${e.nodes[0].variable.name.value}" of non-null ` + | ||
`type "${e.nodes[0].type.type.name.value}!" must not be null.`))))) { | ||
if (isBadUserInputGraphQLError(e)) { | ||
return (0, apollo_server_errors_1.fromGraphQLError)(e, { | ||
@@ -155,0 +154,0 @@ errorClass: apollo_server_errors_1.UserInputError, |
{ | ||
"name": "apollo-server-core", | ||
"version": "3.6.2", | ||
"version": "3.6.3", | ||
"description": "Core engine for Apollo GraphQL server", | ||
@@ -52,3 +52,3 @@ "main": "dist/index.js", | ||
}, | ||
"gitHead": "022184a4d01d4452ebbcfeeef6e8ee1aae7a5db7" | ||
"gitHead": "289acad0e3777bd0010506763c3fd6e4c0289813" | ||
} |
@@ -56,3 +56,3 @@ import { Trace } from 'apollo-reporting-protobuf'; | ||
}, | ||
async requestDidStart({ request: { http } }) { | ||
async requestDidStart({ request: { http }, metrics }) { | ||
if (!enabled) { | ||
@@ -71,2 +71,13 @@ return; | ||
// If some other (user-written?) plugin already decided that we are not | ||
// capturing traces, then we should not capture traces. | ||
if (metrics.captureTraces === false) { | ||
return; | ||
} | ||
// Note that this will override any `fieldLevelInstrumentation` parameter | ||
// to the usage reporting plugin for requests with the | ||
// `apollo-federation-include-trace` header set. | ||
metrics.captureTraces = true; | ||
treeBuilder.startTiming(); | ||
@@ -92,2 +103,10 @@ | ||
// If we're in a gateway, include the query plan (and subgraph traces) | ||
// in the inline trace. This is designed more for manually querying | ||
// your graph while running locally to see what the query planner is | ||
// doing rather than for running in production. | ||
if (metrics.queryPlanTrace) { | ||
treeBuilder.trace.queryPlan = metrics.queryPlanTrace; | ||
} | ||
const encodedUint8Array = Trace.encode(treeBuilder.trace).finish(); | ||
@@ -94,0 +113,0 @@ const encodedBuffer = Buffer.from( |
@@ -18,8 +18,21 @@ import type { ImplicitlyInstallablePlugin } from '../../../ApolloServer'; | ||
/** | ||
* Folks can configure their landing page to link to Studio Explorer with a | ||
* document, variables and headers loaded in the UI. | ||
* Users can configure their landing page to link to Studio Explorer with a | ||
* document loaded in the UI. | ||
*/ | ||
document?: string; | ||
/** | ||
* Users can configure their landing page to link to Studio Explorer with | ||
* variables loaded in the UI. | ||
*/ | ||
variables?: Record<string, string>; | ||
/** | ||
* Users can configure their landing page to link to Studio Explorer with | ||
* headers loaded in the UI. | ||
*/ | ||
headers?: Record<string, string>; | ||
/** | ||
* Users can configure their landing page to link to Studio Explorer with the | ||
* setting to include/exclude cookies loaded in the UI. | ||
*/ | ||
includeCookies?: boolean; | ||
// For Apollo use only. | ||
@@ -51,2 +64,3 @@ __internal_apolloStudioEnv__?: 'staging' | 'prod'; | ||
headers?: Record<string, string>; | ||
includeCookies?: boolean; | ||
footer?: boolean; | ||
@@ -61,3 +75,12 @@ } | ||
// quite updated the plugin yet. | ||
const { version, __internal_apolloStudioEnv__, footer, ...rest } = options; | ||
const { | ||
version, | ||
__internal_apolloStudioEnv__, | ||
footer, | ||
document, | ||
variables, | ||
headers, | ||
includeCookies, | ||
...rest | ||
} = options; | ||
return ApolloServerPluginLandingPageDefault( | ||
@@ -69,2 +92,6 @@ version, | ||
footer, | ||
document, | ||
variables, | ||
headers, | ||
includeCookies, | ||
...rest, | ||
@@ -81,4 +108,13 @@ }), | ||
// quite updated the plugin yet. | ||
const { version, __internal_apolloStudioEnv__, footer, graphRef, ...rest } = | ||
options; | ||
const { | ||
version, | ||
__internal_apolloStudioEnv__, | ||
footer, | ||
document, | ||
variables, | ||
headers, | ||
includeCookies, | ||
graphRef, | ||
...rest | ||
} = options; | ||
return ApolloServerPluginLandingPageDefault( | ||
@@ -90,2 +126,6 @@ version, | ||
footer, | ||
document, | ||
variables, | ||
headers, | ||
includeCookies, | ||
graphRef, | ||
@@ -92,0 +132,0 @@ ...rest, |
@@ -518,21 +518,31 @@ import os from 'os'; | ||
) { | ||
// We're not completely ignoring the operation. But should we | ||
// calculate a detailed trace of every field while we do so (either | ||
// directly in this plugin, or in a subgraph by sending the | ||
// apollo-federation-include-trace header)? That will allow this | ||
// operation to contribute to the "field executions" column in the | ||
// Studio Fields page, to the timing hints in Explorer and | ||
// vscode-graphql, and to the traces visible under Operations. (Note | ||
// that `true` here does not imply that this operation will | ||
// necessarily be *sent* to the usage-reporting endpoint in the form | ||
// of a trace --- it still might be aggregated into stats first. But | ||
// capturing a trace will mean we can understand exactly what fields | ||
// were executed and what their performance was, at the tradeoff of | ||
// some overhead for tracking the trace (and transmitting it between | ||
// subgraph and gateway). | ||
const rawWeight = await fieldLevelInstrumentation(requestContext); | ||
treeBuilder.trace.fieldExecutionWeight = | ||
typeof rawWeight === 'number' ? rawWeight : rawWeight ? 1 : 0; | ||
if (metrics.captureTraces === undefined) { | ||
// We're not completely ignoring the operation. But should we | ||
// calculate a detailed trace of every field while we do so (either | ||
// directly in this plugin, or in a subgraph by sending the | ||
// apollo-federation-include-trace header)? That will allow this | ||
// operation to contribute to the "field executions" column in the | ||
// Studio Fields page, to the timing hints in Explorer and | ||
// vscode-graphql, and to the traces visible under Operations. (Note | ||
// that `true` here does not imply that this operation will | ||
// necessarily be *sent* to the usage-reporting endpoint in the form | ||
// of a trace --- it still might be aggregated into stats first. But | ||
// capturing a trace will mean we can understand exactly what fields | ||
// were executed and what their performance was, at the tradeoff of | ||
// some overhead for tracking the trace (and transmitting it between | ||
// subgraph and gateway). | ||
const rawWeight = await fieldLevelInstrumentation( | ||
requestContext, | ||
); | ||
treeBuilder.trace.fieldExecutionWeight = | ||
typeof rawWeight === 'number' ? rawWeight : rawWeight ? 1 : 0; | ||
metrics.captureTraces = !!treeBuilder.trace.fieldExecutionWeight; | ||
metrics.captureTraces = | ||
!!treeBuilder.trace.fieldExecutionWeight; | ||
} else if (metrics.captureTraces) { | ||
// Some other plugin already decided that we are capturing traces. | ||
// (For example, you may be running ApolloServerPluginInlineTrace | ||
// and this is a request with the header that requests tracing.) | ||
treeBuilder.trace.fieldExecutionWeight = 1; | ||
} | ||
} | ||
@@ -539,0 +549,0 @@ }, |
@@ -101,2 +101,18 @@ import { | ||
function isBadUserInputGraphQLError(error: GraphQLError): Boolean { | ||
return ( | ||
error.nodes?.length === 1 && | ||
error.nodes[0].kind === Kind.VARIABLE_DEFINITION && | ||
(error.message.startsWith( | ||
`Variable "$${error.nodes[0].variable.name.value}" got invalid value `, | ||
) || | ||
error.message.startsWith( | ||
`Variable "$${error.nodes[0].variable.name.value}" of required type `, | ||
) || | ||
error.message.startsWith( | ||
`Variable "$${error.nodes[0].variable.name.value}" of non-null type `, | ||
)) | ||
); | ||
} | ||
export async function processGraphQLRequest<TContext>( | ||
@@ -404,19 +420,3 @@ config: GraphQLRequestPipelineConfig<TContext>, | ||
const resultErrors = result.errors?.map((e) => { | ||
if ( | ||
e.nodes?.length === 1 && | ||
e.nodes[0].kind === Kind.VARIABLE_DEFINITION && | ||
(e.message.startsWith( | ||
`Variable "$${e.nodes[0].variable.name.value}" got invalid value `, | ||
) || | ||
(e.nodes[0].type.kind === Kind.NON_NULL_TYPE && | ||
e.nodes[0].type.type.kind === Kind.NAMED_TYPE && | ||
(e.message.startsWith( | ||
`Variable "$${e.nodes[0].variable.name.value}" of required ` + | ||
`type "${e.nodes[0].type.type.name.value}!" was not provided.`, | ||
) || | ||
e.message.startsWith( | ||
`Variable "$${e.nodes[0].variable.name.value}" of non-null ` + | ||
`type "${e.nodes[0].type.type.name.value}!" must not be null.`, | ||
)))) | ||
) { | ||
if (isBadUserInputGraphQLError(e)) { | ||
return fromGraphQLError(e, { | ||
@@ -423,0 +423,0 @@ errorClass: UserInputError, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
947368
18099