UNPKG

graphql

Version:

A Query Language and Runtime which can target any service.

244 lines (243 loc) 10 kB
/** @category Values */ import type { Maybe } from "../jsutils/Maybe.js"; import type { ObjMap, ReadOnlyObjMap } from "../jsutils/ObjMap.js"; import { GraphQLError } from "../error/GraphQLError.js"; import type { DirectiveNode, FieldNode, FragmentSpreadNode, VariableDefinitionNode } from "../language/ast.js"; import type { GraphQLField } from "../type/definition.js"; import type { GraphQLDirective } from "../type/directives.js"; import type { GraphQLSchema } from "../type/schema.js"; import type { FragmentVariableValues } from "./collectFields.js"; import type { GraphQLVariableSignature } from "./getVariableSignature.js"; /** * Coerced variable values prepared for execution. * * The `coerced` map contains runtime values keyed by variable name. The * `sources` map records whether each value came from request input, an operation * default, or a fragment-variable default so utilities can preserve defaults * when replacing variables in literals. */ export interface VariableValues { /** Source metadata for each variable value keyed by variable name. */ readonly sources: ReadOnlyObjMap<VariableValueSource>; /** Coerced runtime variable values keyed by variable name. */ readonly coerced: ReadOnlyObjMap<unknown>; } interface VariableValueSource { readonly signature: GraphQLVariableSignature; readonly value?: unknown; } type VariableValuesOrErrors = { variableValues: VariableValues; errors?: never; } | { errors: ReadonlyArray<GraphQLError>; variableValues?: never; }; /** * Prepares an object map of variableValues of the correct type based on the * provided variable definitions and arbitrary input. If the input cannot be * parsed to match the variable definitions, GraphQLError values are returned. * * Note: Returned maps use null prototypes to avoid collisions with * Object prototype properties. * @param schema - GraphQL schema to use. * @param varDefNodes - The variable definition AST nodes to coerce. * @param inputs - The runtime variable values keyed by variable name. * @param options - Optional configuration for this operation. * @param [options.maxErrors] - Maximum number of coercion errors to report. * @param [options.hideSuggestions] - Whether suggestion text should be omitted * from errors. * @returns Coerced variable values with source metadata, or request errors. * @example * ```ts * // Coerce provided variables and apply operation defaults. * import assert from 'node:assert'; * import { parse } from 'graphql/language'; * import { buildSchema } from 'graphql/utilities'; * import { getVariableValues } from 'graphql/execution'; * * const schema = buildSchema(` * type Query { * reviews(stars: Int!, limit: Int = 10): [String] * } * `); * const document = parse(` * query ($stars: Int!, $limit: Int = 10) { * reviews(stars: $stars, limit: $limit) * } * `); * const operation = document.definitions[0]; * * const result = getVariableValues(schema, operation.variableDefinitions, { * stars: '5', * }); * * assert('variableValues' in result); * * result.variableValues.coerced; // => { stars: 5, limit: 10 } * ``` * @example * ```ts * // This variant uses maxErrors to cap reported coercion errors. * import assert from 'node:assert'; * import { parse } from 'graphql/language'; * import { buildSchema } from 'graphql/utilities'; * import { getVariableValues } from 'graphql/execution'; * * const schema = buildSchema(` * input ReviewInput { * stars: Int! * } * * type Query { * review(input: ReviewInput!): String * } * `); * const document = parse(` * query ($first: ReviewInput!, $second: ReviewInput!) { * first: review(input: $first) * second: review(input: $second) * } * `); * const operation = document.definitions[0]; * * const result = getVariableValues( * schema, * operation.variableDefinitions, * { first: { stars: 'bad' }, second: { stars: 'also bad' } }, * { maxErrors: 1 }, * ); * * assert('errors' in result); * * result.errors.length; // => 2 * result.errors[1].message; // matches /error limit reached/ * ``` */ export declare function getVariableValues(schema: GraphQLSchema, varDefNodes: ReadonlyArray<VariableDefinitionNode>, inputs: { readonly [variable: string]: unknown; }, options?: { maxErrors?: number; hideSuggestions?: boolean; }): VariableValuesOrErrors; /** @internal */ export declare function getFragmentVariableValues(fragmentSpreadNode: FragmentSpreadNode, fragmentSignatures: ReadOnlyObjMap<GraphQLVariableSignature>, variableValues: VariableValues, fragmentVariableValues?: Maybe<FragmentVariableValues>, hideSuggestions?: Maybe<boolean>): FragmentVariableValues; /** * Prepares an object map of argument values given a list of argument * definitions and list of argument AST nodes. * * Note: Returned value uses a null prototype to avoid collisions with * JavaScript's own property names. * @param def - Field or directive definition that declares the arguments. * @param node - Field or directive AST node supplying argument literals. * @param variableValues - Operation variable values returned by getVariableValues. * @param fragmentVariableValues - Fragment variable values for the current fragment scope. * @param hideSuggestions - Whether suggestion text should be omitted from errors. * @returns A map of coerced argument values. * @example * ```ts * // Read literal argument values and defaults. * import { parse } from 'graphql/language'; * import { buildSchema } from 'graphql/utilities'; * import { getArgumentValues } from 'graphql/execution'; * * const schema = buildSchema(` * type Query { * reviews(stars: Int!, limit: Int = 10): [String] * } * `); * const fieldDef = schema.getQueryType().getFields().reviews; * const document = parse('{ reviews(stars: 5) }'); * const fieldNode = document.definitions[0].selectionSet.selections[0]; * * getArgumentValues(fieldDef, fieldNode); // => { stars: 5, limit: 10 } * ``` * @example * ```ts * // This variant resolves argument values from operation variables. * import assert from 'node:assert'; * import { parse } from 'graphql/language'; * import { buildSchema } from 'graphql/utilities'; * import { getArgumentValues, getVariableValues } from 'graphql/execution'; * * const schema = buildSchema(` * type Query { * reviews(stars: Int!): [String] * } * `); * const fieldDef = schema.getQueryType().getFields().reviews; * const document = parse('query ($stars: Int!) { reviews(stars: $stars) }'); * const operation = document.definitions[0]; * const fieldNode = document.definitions[0].selectionSet.selections[0]; * const variables = getVariableValues(schema, operation.variableDefinitions, { * stars: '5', * }); * * assert('variableValues' in variables); * * getArgumentValues(fieldDef, fieldNode, variables.variableValues); // => { stars: 5 } * getArgumentValues(fieldDef, fieldNode); // throws an error * ``` */ export declare function getArgumentValues(def: GraphQLField<unknown, unknown> | GraphQLDirective, node: FieldNode | DirectiveNode, variableValues?: Maybe<VariableValues>, fragmentVariableValues?: Maybe<FragmentVariableValues>, hideSuggestions?: Maybe<boolean>): ObjMap<unknown>; /** * Prepares an object map of argument values given a directive definition * and a AST node which may contain directives. Optionally also accepts a map * of variable values. * * If the directive does not exist on the node, returns undefined. * * Note: Returned value uses a null prototype to avoid collisions with * JavaScript's own property names. * @param directiveDef - Directive definition to read argument definitions from. * @param node - AST node that may contain directives. * @param node.directives - The directives on the AST node. * @param variableValues - Operation variable values returned by getVariableValues. * @param fragmentVariableValues - Fragment variable values for the current fragment scope. * @param hideSuggestions - Whether suggestion text should be omitted from errors. * @returns A map of coerced directive argument values, or undefined when absent. * @example * ```ts * // Read literal directive arguments from a node. * import { parse } from 'graphql/language'; * import { GraphQLSkipDirective } from 'graphql/type'; * import { getDirectiveValues } from 'graphql/execution'; * * const document = parse('{ name @skip(if: true) }'); * const fieldNode = document.definitions[0].selectionSet.selections[0]; * * getDirectiveValues(GraphQLSkipDirective, fieldNode); // => { if: true } * ``` * @example * ```ts * // This variant resolves directive arguments from variables and handles absent directives. * import assert from 'node:assert'; * import { parse } from 'graphql/language'; * import { GraphQLIncludeDirective } from 'graphql/type'; * import { buildSchema } from 'graphql/utilities'; * import { getDirectiveValues, getVariableValues } from 'graphql/execution'; * * const schema = buildSchema('type Query { name: String }'); * const document = parse( * 'query ($includeName: Boolean!) { name @include(if: $includeName) }', * ); * const operation = document.definitions[0]; * const fieldNode = document.definitions[0].selectionSet.selections[0]; * const variables = getVariableValues(schema, operation.variableDefinitions, { * includeName: false, * }); * * assert('variableValues' in variables); * * getDirectiveValues( * GraphQLIncludeDirective, * fieldNode, * variables.variableValues, * ); // => { if: false } * getDirectiveValues(GraphQLIncludeDirective, { directives: [] }); // => undefined * ``` */ export declare function getDirectiveValues(directiveDef: GraphQLDirective, node: { readonly directives?: ReadonlyArray<DirectiveNode> | undefined; }, variableValues?: Maybe<VariableValues>, fragmentVariableValues?: Maybe<FragmentVariableValues>, hideSuggestions?: Maybe<boolean>): undefined | ObjMap<unknown>; export {};