File: D:/HostingSpaces/SBogers10/shop.komma.nl/node_modules/apollo-graphql/src/operationId.ts
// In Apollo Studio, we want to group requests making the same query together,
// and treat different queries distinctly. But what does it mean for two queries
// to be "the same"? And what if you don't want to send the full text of the
// query to Apollo's servers, either because it contains sensitive data
// or because it contains extraneous operations or fragments?
//
// To solve these problems, ApolloServerPluginUsageReporting has the concept of
// "signatures". We don't (by default) send the full query string of queries to
// Apollo's servers. Instead, each trace has its query string's "signature".
//
// You can technically specify any function mapping a GraphQL query AST
// (DocumentNode) to string as your signature algorithm by providing it as the
// 'calculateSignature' option to ApolloServerPluginUsageReporting. (This option
// is not recommended, because Apollo's servers make some assumptions about the
// semantics of your operation based on the signature.) This file defines the
// default function used for this purpose: defaultUsageReportingSignature
// (formerly known as defaultEngineReportingSignature).
//
// This module utilizes several AST transformations from the adjacent
// 'transforms' module (which are also for writing your own signature method).
// - dropUnusedDefinitions, which removes operations and fragments that
// aren't going to be used in execution
// - hideLiterals, which replaces all numeric and string literals as well
// as list and object input values with "empty" values
// - removeAliases, which removes field aliasing from the query
// - sortAST, which sorts the children of most multi-child nodes
// consistently
// - printWithReducedWhitespace, a variant on graphql-js's 'print'
// which gets rid of unneeded whitespace
//
// defaultUsageReportingSignature consists of applying all of these building
// blocks.
//
// Historical note: the default signature algorithm of the Go engineproxy
// performed all of the above operations, and Apollo's servers then re-ran a
// mostly identical signature implementation on received traces. This was
// primarily to deal with edge cases where some users used literal interpolation
// instead of GraphQL variables, included randomized alias names, etc. In
// addition, the servers relied on the fact that dropUnusedDefinitions had been
// called in order (and that the signature could be parsed as GraphQL) to
// extract the name of the operation for display. This caused confusion, as the
// query document shown in the Studio UI wasn't the same as the one actually
// sent. ApolloServerPluginUsageReporting (previously apollo-engine-reporting)
// uses a reporting API which requires it to explicitly include the operation
// name with each signature; this means that the server no longer needs to parse
// the signature or run its own signature algorithm on it, and the details of
// the signature algorithm are now up to the reporting agent. That said, not all
// Studio features will work properly if your signature function changes the
// signature in unexpected ways.
//
// This file also exports operationRegistrySignature and
// defaultOperationRegistrySignature, which are slightly different normalization
// functions used in other contextes.
import { DocumentNode } from "graphql";
import { createHash } from "apollo-env";
import {
printWithReducedWhitespace,
dropUnusedDefinitions,
sortAST,
hideStringAndNumericLiterals,
removeAliases,
hideLiterals
} from "./transforms";
// The usage reporting signature function consists of removing extra whitespace,
// sorting the AST in a deterministic manner, hiding literals, and removing
// unused definitions.
export function defaultUsageReportingSignature(
ast: DocumentNode,
operationName: string
): string {
return printWithReducedWhitespace(
sortAST(
removeAliases(hideLiterals(dropUnusedDefinitions(ast, operationName)))
)
);
}
// The operation registry signature function consists of removing extra whitespace,
// sorting the AST in a deterministic manner, potentially hiding string and numeric
// literals, and removing unused definitions. This is a less aggressive transform
// than its usage reporting signature counterpart.
export function operationRegistrySignature(
ast: DocumentNode,
operationName: string,
options: { preserveStringAndNumericLiterals: boolean } = {
preserveStringAndNumericLiterals: false
}
): string {
const withoutUnusedDefs = dropUnusedDefinitions(ast, operationName);
const maybeWithLiterals = options.preserveStringAndNumericLiterals
? withoutUnusedDefs
: hideStringAndNumericLiterals(withoutUnusedDefs);
return printWithReducedWhitespace(sortAST(maybeWithLiterals));
}
export function defaultOperationRegistrySignature(
ast: DocumentNode,
operationName: string
): string {
return operationRegistrySignature(ast, operationName, {
preserveStringAndNumericLiterals: false
});
}
export function operationHash(operation: string): string {
return createHash("sha256")
.update(operation)
.digest("hex");
}