@apollo/server
Advanced tools
Comparing version 4.0.0-alpha.3 to 4.0.0-alpha.4
@@ -49,2 +49,3 @@ "use strict"; | ||
const isDefined_js_1 = require("./utils/isDefined.js"); | ||
const UnreachableCaseError_js_1 = require("./utils/UnreachableCaseError.js"); | ||
const NoIntrospection = (context) => ({ | ||
@@ -57,7 +58,2 @@ Field(node) { | ||
}); | ||
class UnreachableCaseError extends Error { | ||
constructor(val) { | ||
super(`Unreachable case: ${val}`); | ||
} | ||
} | ||
function defaultLogger() { | ||
@@ -294,3 +290,3 @@ const loglevelLogger = loglevel_1.default.getLogger('apollo-server'); | ||
default: | ||
throw new UnreachableCaseError(this.internals.state); | ||
throw new UnreachableCaseError_js_1.UnreachableCaseError(this.internals.state); | ||
} | ||
@@ -318,3 +314,3 @@ } | ||
} | ||
const { typeDefs, resolvers, parseOptions } = config; | ||
const { typeDefs, resolvers } = config; | ||
const augmentedTypeDefs = Array.isArray(typeDefs) ? typeDefs : [typeDefs]; | ||
@@ -324,3 +320,2 @@ return (0, schema_1.makeExecutableSchema)({ | ||
resolvers, | ||
parseOptions, | ||
}); | ||
@@ -365,3 +360,3 @@ } | ||
default: | ||
throw new UnreachableCaseError(this.internals.state); | ||
throw new UnreachableCaseError_js_1.UnreachableCaseError(this.internals.state); | ||
} | ||
@@ -368,0 +363,0 @@ const barrier = (0, resolvable_1.default)(); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.packageVersion = void 0; | ||
exports.packageVersion = "4.0.0-alpha.3"; | ||
exports.packageVersion = "4.0.0-alpha.4"; | ||
//# sourceMappingURL=packageVersion.js.map |
@@ -28,3 +28,4 @@ "use strict"; | ||
const treeBuilder = new traceTreeBuilder_js_1.TraceTreeBuilder({ | ||
rewriteError: options.rewriteError, | ||
maskedBy: 'ApolloServerPluginInlineTrace', | ||
sendErrors: options.includeErrors, | ||
}); | ||
@@ -31,0 +32,0 @@ if (http?.headers.get('apollo-federation-include-trace') !== 'ftv1') { |
@@ -29,2 +29,6 @@ "use strict"; | ||
return ` | ||
<div class="fallback"> | ||
<h1>Welcome to Apollo Server</h1> | ||
<p>Apollo Explorer cannot be loaded; it appears that you might be offline.</p> | ||
</div> | ||
<style> | ||
@@ -53,2 +57,6 @@ iframe { | ||
return ` | ||
<div class="fallback"> | ||
<h1>Welcome to Apollo Server</h1> | ||
<p>Apollo Sandbox cannot be loaded; it appears that you might be offline.</p> | ||
</div> | ||
<style> | ||
@@ -55,0 +63,0 @@ iframe { |
@@ -32,2 +32,6 @@ "use strict"; | ||
return ` | ||
<div class="fallback"> | ||
<h1>Welcome to Apollo Server</h1> | ||
<p>The full landing page cannot be loaded; it appears that you might be offline.</p> | ||
</div> | ||
<script>window.landingPage = ${encodedConfig};</script> | ||
@@ -86,11 +90,2 @@ <script src="https://apollo-server-landing-page.cdn.apollographql.com/${version}/static/js/main.js"></script>`; | ||
</style> | ||
<div class="fallback"> | ||
<h1>Welcome to Apollo Server</h1> | ||
<p>It appears that you might be offline. POST to this endpoint to query your graph:</p> | ||
<code style="white-space: pre;"> | ||
curl --request POST \\ | ||
--header 'content-type: application/json' \\ | ||
--url '<script>document.write(window.location.href)</script>' \\ | ||
--data '{"query":"query { __typename }"}'</code> | ||
</div> | ||
${config.embed | ||
@@ -97,0 +92,0 @@ ? 'graphRef' in config && config.graphRef |
@@ -6,2 +6,3 @@ "use strict"; | ||
const usage_reporting_protobuf_1 = require("@apollo/usage-reporting-protobuf"); | ||
const UnreachableCaseError_js_1 = require("../utils/UnreachableCaseError.js"); | ||
function internalError(message) { | ||
@@ -22,5 +23,19 @@ return new Error(`[internal apollo-server error] ${message}`); | ||
]); | ||
this.rewriteError = options.rewriteError; | ||
if (options.logger) | ||
this.logger = options.logger; | ||
const { logger, sendErrors, maskedBy } = options; | ||
if (!sendErrors || 'masked' in sendErrors) { | ||
this.transformError = () => new graphql_1.GraphQLError('<masked>', { | ||
extensions: { maskedBy }, | ||
}); | ||
} | ||
else if ('transform' in sendErrors) { | ||
this.transformError = sendErrors.transform; | ||
} | ||
else if ('unmodified' in sendErrors) { | ||
this.transformError = null; | ||
} | ||
else { | ||
throw new UnreachableCaseError_js_1.UnreachableCaseError(sendErrors); | ||
} | ||
if (logger) | ||
this.logger = logger; | ||
} | ||
@@ -72,3 +87,3 @@ startTiming() { | ||
} | ||
const errorForReporting = this.rewriteAndNormalizeError(err); | ||
const errorForReporting = this.transformAndNormalizeError(err); | ||
if (errorForReporting === null) { | ||
@@ -121,6 +136,6 @@ return; | ||
} | ||
rewriteAndNormalizeError(err) { | ||
if (this.rewriteError) { | ||
transformAndNormalizeError(err) { | ||
if (this.transformError) { | ||
const clonedError = Object.assign(Object.create(Object.getPrototypeOf(err)), err); | ||
const rewrittenError = this.rewriteError(clonedError); | ||
const rewrittenError = this.transformError(clonedError); | ||
if (rewrittenError === null) { | ||
@@ -132,3 +147,10 @@ return null; | ||
} | ||
return new graphql_1.GraphQLError(rewrittenError.message, err.nodes, err.source, err.positions, err.path, err.originalError, rewrittenError.extensions || err.extensions); | ||
return new graphql_1.GraphQLError(rewrittenError.message, { | ||
nodes: err.nodes, | ||
source: err.source, | ||
positions: err.positions, | ||
path: err.path, | ||
originalError: err.originalError, | ||
extensions: rewrittenError.extensions || err.extensions, | ||
}); | ||
} | ||
@@ -135,0 +157,0 @@ return err; |
@@ -209,3 +209,4 @@ "use strict"; | ||
const treeBuilder = new traceTreeBuilder_js_1.TraceTreeBuilder({ | ||
rewriteError: options.rewriteError, | ||
maskedBy: 'ApolloServerPluginUsageReporting', | ||
sendErrors: options.sendErrorsInTraces, | ||
logger, | ||
@@ -212,0 +213,0 @@ }); |
@@ -20,2 +20,3 @@ import { isNodeLike } from '@apollo/utils.isnodelike'; | ||
import { isDefined } from './utils/isDefined.js'; | ||
import { UnreachableCaseError } from './utils/UnreachableCaseError.js'; | ||
const NoIntrospection = (context) => ({ | ||
@@ -28,7 +29,2 @@ Field(node) { | ||
}); | ||
class UnreachableCaseError extends Error { | ||
constructor(val) { | ||
super(`Unreachable case: ${val}`); | ||
} | ||
} | ||
function defaultLogger() { | ||
@@ -288,3 +284,3 @@ const loglevelLogger = loglevel.getLogger('apollo-server'); | ||
} | ||
const { typeDefs, resolvers, parseOptions } = config; | ||
const { typeDefs, resolvers } = config; | ||
const augmentedTypeDefs = Array.isArray(typeDefs) ? typeDefs : [typeDefs]; | ||
@@ -294,3 +290,2 @@ return makeExecutableSchema({ | ||
resolvers, | ||
parseOptions, | ||
}); | ||
@@ -297,0 +292,0 @@ } |
import type { Logger } from '@apollo/utils.logger'; | ||
import type { IExecutableSchemaDefinition } from '@graphql-tools/schema'; | ||
import type { DocumentNode, GraphQLFieldResolver, GraphQLFormattedError, GraphQLSchema, ValidationContext } from 'graphql'; | ||
import type { DocumentNode, GraphQLFieldResolver, GraphQLFormattedError, GraphQLSchema, ParseOptions, ValidationContext } from 'graphql'; | ||
import type { KeyValueCache } from '@apollo/utils.keyvaluecache'; | ||
@@ -44,3 +44,3 @@ import type { GatewayInterface } from '@apollo/server-gateway-interface'; | ||
csrfPrevention?: CSRFPreventionOptions | boolean; | ||
parseOptions?: IExecutableSchemaDefinition<TContext>['parseOptions']; | ||
parseOptions?: ParseOptions; | ||
} | ||
@@ -47,0 +47,0 @@ interface ApolloServerOptionsWithGateway<TContext extends BaseContext> extends ApolloServerOptionsBase<TContext> { |
@@ -1,2 +0,2 @@ | ||
export declare const packageVersion = "4.0.0-alpha.3"; | ||
export declare const packageVersion = "4.0.0-alpha.4"; | ||
//# sourceMappingURL=packageVersion.d.ts.map |
@@ -1,2 +0,2 @@ | ||
export const packageVersion = "4.0.0-alpha.3"; | ||
export const packageVersion = "4.0.0-alpha.4"; | ||
//# sourceMappingURL=packageVersion.js.map |
@@ -1,5 +0,5 @@ | ||
import type { ApolloServerPluginUsageReportingOptions } from '../usageReporting/options'; | ||
import type { SendErrorsOptions } from '../usageReporting/index.js'; | ||
import type { ApolloServerPlugin, BaseContext } from '../../externalTypes'; | ||
export interface ApolloServerPluginInlineTraceOptions { | ||
rewriteError?: ApolloServerPluginUsageReportingOptions<never>['rewriteError']; | ||
includeErrors?: SendErrorsOptions; | ||
__onlyIfSchemaIsFederated?: boolean; | ||
@@ -6,0 +6,0 @@ } |
@@ -25,3 +25,4 @@ import { Trace } from '@apollo/usage-reporting-protobuf'; | ||
const treeBuilder = new TraceTreeBuilder({ | ||
rewriteError: options.rewriteError, | ||
maskedBy: 'ApolloServerPluginInlineTrace', | ||
sendErrors: options.includeErrors, | ||
}); | ||
@@ -28,0 +29,0 @@ if (http?.headers.get('apollo-federation-include-trace') !== 'ftv1') { |
@@ -26,2 +26,6 @@ function getConfigStringForHtml(config) { | ||
return ` | ||
<div class="fallback"> | ||
<h1>Welcome to Apollo Server</h1> | ||
<p>Apollo Explorer cannot be loaded; it appears that you might be offline.</p> | ||
</div> | ||
<style> | ||
@@ -49,2 +53,6 @@ iframe { | ||
return ` | ||
<div class="fallback"> | ||
<h1>Welcome to Apollo Server</h1> | ||
<p>Apollo Sandbox cannot be loaded; it appears that you might be offline.</p> | ||
</div> | ||
<style> | ||
@@ -51,0 +59,0 @@ iframe { |
@@ -27,2 +27,6 @@ import { getEmbeddedExplorerHTML, getEmbeddedSandboxHTML, } from './getEmbeddedHTML.js'; | ||
return ` | ||
<div class="fallback"> | ||
<h1>Welcome to Apollo Server</h1> | ||
<p>The full landing page cannot be loaded; it appears that you might be offline.</p> | ||
</div> | ||
<script>window.landingPage = ${encodedConfig};</script> | ||
@@ -81,11 +85,2 @@ <script src="https://apollo-server-landing-page.cdn.apollographql.com/${version}/static/js/main.js"></script>`; | ||
</style> | ||
<div class="fallback"> | ||
<h1>Welcome to Apollo Server</h1> | ||
<p>It appears that you might be offline. POST to this endpoint to query your graph:</p> | ||
<code style="white-space: pre;"> | ||
curl --request POST \\ | ||
--header 'content-type: application/json' \\ | ||
--url '<script>document.write(window.location.href)</script>' \\ | ||
--data '{"query":"query { __typename }"}'</code> | ||
</div> | ||
${config.embed | ||
@@ -92,0 +87,0 @@ ? 'graphRef' in config && config.graphRef |
import { GraphQLError, GraphQLResolveInfo } from 'graphql'; | ||
import { Trace, google } from '@apollo/usage-reporting-protobuf'; | ||
import type { Logger } from '@apollo/utils.logger'; | ||
import type { SendErrorsOptions } from './usageReporting'; | ||
export declare class TraceTreeBuilder { | ||
@@ -11,6 +12,7 @@ private rootNode; | ||
private nodes; | ||
private readonly rewriteError?; | ||
private readonly transformError; | ||
constructor(options: { | ||
maskedBy: string; | ||
logger?: Logger; | ||
rewriteError?: (err: GraphQLError) => GraphQLError | null; | ||
sendErrors?: SendErrorsOptions; | ||
}); | ||
@@ -24,5 +26,5 @@ startTiming(): void; | ||
private ensureParentNode; | ||
private rewriteAndNormalizeError; | ||
private transformAndNormalizeError; | ||
} | ||
export declare function dateToProtoTimestamp(date: Date): google.protobuf.Timestamp; | ||
//# sourceMappingURL=traceTreeBuilder.d.ts.map |
import { GraphQLError } from 'graphql'; | ||
import { Trace, google } from '@apollo/usage-reporting-protobuf'; | ||
import { UnreachableCaseError } from '../utils/UnreachableCaseError.js'; | ||
function internalError(message) { | ||
@@ -18,5 +19,19 @@ return new Error(`[internal apollo-server error] ${message}`); | ||
]); | ||
this.rewriteError = options.rewriteError; | ||
if (options.logger) | ||
this.logger = options.logger; | ||
const { logger, sendErrors, maskedBy } = options; | ||
if (!sendErrors || 'masked' in sendErrors) { | ||
this.transformError = () => new GraphQLError('<masked>', { | ||
extensions: { maskedBy }, | ||
}); | ||
} | ||
else if ('transform' in sendErrors) { | ||
this.transformError = sendErrors.transform; | ||
} | ||
else if ('unmodified' in sendErrors) { | ||
this.transformError = null; | ||
} | ||
else { | ||
throw new UnreachableCaseError(sendErrors); | ||
} | ||
if (logger) | ||
this.logger = logger; | ||
} | ||
@@ -68,3 +83,3 @@ startTiming() { | ||
} | ||
const errorForReporting = this.rewriteAndNormalizeError(err); | ||
const errorForReporting = this.transformAndNormalizeError(err); | ||
if (errorForReporting === null) { | ||
@@ -117,6 +132,6 @@ return; | ||
} | ||
rewriteAndNormalizeError(err) { | ||
if (this.rewriteError) { | ||
transformAndNormalizeError(err) { | ||
if (this.transformError) { | ||
const clonedError = Object.assign(Object.create(Object.getPrototypeOf(err)), err); | ||
const rewrittenError = this.rewriteError(clonedError); | ||
const rewrittenError = this.transformError(clonedError); | ||
if (rewrittenError === null) { | ||
@@ -128,3 +143,10 @@ return null; | ||
} | ||
return new GraphQLError(rewrittenError.message, err.nodes, err.source, err.positions, err.path, err.originalError, rewrittenError.extensions || err.extensions); | ||
return new GraphQLError(rewrittenError.message, { | ||
nodes: err.nodes, | ||
source: err.source, | ||
positions: err.positions, | ||
path: err.path, | ||
originalError: err.originalError, | ||
extensions: rewrittenError.extensions || err.extensions, | ||
}); | ||
} | ||
@@ -131,0 +153,0 @@ return err; |
export { ApolloServerPluginUsageReporting } from './plugin.js'; | ||
export type { ApolloServerPluginUsageReportingOptions, SendValuesBaseOptions, VariableValueOptions, ClientInfo, GenerateClientInfo, } from './options.js'; | ||
export type { ApolloServerPluginUsageReportingOptions, SendValuesBaseOptions, VariableValueOptions, SendErrorsOptions, ClientInfo, GenerateClientInfo, } from './options.js'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -9,3 +9,3 @@ import type { GraphQLError, DocumentNode } from 'graphql'; | ||
sendHeaders?: SendValuesBaseOptions; | ||
rewriteError?: (err: GraphQLError) => GraphQLError | null; | ||
sendErrorsInTraces?: SendErrorsOptions; | ||
fieldLevelInstrumentation?: number | ((request: GraphQLRequestContextDidResolveOperation<TContext>) => Promise<number | boolean>); | ||
@@ -46,2 +46,9 @@ includeRequest?: (request: GraphQLRequestContextDidResolveOperation<TContext> | GraphQLRequestContextWillSendResponse<TContext>) => Promise<boolean>; | ||
} | SendValuesBaseOptions; | ||
export declare type SendErrorsOptions = { | ||
unmodified: true; | ||
} | { | ||
masked: true; | ||
} | { | ||
transform: (err: GraphQLError) => GraphQLError | null; | ||
}; | ||
export interface ClientInfo { | ||
@@ -48,0 +55,0 @@ clientName?: string; |
@@ -203,3 +203,4 @@ import { Report, ReportHeader, Trace } from '@apollo/usage-reporting-protobuf'; | ||
const treeBuilder = new TraceTreeBuilder({ | ||
rewriteError: options.rewriteError, | ||
maskedBy: 'ApolloServerPluginUsageReporting', | ||
sendErrors: options.sendErrorsInTraces, | ||
logger, | ||
@@ -206,0 +207,0 @@ }); |
{ | ||
"name": "@apollo/server", | ||
"version": "4.0.0-alpha.3", | ||
"version": "4.0.0-alpha.4", | ||
"description": "Core engine for Apollo GraphQL server", | ||
@@ -103,3 +103,3 @@ "type": "module", | ||
"@apollographql/graphql-playground-html": "1.6.29", | ||
"@graphql-tools/schema": "^8.0.0", | ||
"@graphql-tools/schema": "^9.0.0", | ||
"@josephg/resolvable": "^1.0.0", | ||
@@ -106,0 +106,0 @@ "@types/express-serve-static-core": "4.17.30", |
@@ -62,2 +62,3 @@ import { isNodeLike } from '@apollo/utils.isnodelike'; | ||
import { isDefined } from './utils/isDefined.js'; | ||
import { UnreachableCaseError } from './utils/UnreachableCaseError.js'; | ||
import type { WithRequired } from '@apollo/utils.withrequired'; | ||
@@ -132,11 +133,2 @@ import type { ApolloServerOptionsWithStaticSchema } from './externalTypes/constructor'; | ||
// Throw this in places that should be unreachable (because all other cases have | ||
// been handled, reducing the type of the argument to `never`). TypeScript will | ||
// complain if in fact there is a valid type for the argument. | ||
class UnreachableCaseError extends Error { | ||
constructor(val: never) { | ||
super(`Unreachable case: ${val}`); | ||
} | ||
} | ||
// TODO(AS4): Move this to its own file or something. Also organize the fields. | ||
@@ -677,3 +669,3 @@ | ||
const { typeDefs, resolvers, parseOptions } = config; | ||
const { typeDefs, resolvers } = config; | ||
const augmentedTypeDefs = Array.isArray(typeDefs) ? typeDefs : [typeDefs]; | ||
@@ -690,3 +682,2 @@ | ||
resolvers, | ||
parseOptions, | ||
}); | ||
@@ -693,0 +684,0 @@ } |
@@ -8,2 +8,3 @@ import type { Logger } from '@apollo/utils.logger'; | ||
GraphQLSchema, | ||
ParseOptions, | ||
ValidationContext, | ||
@@ -97,7 +98,5 @@ } from 'graphql'; | ||
// This is used for two different things: parsing the schema if you're a | ||
// SchemaFromTypeDefsConfig, *and* parsing operations. Arguably this is a bit | ||
// weird. If you need to parse schemas with different options, just be a | ||
// SchemaProvidedConfig and call makeExecutableSchema yourself. | ||
parseOptions?: IExecutableSchemaDefinition<TContext>['parseOptions']; | ||
// Used for parsing operations; unlike in AS3, this is not also used for | ||
// parsing the schema. | ||
parseOptions?: ParseOptions; | ||
} | ||
@@ -104,0 +103,0 @@ |
@@ -1,1 +0,1 @@ | ||
export const packageVersion = "4.0.0-alpha.3"; | ||
export const packageVersion = "4.0.0-alpha.4"; |
import { Trace } from '@apollo/usage-reporting-protobuf'; | ||
import { TraceTreeBuilder } from '../traceTreeBuilder.js'; | ||
import type { ApolloServerPluginUsageReportingOptions } from '../usageReporting/options'; | ||
import type { SendErrorsOptions } from '../usageReporting/index.js'; | ||
import { internalPlugin } from '../../internalPlugin.js'; | ||
@@ -10,8 +10,21 @@ import { schemaIsFederated } from '../schemaIsFederated.js'; | ||
/** | ||
* By default, all errors from this service get included in the trace. You | ||
* can specify a filter function to exclude specific errors from being | ||
* reported by returning an explicit `null`, or you can mask certain details | ||
* of the error by modifying it and returning the modified error. | ||
* By default, if a trace contains errors, the errors are included in the | ||
* trace with the message `<masked>`. The errors are associated with specific | ||
* paths in the operation, but do not include the original error message or | ||
* any extensions such as the error `code`, as those details may contain your | ||
* users' private data. The extension `maskedBy: | ||
* 'ApolloServerPluginInlineTrace'` is added. | ||
* | ||
* If you'd like details about the error included in traces, set this option. | ||
* This option can take several forms: | ||
* | ||
* - { masked: true }: mask error messages and omit extensions (DEFAULT) | ||
* - { unmodified: true }: include all error messages and extensions | ||
* - { transform: ... }: a custom function for transforming errors. This | ||
* function receives a `GraphQLError` and may return a `GraphQLError` | ||
* (either a new error, or its potentially-modified argument) or `null`. | ||
* This error is used in the trace; if `null`, the error is not included in | ||
* traces or error statistics. | ||
*/ | ||
rewriteError?: ApolloServerPluginUsageReportingOptions<never>['rewriteError']; | ||
includeErrors?: SendErrorsOptions; | ||
/** | ||
@@ -64,3 +77,4 @@ * This option is for internal use by `@apollo/server` only. | ||
const treeBuilder = new TraceTreeBuilder({ | ||
rewriteError: options.rewriteError, | ||
maskedBy: 'ApolloServerPluginInlineTrace', | ||
sendErrors: options.includeErrors, | ||
}); | ||
@@ -67,0 +81,0 @@ |
@@ -67,2 +67,6 @@ import type { | ||
return ` | ||
<div class="fallback"> | ||
<h1>Welcome to Apollo Server</h1> | ||
<p>Apollo Explorer cannot be loaded; it appears that you might be offline.</p> | ||
</div> | ||
<style> | ||
@@ -96,2 +100,6 @@ iframe { | ||
return ` | ||
<div class="fallback"> | ||
<h1>Welcome to Apollo Server</h1> | ||
<p>Apollo Sandbox cannot be loaded; it appears that you might be offline.</p> | ||
</div> | ||
<style> | ||
@@ -98,0 +106,0 @@ iframe { |
@@ -67,2 +67,6 @@ import type { ApolloServerPlugin, BaseContext } from '../../../externalTypes'; | ||
return ` | ||
<div class="fallback"> | ||
<h1>Welcome to Apollo Server</h1> | ||
<p>The full landing page cannot be loaded; it appears that you might be offline.</p> | ||
</div> | ||
<script>window.landingPage = ${encodedConfig};</script> | ||
@@ -130,11 +134,2 @@ <script src="https://apollo-server-landing-page.cdn.apollographql.com/${version}/static/js/main.js"></script>`; | ||
</style> | ||
<div class="fallback"> | ||
<h1>Welcome to Apollo Server</h1> | ||
<p>It appears that you might be offline. POST to this endpoint to query your graph:</p> | ||
<code style="white-space: pre;"> | ||
curl --request POST \\ | ||
--header 'content-type: application/json' \\ | ||
--url '<script>document.write(window.location.href)</script>' \\ | ||
--data '{"query":"query { __typename }"}'</code> | ||
</div> | ||
${ | ||
@@ -141,0 +136,0 @@ config.embed |
@@ -6,2 +6,4 @@ // This class is a helper for ApolloServerPluginUsageReporting and | ||
import type { Logger } from '@apollo/utils.logger'; | ||
import type { SendErrorsOptions } from './usageReporting'; | ||
import { UnreachableCaseError } from '../utils/UnreachableCaseError.js'; | ||
@@ -14,3 +16,3 @@ function internalError(message: string) { | ||
private rootNode = new Trace.Node(); | ||
private logger: Logger = console; | ||
private logger: Logger = console; // TODO(AS4): why have this default? | ||
public trace = new Trace({ | ||
@@ -32,10 +34,25 @@ root: this.rootNode, | ||
]); | ||
private readonly rewriteError?: (err: GraphQLError) => GraphQLError | null; | ||
private readonly transformError: | ||
| ((err: GraphQLError) => GraphQLError | null) | ||
| null; | ||
public constructor(options: { | ||
maskedBy: string; | ||
logger?: Logger; | ||
rewriteError?: (err: GraphQLError) => GraphQLError | null; | ||
sendErrors?: SendErrorsOptions; | ||
}) { | ||
this.rewriteError = options.rewriteError; | ||
if (options.logger) this.logger = options.logger; | ||
const { logger, sendErrors, maskedBy } = options; | ||
if (!sendErrors || 'masked' in sendErrors) { | ||
this.transformError = () => | ||
new GraphQLError('<masked>', { | ||
extensions: { maskedBy }, | ||
}); | ||
} else if ('transform' in sendErrors) { | ||
this.transformError = sendErrors.transform; | ||
} else if ('unmodified' in sendErrors) { | ||
this.transformError = null; | ||
} else { | ||
throw new UnreachableCaseError(sendErrors); | ||
} | ||
if (logger) this.logger = logger; | ||
} | ||
@@ -105,6 +122,6 @@ | ||
// In terms of reporting, errors can be re-written by the user by | ||
// utilizing the `rewriteError` parameter. This allows changing | ||
// utilizing the `transformError` parameter. This allows changing | ||
// the message or stack to remove potentially sensitive information. | ||
// Returning `null` will result in the error not being reported at all. | ||
const errorForReporting = this.rewriteAndNormalizeError(err); | ||
const errorForReporting = this.transformAndNormalizeError(err); | ||
@@ -178,5 +195,5 @@ if (errorForReporting === null) { | ||
private rewriteAndNormalizeError(err: GraphQLError): GraphQLError | null { | ||
if (this.rewriteError) { | ||
// Before passing the error to the user-provided `rewriteError` function, | ||
private transformAndNormalizeError(err: GraphQLError): GraphQLError | null { | ||
if (this.transformError) { | ||
// Before passing the error to the user-provided `transformError` function, | ||
// we'll make a shadow copy of the error so the user is free to change | ||
@@ -197,3 +214,3 @@ // the object as they see fit. | ||
const rewrittenError = this.rewriteError(clonedError); | ||
const rewrittenError = this.transformError(clonedError); | ||
@@ -213,3 +230,3 @@ // Returning an explicit `null` means the user is requesting that the error | ||
// We only allow rewriteError to change the message and extensions of the | ||
// We only allow transformError to change the message and extensions of the | ||
// error; we keep everything else the same. That way people don't have to | ||
@@ -220,11 +237,10 @@ // do extra work to keep the error on the same trace node. We also keep | ||
// show up in the trace (even in the json field) anyway.) | ||
return new GraphQLError( | ||
rewrittenError.message, | ||
err.nodes, | ||
err.source, | ||
err.positions, | ||
err.path, | ||
err.originalError, | ||
rewrittenError.extensions || err.extensions, | ||
); | ||
return new GraphQLError(rewrittenError.message, { | ||
nodes: err.nodes, | ||
source: err.source, | ||
positions: err.positions, | ||
path: err.path, | ||
originalError: err.originalError, | ||
extensions: rewrittenError.extensions || err.extensions, | ||
}); | ||
} | ||
@@ -231,0 +247,0 @@ return err; |
@@ -6,4 +6,5 @@ export { ApolloServerPluginUsageReporting } from './plugin.js'; | ||
VariableValueOptions, | ||
SendErrorsOptions, | ||
ClientInfo, | ||
GenerateClientInfo, | ||
} from './options.js'; |
@@ -50,8 +50,22 @@ import type { GraphQLError, DocumentNode } from 'graphql'; | ||
/** | ||
* By default, all errors get reported to Apollo servers. You can specify | ||
* a filter function to exclude specific errors from being reported by | ||
* returning an explicit `null`, or you can mask certain details of the error | ||
* by modifying it and returning the modified error. | ||
* By default, if a trace contains errors, the errors are reported to Apollo | ||
* servers with the message `<masked>`. The errors are associated with | ||
* specific paths in the operation, but do not include the original error | ||
* message or any extensions such as the error `code`, as those details may | ||
* contain your users' private data. The extension `maskedBy: | ||
* 'ApolloServerPluginUsageReporting'` is added. | ||
* | ||
* If you'd like details about the error included in traces, set this option. | ||
* This option can take several forms: | ||
* | ||
* - { masked: true }: mask error messages and omit extensions (DEFAULT) | ||
* - { unmodified: true }: send all error messages and extensions to Apollo | ||
* servers | ||
* - { transform: ... }: a custom function for transforming errors. This | ||
* function receives a `GraphQLError` and may return a `GraphQLError` | ||
* (either a new error, or its potentially-modified argument) or `null`. | ||
* This error is used in the report to Apollo servers; if `null`, the error | ||
* is not included in traces or error statistics. | ||
*/ | ||
rewriteError?: (err: GraphQLError) => GraphQLError | null; | ||
sendErrorsInTraces?: SendErrorsOptions; | ||
@@ -325,2 +339,7 @@ // We should strongly consider changing the default to false in AS4. | ||
export type SendErrorsOptions = | ||
| { unmodified: true } | ||
| { masked: true } | ||
| { transform: (err: GraphQLError) => GraphQLError | null }; | ||
export interface ClientInfo { | ||
@@ -327,0 +346,0 @@ clientName?: string; |
@@ -391,3 +391,4 @@ import { Report, ReportHeader, Trace } from '@apollo/usage-reporting-protobuf'; | ||
const treeBuilder: TraceTreeBuilder = new TraceTreeBuilder({ | ||
rewriteError: options.rewriteError, | ||
maskedBy: 'ApolloServerPluginUsageReporting', | ||
sendErrors: options.sendErrorsInTraces, | ||
logger, | ||
@@ -394,0 +395,0 @@ }); |
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
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
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
1245327
380
21931
+ Added@graphql-tools/merge@8.4.2(transitive)
+ Added@graphql-tools/schema@9.0.19(transitive)
+ Added@graphql-tools/utils@9.2.1(transitive)
+ Added@graphql-typed-document-node/core@3.2.0(transitive)
+ Addedvalue-or-promise@1.0.12(transitive)
- Removed@graphql-tools/merge@8.3.1(transitive)
- Removed@graphql-tools/schema@8.5.1(transitive)
- Removed@graphql-tools/utils@8.9.0(transitive)
- Removedvalue-or-promise@1.0.11(transitive)
Updated@graphql-tools/schema@^9.0.0