From 46b4ae9d3fe7e8f47bb03e8c20768fd22b36aa88 Mon Sep 17 00:00:00 2001 From: Yaacov Rydzinski Date: Tue, 19 May 2026 23:24:45 +0300 Subject: [PATCH 1/2] docs: use api docs generated from inline jsdoc comments (#4750) --- cspell.yml | 56 +- website/components/ApiCode.tsx | 50 + website/css/globals.css | 224 + website/generate-api.js | 3197 ++++++ website/package-lock.json | 241 +- website/package.json | 4 +- website/pages/_app.tsx | 12 +- website/pages/_meta.ts | 26 +- website/pages/api-v16/_meta.ts | 16 +- website/pages/api-v16/error.mdx | 753 +- website/pages/api-v16/execution.mdx | 1305 ++- website/pages/api-v16/execution/_meta.ts | 20 + website/pages/api-v16/graphql-http.mdx | 38 - website/pages/api-v16/graphql.mdx | 525 +- website/pages/api-v16/graphql/_meta.ts | 12 + website/pages/api-v16/language.mdx | 5861 +++++++++- website/pages/api-v16/language/_meta.ts | 36 + website/pages/api-v16/subscription.mdx | 31 + website/pages/api-v16/type.mdx | 10306 ++++++++++++++++- website/pages/api-v16/type/_meta.ts | 36 + website/pages/api-v16/utilities.mdx | 4781 +++++++- website/pages/api-v16/utilities/_meta.ts | 52 + website/pages/api-v16/validation.mdx | 4139 ++++++- website/pages/api-v16/validation/_meta.ts | 20 + website/pages/api-v17/_meta.ts | 11 + website/pages/api-v17/error.mdx | 505 + website/pages/api-v17/execution.mdx | 4174 +++++++ website/pages/api-v17/execution/_meta.ts | 24 + website/pages/api-v17/graphql.mdx | 596 + website/pages/api-v17/graphql/_meta.ts | 20 + website/pages/api-v17/language.mdx | 5742 ++++++++++ website/pages/api-v17/language/_meta.ts | 36 + website/pages/api-v17/type.mdx | 11846 ++++++++++++++++++++ website/pages/api-v17/type/_meta.ts | 36 + website/pages/api-v17/utilities.mdx | 5435 +++++++++ website/pages/api-v17/utilities/_meta.ts | 48 + website/pages/api-v17/validation.mdx | 4744 ++++++++ website/pages/api-v17/validation/_meta.ts | 20 + website/pages/docs/_meta.ts | 3 + website/pages/docs/graphql-http.mdx | 56 + website/theme.config.tsx | 1 + website/typedoc-api.json | 20 + 42 files changed, 63644 insertions(+), 1414 deletions(-) create mode 100644 website/components/ApiCode.tsx create mode 100644 website/generate-api.js create mode 100644 website/pages/api-v16/execution/_meta.ts delete mode 100644 website/pages/api-v16/graphql-http.mdx create mode 100644 website/pages/api-v16/graphql/_meta.ts create mode 100644 website/pages/api-v16/language/_meta.ts create mode 100644 website/pages/api-v16/subscription.mdx create mode 100644 website/pages/api-v16/type/_meta.ts create mode 100644 website/pages/api-v16/utilities/_meta.ts create mode 100644 website/pages/api-v16/validation/_meta.ts create mode 100644 website/pages/api-v17/_meta.ts create mode 100644 website/pages/api-v17/error.mdx create mode 100644 website/pages/api-v17/execution.mdx create mode 100644 website/pages/api-v17/execution/_meta.ts create mode 100644 website/pages/api-v17/graphql.mdx create mode 100644 website/pages/api-v17/graphql/_meta.ts create mode 100644 website/pages/api-v17/language.mdx create mode 100644 website/pages/api-v17/language/_meta.ts create mode 100644 website/pages/api-v17/type.mdx create mode 100644 website/pages/api-v17/type/_meta.ts create mode 100644 website/pages/api-v17/utilities.mdx create mode 100644 website/pages/api-v17/utilities/_meta.ts create mode 100644 website/pages/api-v17/validation.mdx create mode 100644 website/pages/api-v17/validation/_meta.ts create mode 100644 website/pages/docs/graphql-http.mdx create mode 100644 website/typedoc-api.json diff --git a/cspell.yml b/cspell.yml index 56cade9745..c4339b18e2 100644 --- a/cspell.yml +++ b/cspell.yml @@ -11,7 +11,8 @@ ignorePaths: - benchmark/github-schema.json - website/icons - website/css - - website/pages/api-v16-new + - website/pages/api-v16 + - website/pages/api-v17 overrides: - filename: 'website/**' dictionaries: @@ -60,7 +61,11 @@ words: - sublinks - thunked - tsdoc + - worktree + - worktrees - instanceof + - apos + - middot # Different names used inside tests - Skywalker @@ -92,55 +97,6 @@ words: - vercel - unbatched - # used as href anchors - - graphqlerror - - graphqlerroroptions - - syntaxerror - - formaterror - - locatederror - - executionargs - - graphqlargs - - graphqlsync - - graphqlschema - - graphqlsubscription - - graphqlscalartype - - graphqlobjecttype - - graphqlinterfacetype - - graphqluniontype - - graphqlenumtype - - graphqlinputobjecttype - - graphqllist - - graphqlnonnull - - graphqlint - - graphqlfloat - - graphqlstring - - graphqlboolean - - graphqlid - - getlocation - - directivelocation - - tokenkind - - getenterleaveforkind - - getroottype - - assertname - - isinputtype - - isoutputtype - - isleaftype - - iscompositetype - - isabstracttype - - getnullabletype - - getnamedtype - - introspectionquery - - buildclientschema - - buildschema - - printschema - - printintrospectionschema - - buildastschema - - typefromast - - astfromvalue - - typeinfo - - isvalidjsvalue - - isvalidliteralvalue - - specifiedrules - Wordmark - codeofconduct - graphqlconf diff --git a/website/components/ApiCode.tsx b/website/components/ApiCode.tsx new file mode 100644 index 0000000000..ff673a22c1 --- /dev/null +++ b/website/components/ApiCode.tsx @@ -0,0 +1,50 @@ +/* eslint-disable node/no-unpublished-import */ + +import React from 'react'; + +type ApiTokenKind = + | 'keyword' + | 'literal' + | 'name' + | 'parameter' + | 'property' + | 'type'; +type ApiPart = + | string + | readonly [ApiTokenKind, string] + | readonly ['link', string, string]; + +export function ApiSignature({ parts }: { parts: ReadonlyArray }) { + return ( +
+      {renderApiParts(parts)}
+    
+ ); +} + +export function ApiType({ parts }: { parts: ReadonlyArray }) { + return {renderApiParts(parts)}; +} + +function renderApiParts(parts: ReadonlyArray) { + return parts.map((part, index) => { + if (typeof part === 'string') { + return part; + } + + const [kind, value] = part; + if (kind === 'link') { + return ( + + {value} + + ); + } + + return ( + + {value} + + ); + }); +} diff --git a/website/css/globals.css b/website/css/globals.css index d8207c0885..e37406e328 100644 --- a/website/css/globals.css +++ b/website/css/globals.css @@ -77,6 +77,117 @@ div[id^='headlessui-menu-items'] { @apply gap-6; } +/* + * The API versions are real top-level route folders so Nextra can build their sidebars. + * Hide the version folders from non-API sidebars; keep both visible inside either API + * reference so users can switch versions even when a folder is collapsed. + */ +.site-route:not(.api-docs-route) + .nextra-sidebar-container + li:has(> button[data-href='/api-v16']), +.site-route:not(.api-docs-route) + .nextra-sidebar-container + li:has(> button[data-href='/api-v17']) { + display: none; +} + +.api-category-toc { + margin: 1.25rem 0 2rem; + font-size: 0.925rem; + line-height: 1.8; + hyphens: none; + overflow-wrap: normal; + text-align: center !important; + word-break: normal; +} + +.api-category-toc p { + margin: 0.45rem 0; + hyphens: none; + overflow-wrap: normal; + text-align: center !important; + word-break: normal; +} + +.api-category-toc a { + display: inline-block; + hyphens: none; + overflow-wrap: normal; + text-decoration: underline; + text-underline-offset: 0.15em; + word-break: keep-all; +} + +.api-item-divider { + margin: 2rem 0; + border: 0; + border-top: 1px solid rgb(156 163 175); +} + +.api-subsection-divider { + margin: 1rem 0 0.65rem; + border: 0; + border-top: 1px solid rgb(209 213 219); +} + +.api-subsection-title { + margin-bottom: 0.55rem; + font-size: 0.8125rem; + font-weight: 650; + letter-spacing: 0.02em; + text-transform: uppercase; + color: rgb(75 85 99); +} + +.api-tag { + align-items: center; + background: #fffbeb; + border: 1px solid #fbbf24; + border-radius: 999px; + color: #92400e; + display: inline-flex; + font-size: 0.72rem; + font-weight: 600; + line-height: 1.2; + margin-left: 0.35rem; + padding: 0.12rem 0.42rem; + vertical-align: 0.08rem; + white-space: nowrap; +} + +.api-docs-route table { + border-collapse: collapse; + display: table; + margin: 1rem 0; + width: 100%; +} + +.api-docs-route th, +.api-docs-route td { + border: 1px solid rgb(209 213 219); + padding: 0.55rem 0.75rem; + text-align: left; + vertical-align: middle; +} + +.api-docs-route th { + background: #f6f8fa; + color: #24292e; + font-weight: 650; +} + +.api-docs-route table .api-type { + padding: 0.55rem 0.75rem; + width: 100%; +} + +.api-docs-route .api-type::before, +.api-docs-route .api-type::after, +.api-docs-route .api-signature code::before, +.api-docs-route .api-signature code::after { + content: none; +} + /* Move nav links to the left */ .nextra-nav-container nav { @apply justify-start; @@ -135,6 +246,119 @@ div[id^='headlessui-menu-items'] { @apply bg-primary/50 dark:bg-primary; } +.api-signature { + background: #f6f8fa; + border-radius: 0.375rem; + color: #24292e; + font-size: 0.875rem; + line-height: 1.7; + margin: 1rem 0; + overflow-x: auto; + overflow-wrap: normal; + padding: 0.75rem 1rem; + tab-size: 2; + white-space: pre-wrap; + word-break: normal; +} + +pre.api-signature > code:not([class*='twoslash-']) { + display: block !important; + white-space: inherit; +} + +pre.api-signature > code:not([class*='twoslash-']) > span, +pre.api-signature > code:not([class*='twoslash-']) a { + display: inline !important; + padding: 0 !important; +} + +.api-signature :where(a:hover), +.api-type :where(a:hover) { + text-decoration: underline; +} + +.api-signature-name { + color: #6f42c1; +} + +.api-signature-keyword { + color: #d73a49; +} + +.api-signature-type { + color: #005cc5; + text-decoration: none; +} + +.api-signature-parameter, +.api-signature-property { + color: #e36209; +} + +.api-signature-literal { + color: #032f62; +} + +.api-type { + background: #f6f8fa; + border-radius: 0.375rem; + color: #24292e; + display: block; + font-size: 0.875em; + line-height: 1.7; + max-width: 100%; + overflow-x: auto; + padding: 0.15rem 0.35rem; + white-space: pre-wrap; +} + +html[class~='dark'] .api-signature { + background: #111827; + color: #e1e4e8; +} + +html[class~='dark'] .api-type { + background: #111827; + color: #e1e4e8; +} + +html[class~='dark'] .api-tag { + background: #422006; + border-color: #a16207; + color: #fde68a; +} + +html[class~='dark'] .api-docs-route th, +html[class~='dark'] .api-docs-route td { + border-color: rgb(75 85 99); +} + +html[class~='dark'] .api-docs-route th { + background: #111827; + color: #e1e4e8; +} + +html[class~='dark'] .api-signature-type { + color: #79b8ff; +} + +html[class~='dark'] .api-signature-name { + color: #b392f0; +} + +html[class~='dark'] .api-signature-keyword { + color: #f97583; +} + +html[class~='dark'] .api-signature-parameter, +html[class~='dark'] .api-signature-property { + color: #ffa657; +} + +html[class~='dark'] .api-signature-literal { + color: #a5d6ff; +} + @media (prefers-color-scheme: dark) { body { /*background: linear-gradient(*/ diff --git a/website/generate-api.js b/website/generate-api.js new file mode 100644 index 0000000000..6bcd5d2b50 --- /dev/null +++ b/website/generate-api.js @@ -0,0 +1,3197 @@ +'use strict'; + +const { + cpSync, + existsSync, + mkdtempSync, + mkdirSync, + readdirSync, + readFileSync, + rmSync, + writeFileSync, +} = require('node:fs'); +const { spawnSync } = require('node:child_process'); +const { createRequire } = require('node:module'); +const { tmpdir } = require('node:os'); +const { dirname, join, resolve } = require('node:path'); + +const repoRoot = resolve(__dirname, '..'); +const websiteDir = __dirname; +const repoRequire = createRequire(join(repoRoot, 'package.json')); +const websiteRequire = createRequire(join(websiteDir, 'package.json')); +const typedocTemplatePath = join(__dirname, 'typedoc-api.json'); +const tmpDir = mkdtempSync(join(tmpdir(), 'graphql-js-api-')); +const prettier = repoRequire('prettier'); +const ts = websiteRequire('typescript'); +const prettierConfig = prettier.resolveConfig.sync(repoRoot) ?? {}; +const signaturePrettierOptions = { + ...prettierConfig, + parser: 'typescript', +}; + +let generation = { + docsVersionLabel: 'api-docs', +}; +const worktreeDirs = []; + +const groupOrder = [ + 'Classes', + 'Functions', + 'Constants', + 'Enumerations', + 'Types', +]; + +// TypeDoc serializes reflection kinds as numeric enum values in JSON. +const ReflectionKind = { + Namespace: 4, + Enum: 8, + Variable: 32, + Function: 64, + Class: 128, + Interface: 256, + Constructor: 512, + Property: 1024, + Method: 2048, + IndexSignature: 8192, + Parameter: 32768, + TypeAlias: 2097152, + Reference: 4194304, +}; + +const keywordLikeIdentifiers = new Set(['false', 'null', 'true', 'undefined']); +const literalTokenKinds = new Set([ + ts.SyntaxKind.NumericLiteral, + ts.SyntaxKind.BigIntLiteral, + ts.SyntaxKind.StringLiteral, + ts.SyntaxKind.NoSubstitutionTemplateLiteral, +]); +const typeNodeKeywordNames = new Map([ + [ts.SyntaxKind.AnyKeyword, 'any'], + [ts.SyntaxKind.BigIntKeyword, 'bigint'], + [ts.SyntaxKind.BooleanKeyword, 'boolean'], + [ts.SyntaxKind.NeverKeyword, 'never'], + [ts.SyntaxKind.NullKeyword, 'null'], + [ts.SyntaxKind.NumberKeyword, 'number'], + [ts.SyntaxKind.ObjectKeyword, 'object'], + [ts.SyntaxKind.StringKeyword, 'string'], + [ts.SyntaxKind.SymbolKeyword, 'symbol'], + [ts.SyntaxKind.UndefinedKeyword, 'undefined'], + [ts.SyntaxKind.UnknownKeyword, 'unknown'], + [ts.SyntaxKind.VoidKeyword, 'void'], +]); + +const apiCodeComponents = ['ApiSignature', 'ApiType']; +const deprecatedTagMarkup = + 'Deprecated'; + +const renderContext = emptyRenderContext(); +let sourceContext = emptySourceContext(); +const visibleChildrenCache = new WeakMap(); + +function run(command, args, cwd) { + const result = spawnSync(command, args, { + cwd, + stdio: 'inherit', + env: process.env, + }); + const failure = spawnFailureMessage(command, args, cwd, result); + if (failure != null) { + throw new Error(failure); + } +} + +function spawnFailureMessage(command, args, cwd, result) { + const commandText = [command, ...args].join(' '); + if (result.error != null) { + return `${commandText} failed to start in ${cwd}: ${result.error.message}`; + } + if (result.status !== 0) { + const reason = + result.signal == null + ? `exit code ${result.status}` + : `signal ${result.signal}`; + return `${commandText} failed in ${cwd} with ${reason}`; + } + return null; +} + +function checkoutSourceRef(ref, index) { + const dir = join(tmpDir, `source-${index}`); + run('git', ['worktree', 'add', '--detach', dir, ref], repoRoot); + worktreeDirs.push(dir); + return dir; +} + +function removeSourceWorktrees() { + for (let i = worktreeDirs.length - 1; i >= 0; i--) { + const dir = worktreeDirs[i]; + const result = spawnSync('git', ['worktree', 'remove', '--force', dir], { + cwd: repoRoot, + stdio: 'inherit', + env: process.env, + }); + const failure = spawnFailureMessage( + 'git', + ['worktree', 'remove', '--force', dir], + repoRoot, + result, + ); + if (failure != null) { + console.error(`[api-docs] ${failure}`); + } + } +} + +function readJson(path) { + try { + return JSON.parse(readFileSync(path, 'utf8')); + } catch (error) { + fail(`Cannot parse JSON ${path}: ${error.message}`); + } +} + +function readTsConfig(path) { + const parsed = ts.parseConfigFileTextToJson(path, readFileSync(path, 'utf8')); + if (parsed.error != null) { + const message = ts.flattenDiagnosticMessageText( + parsed.error.messageText, + '\n', + ); + fail(`Cannot parse ${path}: ${message}`); + } + return parsed.config; +} + +function writeJson(path, value) { + writeFileSync(path, JSON.stringify(value, null, 2) + '\n'); +} + +function fail(message) { + throw new Error(`[${generation.docsVersionLabel}] ${message}`); +} + +function sourceFile(path, content) { + return ts.createSourceFile(path, content, ts.ScriptTarget.Latest, true); +} + +function assertSourceRoot(sourceDir) { + if (!existsSync(join(sourceDir, 'src/index.ts'))) { + fail(`Source directory does not look like graphql-js root: ${sourceDir}`); + } +} + +function sourceMajorVersion(sourceDir) { + const version = readJson(join(sourceDir, 'package.json')).version; + const match = typeof version === 'string' ? /^(\d+)\./.exec(version) : null; + if (match == null) { + fail(`Cannot infer major version from package version: ${version}`); + } + return Number(match[1]); +} + +function configureGeneration(ref, dir) { + generation = { + docsVersionLabel: ref, + }; + assertSourceRoot(dir); + + const majorVersion = sourceMajorVersion(dir); + const apiVersion = `api-v${majorVersion}`; + generation = { + apiVersion, + docsBasePath: `/${apiVersion}`, + docsVersionLabel: apiVersion, + jsonPath: join(tmpDir, `${apiVersion}.json`), + majorVersion, + outputDir: join(websiteDir, `pages/${apiVersion}`), + sourceDir: dir, + tmpSourceDir: join(tmpDir, `${apiVersion}-source`), + typedocOptionsPath: join(tmpDir, `${apiVersion}-typedoc.json`), + }; + return majorVersion; +} + +function walkFiles(dir, fn) { + const entries = readdirSync(dir, { withFileTypes: true }).sort( + (left, right) => left.name.localeCompare(right.name), + ); + for (const entry of entries) { + const path = join(dir, entry.name); + if (entry.isDirectory()) { + walkFiles(path, fn); + } else if (entry.isFile()) { + fn(path); + } + } +} + +function collectRootExportNames(sourceRootDir) { + // The root package page documents only declarations exported from files + // directly under src/. Submodule re-exports are documented on submodule pages. + const path = join(sourceRootDir, 'src/index.ts'); + const ast = sourceFile(path, readFileSync(path, 'utf8')); + const names = new Set(); + + for (const statement of ast.statements) { + if (ts.isExportDeclaration(statement)) { + const specifier = statement.moduleSpecifier; + if ( + specifier == null || + !ts.isStringLiteral(specifier) || + !isRootSpecifier(specifier.text) || + !statement.exportClause || + !ts.isNamedExports(statement.exportClause) + ) { + continue; + } + for (const element of statement.exportClause.elements) { + names.add((element.propertyName ?? element.name).text); + } + continue; + } + + if (isExported(statement)) { + const name = statement.name?.text; + if (name != null) { + names.add(name); + } else if (ts.isVariableStatement(statement)) { + for (const declaration of statement.declarationList.declarations) { + if (ts.isIdentifier(declaration.name)) { + names.add(declaration.name.text); + } + } + } + } + } + + return names; +} + +function emptySourceMetadata() { + return { + defaultValuesByRef: new Map(), + importsByRef: new Map(), + typesByRef: new Map(), + }; +} + +function emptyDocsIndex() { + return { + docsById: new Map(), + docsBySymbol: new Map(), + typeParameterDefaultsById: new Map(), + }; +} + +function emptyRenderContext() { + return { + docsBasePath: '', + docsIndex: emptyDocsIndex(), + }; +} + +function emptySourceContext() { + return { + metadata: emptySourceMetadata(), + rootExportNames: new Set(), + }; +} + +function collectSourceMetadata(sourceRootDir) { + const metadata = emptySourceMetadata(); + walkFiles(join(sourceRootDir, 'src'), (path) => { + if (!path.endsWith('.ts')) { + return; + } + + const ast = sourceFile(path, readFileSync(path, 'utf8')); + const packagePath = path.slice(sourceRootDir.length + 1); + + for (const statement of ast.statements) { + collectTypeDefinition(metadata, statement, packagePath); + collectImportedTypes( + metadata, + sourceRootDir, + path, + statement, + packagePath, + ); + collectDeclarationDefaults(metadata, statement, packagePath); + } + }); + + return metadata; +} + +function analyzeSourceSnapshot(sourceRootDir) { + return { + metadata: collectSourceMetadata(sourceRootDir), + rootExportNames: collectRootExportNames(sourceRootDir), + }; +} + +function collectTypeDefinition(metadata, statement, packagePath) { + if ( + (ts.isInterfaceDeclaration(statement) || + ts.isTypeAliasDeclaration(statement)) && + statement.name != null + ) { + metadata.typesByRef.set(sourceTypeKey(packagePath, statement.name.text), { + isPublic: isExported(statement) || hasJSDocTag(statement, 'public'), + packagePath, + node: statement, + }); + } +} + +function collectImportedTypes( + metadata, + sourceRootDir, + path, + statement, + packagePath, +) { + if (!ts.isImportDeclaration(statement)) { + return; + } + + const targetPackagePath = importPackagePath(sourceRootDir, path, statement); + const bindings = statement.importClause?.namedBindings; + if ( + targetPackagePath == null || + bindings == null || + !ts.isNamedImports(bindings) + ) { + return; + } + + for (const element of bindings.elements) { + metadata.importsByRef.set(sourceTypeKey(packagePath, element.name.text), { + packagePath: targetPackagePath, + qualifiedName: (element.propertyName ?? element.name).text, + }); + } +} + +function collectDeclarationDefaults(metadata, statement, packagePath) { + if (ts.isFunctionDeclaration(statement) && statement.name != null) { + collectParameterDefaults( + metadata, + packagePath, + statement.name.text, + statement, + ); + return; + } + + if (!ts.isClassDeclaration(statement) || statement.name == null) { + return; + } + + for (const member of statement.members) { + if (ts.isConstructorDeclaration(member)) { + collectParameterDefaults( + metadata, + packagePath, + statement.name.text, + member, + ); + } else if (ts.isMethodDeclaration(member)) { + const name = propertyNameText(member.name); + if (name != null) { + collectParameterDefaults(metadata, packagePath, name, member); + } + } + } +} + +function importPackagePath(sourceRootDir, path, statement) { + if (!ts.isStringLiteral(statement.moduleSpecifier)) { + return null; + } + + const specifier = statement.moduleSpecifier.text; + if (!specifier.startsWith('.')) { + return null; + } + + const resolvedPath = resolve(dirname(path), specifier); + const candidates = [`${resolvedPath}.ts`, join(resolvedPath, 'index.ts')]; + const targetPath = candidates.find((candidate) => existsSync(candidate)); + return targetPath == null ? null : targetPath.slice(sourceRootDir.length + 1); +} + +function collectParameterDefaults( + metadata, + packagePath, + declarationName, + declaration, +) { + for (const parameter of declaration.parameters ?? []) { + if (!ts.isIdentifier(parameter.name) || parameter.initializer == null) { + continue; + } + metadata.defaultValuesByRef.set( + sourceDefaultKey(packagePath, declarationName, parameter.name.text), + parameter.initializer.getText(), + ); + } +} + +function propertyNameText(name) { + return ts.isIdentifier(name) || ts.isStringLiteral(name) ? name.text : null; +} + +function hasJSDocTag(node, tagName) { + return ts + .getJSDocTags(node) + .some((jsDocTag) => jsDocTag.tagName.text === tagName); +} + +function sourceTypeKey(packagePath, qualifiedName) { + return `${packagePath}:${qualifiedName}`; +} + +function sourceDefaultKey(packagePath, declarationName, parameterName) { + return `${packagePath}:${declarationName}:${parameterName}`; +} + +function isRootSpecifier(specifier) { + return specifier.startsWith('./') && !specifier.slice(2).includes('/'); +} + +function writeMeta(dir, entries) { + const content = [ + 'const meta = {', + entries.map(metaEntry).join('\n'), + '};', + '', + 'export default meta;', + '', + ].join('\n'); + + writeFileSync(join(dir, '_meta.ts'), content); +} + +function metaEntry([key, value]) { + const property = metaKey(key); + + if (typeof value === 'string') { + return ` ${property}: '${value}',`; + } + + return [ + ` ${property}: {`, + ` title: '${value.title}',`, + ` href: '${value.href}',`, + ' },', + ].join('\n'); +} + +function metaKey(value) { + return /^[A-Za-z_$][\w$]*$/.test(value) ? value : `'${value}'`; +} + +function slug(text) { + return text + .replace(/\\/g, '') + .replace(/`|\(\)$/g, '') + .toLowerCase() + .replace(/[^\w]+/g, '-') + .replace(/^-+|-+$/g, ''); +} + +function commentBlockTag(comment, name) { + return comment?.blockTags?.find((block) => block.tag === name); +} + +function hasCommentTag(comment, name) { + return ( + comment?.modifierTags?.includes(name) === true || + comment?.blockTags?.some((block) => block.tag === name) === true + ); +} + +function hasReflectionTag(node, name) { + return ( + hasCommentTag(node.comment, name) || + node.signatures?.some((signature) => + hasCommentTag(signature.comment, name), + ) === true + ); +} + +function tagText(comment, name, options) { + const block = commentBlockTag(comment, name); + return block == null ? '' : renderParts(block.content, options).trim(); +} + +function defaultText(node, parent, options = {}) { + const value = rawDefaultValue(node, parent, options); + return value == null ? '' : apiCode(value); +} + +function rawDefaultValue(node, parent, options = {}) { + return ( + sourceDefaultValue(node, parent, options) ?? + (node.defaultValue == null || node.defaultValue === '...' + ? null + : node.defaultValue) + ); +} + +function sourceDefaultValue(node, parent, options = {}) { + if ( + node.kind !== ReflectionKind.Parameter || + parent?.name == null || + node?.name == null + ) { + return null; + } + if (options.sourcePackagePath == null) { + return null; + } + return ( + sourceContext.metadata.defaultValuesByRef.get( + sourceDefaultKey(options.sourcePackagePath, parent.name, node.name), + ) ?? null + ); +} + +function summary(node) { + return renderParts(node.comment?.summary ?? [], { + linkCodeSpans: true, + }).trim(); +} + +function directCategory(node) { + return ( + tagText(node.comment, '@category') || + tagText(node.signatures?.[0]?.comment, '@category') || + null + ); +} + +function resolveItemCategory(node, siblings = []) { + const ownCategory = directCategory(node); + if (ownCategory != null && ownCategory !== '') { + return ownCategory; + } + + if (isEnumNamespace(node)) { + return commonCategory(enumLikeMembers(node).map(directCategory)); + } + + for (const sibling of siblings) { + if (sibling === node || sibling.name !== node.name) { + continue; + } + const siblingCategory = directCategory(sibling); + if (siblingCategory != null) { + return siblingCategory; + } + } + return null; +} + +function commonCategory(categories) { + const visibleCategories = categories.filter(Boolean); + if (visibleCategories.length === 0) { + return null; + } + const [first] = visibleCategories; + return visibleCategories.every((item) => item === first) ? first : null; +} + +function sanitizeTsConfig(tsconfig) { + const compilerOptions = tsconfig.compilerOptions ?? {}; + delete compilerOptions.importsNotUsedAsValues; + delete compilerOptions.rewriteRelativeImportExtensions; + delete compilerOptions.erasableSyntaxOnly; + if (Array.isArray(compilerOptions.lib)) { + compilerOptions.lib = compilerOptions.lib.map((lib) => + String(lib).toLowerCase() === 'es2024' ? 'esnext' : lib, + ); + } + return tsconfig; +} + +function renderParts(parts, options = {}) { + return parts + .map((part) => { + if (part.kind === 'code') { + return options.linkCodeSpans ? linkCodeSpan(part.text) : part.text; + } + return part.text ?? ''; + }) + .join(''); +} + +function linkCodeSpan(value) { + const symbol = inlineCodeText(value); + const doc = symbol == null ? null : singleSymbolDoc(symbol); + if (doc == null) { + return value; + } + + return `[${code(symbol)}](${docHref(doc)})`; +} + +function inlineCodeText(value) { + const text = String(value); + return text.startsWith('`') && text.endsWith('`') && !text.includes('\n') + ? text.slice(1, -1) + : null; +} + +function targetDoc(target) { + return renderContext.docsIndex.docsById.get(target) ?? null; +} + +function singleSymbolDoc(symbol) { + const docs = renderContext.docsIndex.docsBySymbol.get(symbol); + return docs?.length === 1 ? docs[0] : null; +} + +function docHref(doc) { + return `${renderContext.docsBasePath}/${doc.page}${ + doc.anchor == null ? '' : `#${doc.anchor}` + }`; +} + +function heading(level, label) { + return `${'#'.repeat(level)} ${label}`; +} + +function isDeprecated(node) { + return hasCommentTag(node?.comment, '@deprecated'); +} + +function deprecatedTag(node) { + return isDeprecated(node) ? ` ${deprecatedTagMarkup}` : ''; +} + +function callableDeprecatedTag(node, signatures) { + return isDeprecated(node) || + (signatures.length === 1 && isDeprecated(signatures[0])) + ? ` ${deprecatedTagMarkup}` + : ''; +} + +function code(value) { + const normalizedText = String(value).replace(/\r?\n|\r/g, ' '); + const longestBacktickRun = Math.max( + 0, + ...Array.from(normalizedText.matchAll(/`+/g), (match) => match[0].length), + ); + // Markdown code spans cannot escape backticks with backslashes. + const delimiter = '`'.repeat(longestBacktickRun + 1); + const padding = + normalizedText.startsWith('`') || normalizedText.endsWith('`') ? ' ' : ''; + return `${delimiter}${padding}${normalizedText}${padding}${delimiter}`; +} + +function htmlText(value) { + return String(value).replace(/[<>&]/g, (char) => { + switch (char) { + case '<': + return '<'; + case '>': + return '>'; + case '&': + return '&'; + } + return char; + }); +} + +function jsxText(value) { + return String(value).replace(/[&{}<>]/g, (char) => { + switch (char) { + case '&': + return '&'; + case '{': + return '{'; + case '}': + return '}'; + case '<': + return '<'; + case '>': + return '>'; + } + return char; + }); +} + +function jsxAttribute(value) { + return htmlText(value).replace(/"/g, '"'); +} + +function mdxText(value) { + return String(value).replace(/[{}<]/g, (char) => { + switch (char) { + case '{': + return '{'; + case '}': + return '}'; + case '<': + return '<'; + } + return char; + }); +} + +function mdxMarkdown(value) { + return mapInlineCodeSpans( + String(value), + mdxText, + (rawCode, delimiter) => `${delimiter}${rawCode}${delimiter}`, + ); +} + +function table(rows) { + if (rows.length === 0) { + return []; + } + + const headerCells = rows[0] + .map((cell) => ` ${jsxText(cell)}`) + .join('\n'); + const bodyRows = rows + .slice(1) + .map((row) => + [ + ' ', + ...row.map((cell) => ` ${tableCell(cell)}`), + ' ', + ].join('\n'), + ) + .join('\n'); + + return [ + [ + '', + ' ', + ' ', + headerCells, + ' ', + ' ', + ' ', + bodyRows, + ' ', + '
', + ].join('\n'), + ]; +} + +function tableCell(value) { + const cell = String(value); + if (isApiCodeComponentMarkup(cell)) { + return cell; + } + return mapInlineCodeSpans(cell, tableText, tableCode); +} + +function isApiCodeComponentMarkup(value) { + return apiCodeComponents.some((component) => + value.startsWith(`<${component} `), + ); +} + +function tableText(value) { + return jsxText(value).replace(/\\/g, '\').replace(/\n+/g, '
\n'); +} + +function jsString(value) { + return JSON.stringify(value) + .replace(/\|/g, '\\u007c') + .replace(/\u2028/g, '\\u2028') + .replace(/\u2029/g, '\\u2029'); +} + +function jsxCode(value) { + return `{${jsString(value)}}`; +} + +function tableCode(rawCode) { + const value = normalizeCodeSpan(rawCode); + return jsxCode(value); +} + +function normalizeCodeSpan(value) { + const text = value.replace(/\r?\n|\r/g, ' '); + return text.startsWith(' ') && + text.endsWith(' ') && + /\S/.test(text.slice(1, -1)) + ? text.slice(1, -1) + : text; +} + +function mapInlineCodeSpans(value, textFn, codeFn) { + let result = ''; + let index = 0; + + while (index < value.length) { + const start = value.indexOf('`', index); + if (start === -1) { + result += textFn(value.slice(index)); + break; + } + + const delimiter = /^`+/.exec(value.slice(start))[0]; + const end = value.indexOf(delimiter, start + delimiter.length); + if (end === -1) { + result += textFn(value.slice(index)); + break; + } + + result += textFn(value.slice(index, start)); + result += codeFn(value.slice(start + delimiter.length, end), delimiter); + index = end + delimiter.length; + } + + return result; +} + +function targetId(type) { + return typeof type.target === 'number' + ? type.target + : typeof type.target?.id === 'number' + ? type.target.id + : null; +} + +function rawTypeName(type) { + return typeName(type, { keepDefaultTypeArguments: true }); +} + +function typeArguments(type, options) { + const args = type.typeArguments ?? []; + const target = targetId(type); + const defaults = + target == null + ? null + : renderContext.docsIndex.typeParameterDefaultsById.get(target); + if (options.keepDefaultTypeArguments || defaults == null) { + return args; + } + + let end = args.length; + while (end > 0) { + const defaultType = defaults[end - 1]; + if ( + defaultType == null || + rawTypeName(args[end - 1]) !== rawTypeName(defaultType) + ) { + break; + } + end--; + } + return args.slice(0, end); +} + +function referenceName(type) { + return type.name ?? type.qualifiedName; +} + +function typeName(type, options = {}) { + if (type == null) { + return 'unknown'; + } + + switch (type.type) { + case 'array': + return `${arrayElementTypeName(type.elementType, options)}[]`; + case 'conditional': + return `${typeName(type.checkType, options)} extends ${typeName( + type.extendsType, + options, + )} ? ${typeName(type.trueType, options)} : ${typeName( + type.falseType, + options, + )}`; + case 'indexedAccess': + return `${typeName(type.objectType, options)}[${typeName( + type.indexType, + options, + )}]`; + case 'inferred': + case 'intrinsic': + return type.name; + case 'intersection': + return type.types.map((item) => typeName(item, options)).join(' & '); + case 'literal': + return JSON.stringify(type.value); + case 'mapped': + return 'mapped object'; + case 'optional': + return `${typeName(type.elementType, options)}?`; + case 'predicate': + return type.asserts + ? `asserts ${type.name}` + : `${type.name} is ${typeName(type.targetType, options)}`; + case 'query': + return `typeof ${typeName(type.queryType, options)}`; + case 'reference': { + const expanded = sourceTypeEquivalent(type, options); + if (expanded != null) { + return expanded; + } + const args = typeArguments(type, options); + const typeArgs = + args.length === 0 + ? '' + : `<${args.map((arg) => typeName(arg, options)).join(', ')}>`; + return `${referenceName(type)}${typeArgs}`; + } + case 'reflection': + return reflectionType(type.declaration, options); + case 'rest': + return `...${typeName(type.elementType, options)}`; + case 'templateLiteral': + return 'template literal'; + case 'tuple': + return `[${type.elements + .map((item) => typeName(item, options)) + .join(', ')}]`; + case 'typeOperator': + if (type.operator === 'readonly' && type.target?.type === 'array') { + return `readonly ${arrayElementTypeName( + type.target.elementType, + options, + )}[]`; + } + return `${type.operator} ${typeName(type.target, options)}`; + case 'union': + return type.types.map((item) => typeName(item, options)).join(' | '); + case 'unknown': + return 'unknown'; + } + return type.name ?? type.type ?? 'unknown'; +} + +function sourceTypeEquivalent(type, options = {}) { + const qualifiedName = type.target?.qualifiedName ?? type.qualifiedName; + const packagePath = options.sourcePackagePath; + if (qualifiedName == null || packagePath == null) { + return null; + } + const renderedTypeArguments = (type.typeArguments ?? []).map((arg) => + typeName(arg, options), + ); + return sourceTypeName( + packagePath, + qualifiedName, + options, + renderedTypeArguments, + ); +} + +function sourceTypeName( + packagePath, + qualifiedName, + options = {}, + typeArgs = [], +) { + if (options.typeSubstitutions?.has(qualifiedName) && typeArgs.length === 0) { + return options.typeSubstitutions.get(qualifiedName); + } + + const key = sourceTypeKey(packagePath, qualifiedName); + const seen = options.seenSourceTypes ?? new Set(); + if (seen.has(key)) { + return null; + } + + const importedType = sourceContext.metadata.importsByRef.get(key); + if (importedType != null) { + return sourceTypeName( + importedType.packagePath, + importedType.qualifiedName, + { + ...options, + seenSourceTypes: new Set([...seen, key]), + }, + typeArgs, + ); + } + + const definition = sourceContext.metadata.typesByRef.get(key); + if (definition == null || definition.isPublic) { + return null; + } + + const typeSubstitutions = new Map(options.typeSubstitutions); + for (const [index, parameter] of ( + definition.node.typeParameters ?? [] + ).entries()) { + const typeArgument = typeArgs[index]; + if (typeArgument != null) { + typeSubstitutions.set(parameter.name.text, typeArgument); + } + } + const nextOptions = { + ...options, + seenSourceTypes: new Set([...seen, key]), + typeSubstitutions, + }; + const { node } = definition; + if (ts.isInterfaceDeclaration(node)) { + return interfaceTypeName(node, definition.packagePath, nextOptions); + } + if (ts.isTypeAliasDeclaration(node)) { + return renderSourceTypeNode(node.type, definition.packagePath, nextOptions); + } + return null; +} + +function interfaceTypeName(node, packagePath, options) { + const members = node.members + .map((member) => interfaceMemberTypeName(member, packagePath, options)) + .filter(Boolean); + return objectTypeName(members); +} + +function renderSourceTypeNode(node, packagePath, options) { + return typeNodeName(node, packagePath, options); +} + +function objectTypeName(members) { + return members.length === 0 ? 'object' : `{ ${members.join('; ')} }`; +} + +function interfaceMemberTypeName(member, packagePath, options) { + if (ts.isIndexSignatureDeclaration(member)) { + const parameter = member.parameters[0]; + if (parameter?.type == null || member.type == null) { + return null; + } + const parameterType = renderSourceTypeNode( + parameter.type, + packagePath, + options, + ); + const type = renderSourceTypeNode(member.type, packagePath, options); + return indexSignatureText( + hasReadonlyModifier(member), + parameter.name.getText(), + parameterType, + type, + ); + } + + if (ts.isPropertySignature(member) && member.type != null) { + const name = propertyNameText(member.name); + if (name == null) { + return null; + } + const type = renderSourceTypeNode(member.type, packagePath, options); + return `${name}${member.questionToken == null ? '' : '?'}: ${type}`; + } + + return null; +} + +function typeLiteralIndexSignature(signature, options = {}) { + const param = signature.parameters?.[0]; + if (param == null) { + return null; + } + return indexSignatureText( + hasReadonlyFlag(signature), + param.name, + typeName(param.type, options), + typeName(signature.type, options), + ); +} + +function indexSignatureText(isReadonly, name, parameterType, valueType) { + const readonlyText = isReadonly ? 'readonly ' : ''; + return `${readonlyText}[${name}: ${parameterType}]: ${valueType}`; +} + +function hasReadonlyFlag(node) { + return node.flags?.isReadonly === true; +} + +function hasReadonlyModifier(node) { + return ( + node.modifiers?.some( + (modifier) => modifier.kind === ts.SyntaxKind.ReadonlyKeyword, + ) === true + ); +} + +function indexSignatures(node) { + return [ + node?.indexSignature, + ...(node?.indexSignatures ?? []), + ...(node?.children ?? []).filter( + (child) => child.kind === ReflectionKind.IndexSignature, + ), + ].filter(Boolean); +} + +function typeNodeName(node, packagePath, options) { + if (ts.isArrayTypeNode(node)) { + const element = typeNodeName(node.elementType, packagePath, options); + return ts.isUnionTypeNode(node.elementType) || + ts.isIntersectionTypeNode(node.elementType) + ? `(${element})[]` + : `${element}[]`; + } + if (ts.isFunctionTypeNode(node)) { + const params = node.parameters + .map( + (param) => + `${param.name.getText()}${param.questionToken == null ? '' : '?'}: ${ + param.type == null + ? 'unknown' + : typeNodeName(param.type, packagePath, options) + }`, + ) + .join(', '); + return `(${params}) => ${typeNodeName(node.type, packagePath, options)}`; + } + if (ts.isLiteralTypeNode(node)) { + return node.literal.getText(); + } + if (ts.isParenthesizedTypeNode(node)) { + return `(${typeNodeName(node.type, packagePath, options)})`; + } + if (ts.isTypeLiteralNode(node)) { + return interfaceTypeName(node, packagePath, options); + } + if (ts.isTypeOperatorNode(node)) { + return `${ + node.operator === ts.SyntaxKind.ReadonlyKeyword + ? 'readonly' + : node.operator + } ${typeNodeName(node.type, packagePath, options)}`; + } + if (ts.isTypeReferenceNode(node)) { + const name = node.typeName.getText(); + const typeArgs = (node.typeArguments ?? []).map((arg) => + typeNodeName(arg, packagePath, options), + ); + const expanded = sourceTypeName(packagePath, name, options, typeArgs); + const typeArgsText = + typeArgs.length === 0 ? '' : `<${typeArgs.join(', ')}>`; + return expanded ?? `${name}${typeArgsText}`; + } + if (ts.isTupleTypeNode(node)) { + return `[${node.elements + .map((element) => typeNodeName(element, packagePath, options)) + .join(', ')}]`; + } + if (ts.isUnionTypeNode(node)) { + return node.types + .map((item) => typeNodeName(item, packagePath, options)) + .join(' | '); + } + if (ts.isIntersectionTypeNode(node)) { + return node.types + .map((item) => typeNodeName(item, packagePath, options)) + .join(' & '); + } + + return node.getText(); +} + +function signatureText(value) { + return jsxText(value); +} + +function signatureToken(value, kind) { + return `${jsxText(value)}`; +} + +function signatureKeyword(value) { + return signatureToken(value, 'keyword'); +} + +function signatureName(value) { + return signatureToken(value, 'name'); +} + +function signatureTypeToken(value) { + return signatureToken(value, 'type'); +} + +function signatureParameter(value) { + return signatureToken(value, 'parameter'); +} + +function signatureProperty(value) { + return signatureToken(value, 'property'); +} + +function signatureLiteralToken(value) { + return signatureToken(value, 'literal'); +} + +function signatureLink(label, href) { + return `${jsxText( + label, + )}`; +} + +function signaturePartsExpression(value) { + const parts = parseSignatureParts(String(value)); + if (parts.length === 0) { + return '[]'; + } + return `[${parts.map(signaturePartExpression).join(', ')}]`; +} + +function signaturePartExpression(part) { + if (typeof part === 'string') { + return jsPropString(part); + } + if (part.kind === 'link') { + return `[${jsPropString('link')}, ${jsPropString( + part.value, + )}, ${jsPropString(part.href)}]`; + } + return `[${jsPropString(part.kind)}, ${jsPropString(part.value)}]`; +} + +function jsPropString(value) { + return jsString(value).replace(/[<>{}]/g, (char) => { + switch (char) { + case '<': + return '\\u003c'; + case '>': + return '\\u003e'; + case '{': + return '\\u007b'; + case '}': + return '\\u007d'; + } + return char; + }); +} + +function parseSignatureParts(value) { + const parts = []; + let position = 0; + while (position < value.length) { + if (value.startsWith('/.exec( + value.slice(position), + ); + if (start == null) { + fail(`Cannot parse API signature span: ${value.slice(position)}`); + } + const contentStart = position + start[0].length; + const contentEnd = value.indexOf('', contentStart); + if (contentEnd === -1) { + fail(`Unclosed API signature span: ${value.slice(position)}`); + } + parts.push({ + kind: start[1], + value: decodeSignatureHtml(value.slice(contentStart, contentEnd)), + }); + return contentEnd + ''.length; +} + +function readSignatureLink(value, position, parts) { + const prefix = '', hrefStart); + if (hrefEnd === -1) { + fail(`Cannot parse API signature link: ${value.slice(position)}`); + } + const contentStart = hrefEnd + 2; + const contentEnd = value.indexOf('', contentStart); + if (contentEnd === -1) { + fail(`Unclosed API signature link: ${value.slice(position)}`); + } + parts.push({ + kind: 'link', + href: decodeSignatureHtml(value.slice(hrefStart, hrefEnd)), + value: decodeSignatureHtml(value.slice(contentStart, contentEnd)), + }); + return contentEnd + ''.length; +} + +function pushSignatureTextPart(parts, value) { + const textPart = decodeSignatureHtml(value); + if (textPart.length === 0) { + return; + } + const previousPart = parts.at(-1); + if (typeof previousPart === 'string') { + parts[parts.length - 1] = previousPart + textPart; + } else { + parts.push(textPart); + } +} + +function decodeSignatureHtml(value) { + return value.replace( + /&(?:#(\d+)|#x([0-9a-fA-F]+)|amp|apos|gt|lt|quot);/g, + (entity, decimal, hexadecimal) => { + if (decimal != null) { + return String.fromCodePoint(Number(decimal)); + } + if (hexadecimal != null) { + return String.fromCodePoint(Number.parseInt(hexadecimal, 16)); + } + switch (entity) { + case '&': + return '&'; + case ''': + return "'"; + case '>': + return '>'; + case '<': + return '<'; + case '"': + return '"'; + } + return entity; + }, + ); +} + +function apiSignature(value) { + return ``; +} + +function apiCode(value) { + return ``; +} + +function renderSignatureCode(value) { + return renderScannedSignatureSource(String(value), renderSignatureToken); +} + +function renderSignatureToken(token, tokenText) { + if (isKeywordToken(token) || keywordLikeIdentifier(token, tokenText)) { + return signatureKeyword(tokenText); + } + if (isLiteralToken(token)) { + return signatureLiteralToken(tokenText); + } + return signatureText(tokenText); +} + +function renderScannedSignatureSource(source, renderToken) { + const scanner = ts.createScanner( + ts.ScriptTarget.Latest, + false, + ts.LanguageVariant.Standard, + source, + ); + let result = ''; + let position = 0; + let atLineStart = true; + + for ( + let token = scanner.scan(); + token !== ts.SyntaxKind.EndOfFileToken; + token = scanner.scan() + ) { + const tokenStart = scanner.getTokenPos(); + const tokenEnd = scanner.getTextPos(); + const tokenText = scanner.getTokenText(); + result += signatureSourceText(source.slice(position, tokenStart)); + result += + renderLeadingWhitespaceToken(token, tokenText, atLineStart) ?? + renderToken(token, tokenText, atLineStart); + atLineStart = + token === ts.SyntaxKind.NewLineTrivia || + (atLineStart && token === ts.SyntaxKind.WhitespaceTrivia); + position = tokenEnd; + } + + return result + signatureSourceText(source.slice(position)); +} + +function renderLeadingWhitespaceToken(token, tokenText, atLineStart) { + if (atLineStart && token === ts.SyntaxKind.WhitespaceTrivia) { + return tokenText.replace(/ /g, ' ').replace(/\t/g, ' '); + } + return null; +} + +function createSignatureSourceContext(options = {}) { + return { + ...options, + seenSourceTypes: options.seenSourceTypes ?? new Set(), + state: { + nextPlaceholderId: 0, + placeholders: new Map(), + }, + typeSubstitutions: options.typeSubstitutions ?? new Map(), + }; +} + +function withSignatureSourceContext(ctx, overrides) { + return { + ...ctx, + ...overrides, + state: ctx.state, + }; +} + +function signaturePlaceholder(ctx, html) { + const placeholder = `__API_SIGNATURE_${ctx.state.nextPlaceholderId++}__`; + ctx.state.placeholders.set(placeholder, html); + return placeholder; +} + +function signatureNameSource(ctx, name) { + return signaturePlaceholder(ctx, signatureName(name)); +} + +function signatureTypeTokenSource(ctx, name) { + return signaturePlaceholder(ctx, signatureTypeToken(name)); +} + +function signatureParameterSource(ctx, name) { + return signaturePlaceholder(ctx, signatureParameter(name)); +} + +function signaturePropertySource(ctx, name) { + return signaturePlaceholder(ctx, signatureProperty(name)); +} + +function signatureTypeLinkSource(ctx, label, target) { + const doc = targetDoc(target); + return signaturePlaceholder( + ctx, + doc == null + ? signatureTypeToken(label) + : signatureLink(label, docHref(doc)), + ); +} + +function signatureSourceTypeLink(ctx, name) { + const doc = singleSymbolDoc(name); + return signaturePlaceholder( + ctx, + doc == null ? signatureTypeToken(name) : signatureLink(name, docHref(doc)), + ); +} + +function formatSignatureSource(source) { + try { + return prettier.format(source, signaturePrettierOptions).trimEnd(); + } catch (error) { + fail(`Cannot format API signature source:\n${source}\n\n${error.message}`); + } +} + +function renderFormattedSignatureSource(source, ctx) { + return renderScannedSignatureSource(source, (token, tokenText) => + renderFormattedSignatureToken(token, tokenText, ctx), + ); +} + +function renderFormattedSignatureToken(token, tokenText, ctx) { + const placeholder = ctx.state.placeholders.get(tokenText); + if (placeholder != null) { + return placeholder; + } + return renderSignatureToken(token, tokenText); +} + +function signatureSourceText(value) { + return signatureText(value).replace( + /(^|\n)( +)/g, + (_, lineStart, spaces) => `${lineStart}${' '.repeat(spaces.length)}`, + ); +} + +function formatInterfaceMemberSource(memberSource) { + return formatDeclarationBody( + formatSignatureSource(`interface __ApiSignature {\n${memberSource}\n}`), + ); +} + +function formatClassMemberSource(memberSource) { + return formatDeclarationBody( + formatSignatureSource(`declare class __ApiSignature {\n${memberSource}\n}`), + ); +} + +function formatDeclarationBody(source) { + const lines = source.split('\n'); + return lines.slice(1, -1).join('\n').replace(/^ {2}/gm, '').trim(); +} + +function formatTypeSource(type, options = {}) { + const ctx = createSignatureSourceContext(options); + const source = signatureTypeSource(type, ctx); + const formatted = formatInterfaceMemberSource(`__api(): ${source};`); + const body = extractReturnTypeBody(formatted); + return renderFormattedSignatureSource(body, ctx); +} + +function extractReturnTypeBody(source) { + const prefix = '__api():'; + const body = source.slice(prefix.length).replace(/;$/, '').trim(); + return body.replace(/\n {2}([|&] )/g, '\n$1'); +} + +function signatureTypeParametersSource(node, ctx) { + const typeParameters = node.typeParameters ?? []; + if (typeParameters.length === 0) { + return ''; + } + return `<${typeParameters + .map((param) => signatureTypeParameterSource(param, ctx)) + .join(', ')}>`; +} + +function signatureTypeParameterSource(param, ctx) { + const constraint = + param.type == null + ? '' + : ` extends ${signatureTypeSource(param.type, ctx)}`; + const defaultType = + param.default == null + ? '' + : ` = ${signatureTypeSource(param.default, ctx)}`; + return `${signatureTypeTokenSource( + ctx, + param.name, + )}${constraint}${defaultType}`; +} + +function signatureParametersSource(signature, ctx, options = {}) { + return (signature.parameters ?? []) + .map((param) => + signatureParameterDeclarationSource(param, signature, ctx, options), + ) + .join(', '); +} + +function signatureParameterDeclarationSource( + param, + signature, + ctx, + options = {}, +) { + const defaultValue = options.includeDefault + ? rawDefaultValue(param, signature, ctx) + : null; + return `${signatureParameterSource(ctx, param.name)}${ + param.flags?.isOptional === true ? '?' : '' + }: ${signatureTypeSource(param.type, ctx)}${ + defaultValue == null ? '' : ` = ${defaultValue}` + }`; +} + +function signatureFunctionTypeSource(signature, ctx) { + return `(${signatureParametersSource( + signature, + ctx, + )}) => ${signatureTypeSource(signature.type, ctx)}`; +} + +function signatureTypeSource(type, ctx) { + if (type == null) { + return 'unknown'; + } + + switch (type.type) { + case 'array': + return `${signatureArrayElementTypeSource(type.elementType, ctx)}[]`; + case 'conditional': + return `${signatureTypeSource( + type.checkType, + ctx, + )} extends ${signatureTypeSource( + type.extendsType, + ctx, + )} ? ${signatureTypeSource(type.trueType, ctx)} : ${signatureTypeSource( + type.falseType, + ctx, + )}`; + case 'indexedAccess': + return `${signatureTypeSource( + type.objectType, + ctx, + )}[${signatureTypeSource(type.indexType, ctx)}]`; + case 'inferred': + case 'intrinsic': + return type.name; + case 'intersection': + return type.types + .map((item) => signatureTypeSource(item, ctx)) + .join(' & '); + case 'literal': + return JSON.stringify(type.value); + case 'mapped': + return signatureTypeTokenSource(ctx, 'mapped object'); + case 'optional': + return `${signatureTypeSource(type.elementType, ctx)}?`; + case 'predicate': + return type.asserts + ? `asserts ${signatureParameterSource(ctx, type.name)}` + : `${signatureParameterSource(ctx, type.name)} is ${signatureTypeSource( + type.targetType, + ctx, + )}`; + case 'query': + return `typeof ${signatureTypeSource(type.queryType, ctx)}`; + case 'reference': { + const expanded = signatureSourceTypeEquivalent(type, ctx); + if (expanded != null) { + return expanded; + } + const name = referenceName(type); + const target = targetId(type); + const base = + target == null + ? signatureTypeTokenSource(ctx, name) + : signatureTypeLinkSource(ctx, name, target); + return `${base}${signatureTypeArgumentsSource(type, ctx)}`; + } + case 'reflection': + return signatureReflectionTypeSource(type.declaration, ctx); + case 'rest': + return `...${signatureTypeSource(type.elementType, ctx)}`; + case 'templateLiteral': + return signatureTypeTokenSource(ctx, 'template literal'); + case 'tuple': + return `[${type.elements + .map((item) => signatureTypeSource(item, ctx)) + .join(', ')}]`; + case 'typeOperator': + if (type.operator === 'readonly' && type.target?.type === 'array') { + return `readonly ${signatureArrayElementTypeSource( + type.target.elementType, + ctx, + )}[]`; + } + return `${type.operator} ${signatureTypeSource(type.target, ctx)}`; + case 'union': + return type.types + .map((item) => signatureTypeSource(item, ctx)) + .join(' | '); + case 'unknown': + return 'unknown'; + } + return signatureTypeTokenSource( + ctx, + referenceName(type) ?? type.type ?? 'unknown', + ); +} + +function signatureArrayElementTypeSource(type, ctx) { + const source = signatureTypeSource(type, ctx); + return type?.type === 'union' || + type?.type === 'intersection' || + (type?.type === 'reflection' && type.declaration?.signatures?.length) + ? `(${source})` + : source; +} + +function signatureTypeArgumentsSource(type, ctx) { + const args = typeArguments(type, ctx); + return args.length === 0 + ? '' + : `<${args.map((arg) => signatureTypeSource(arg, ctx)).join(', ')}>`; +} + +function signatureSourceTypeEquivalent(type, ctx) { + const qualifiedName = type.target?.qualifiedName ?? type.qualifiedName; + const packagePath = ctx.sourcePackagePath; + if (qualifiedName == null || packagePath == null) { + return null; + } + const renderedTypeArguments = (type.typeArguments ?? []).map((arg) => + signatureTypeSource(arg, ctx), + ); + return signatureSourceTypeName( + packagePath, + qualifiedName, + ctx, + renderedTypeArguments, + ); +} + +function signatureSourceTypeName( + packagePath, + qualifiedName, + ctx, + renderedTypeArguments = [], +) { + if ( + ctx.typeSubstitutions?.has(qualifiedName) && + renderedTypeArguments.length === 0 + ) { + return ctx.typeSubstitutions.get(qualifiedName); + } + + const key = sourceTypeKey(packagePath, qualifiedName); + if (ctx.seenSourceTypes.has(key)) { + return null; + } + + const importedType = sourceContext.metadata.importsByRef.get(key); + if (importedType != null) { + return signatureSourceTypeName( + importedType.packagePath, + importedType.qualifiedName, + withSignatureSourceContext(ctx, { + seenSourceTypes: new Set([...ctx.seenSourceTypes, key]), + }), + renderedTypeArguments, + ); + } + + const definition = sourceContext.metadata.typesByRef.get(key); + if (definition == null || definition.isPublic) { + return null; + } + + const typeSubstitutions = new Map(ctx.typeSubstitutions); + for (const [index, parameter] of ( + definition.node.typeParameters ?? [] + ).entries()) { + const typeArgument = renderedTypeArguments[index]; + if (typeArgument != null) { + typeSubstitutions.set(parameter.name.text, typeArgument); + } + } + + const nextCtx = withSignatureSourceContext(ctx, { + seenSourceTypes: new Set([...ctx.seenSourceTypes, key]), + typeSubstitutions, + }); + const { node } = definition; + if (ts.isInterfaceDeclaration(node)) { + return signatureInterfaceTypeSource(node, definition.packagePath, nextCtx); + } + if (ts.isTypeAliasDeclaration(node)) { + return signatureTypeNodeSource(node.type, definition.packagePath, nextCtx); + } + return null; +} + +function signatureInterfaceTypeSource(node, packagePath, ctx) { + const members = node.members + .map((member) => signatureInterfaceMemberSource(member, packagePath, ctx)) + .filter(Boolean); + return signatureObjectTypeSource(members, ctx); +} + +function signatureObjectTypeSource(members, ctx) { + return members.length === 0 + ? signatureTypeTokenSource(ctx, 'object') + : `{ ${members.join('; ')} }`; +} + +function signatureInterfaceMemberSource(member, packagePath, ctx) { + if (ts.isIndexSignatureDeclaration(member)) { + const parameter = member.parameters[0]; + if (parameter?.type == null || member.type == null) { + return null; + } + return signatureIndexSignatureSource( + hasReadonlyModifier(member), + parameter.name.getText(), + signatureTypeNodeSource(parameter.type, packagePath, ctx), + signatureTypeNodeSource(member.type, packagePath, ctx), + ctx, + ); + } + + if (ts.isPropertySignature(member) && member.type != null) { + const name = propertyNameText(member.name); + if (name == null) { + return null; + } + return signatureTypedPropertySource( + name, + member.questionToken != null, + signatureTypeNodeSource(member.type, packagePath, ctx), + ctx, + ); + } + + return null; +} + +function signatureReflectionTypeSource(node, ctx) { + if (node?.signatures?.length) { + return node.signatures + .map((signature) => `(${signatureFunctionTypeSource(signature, ctx)})`) + .join(' | '); + } + const members = typeLiteralMembers( + node, + ctx, + signatureTypeLiteralIndexSignatureSource, + (child) => + signatureTypedPropertySource( + child.name, + child.flags?.isOptional === true, + signatureTypeSource(child.type, ctx), + ctx, + ), + ); + return signatureObjectTypeSource(members, ctx); +} + +function signatureTypeLiteralIndexSignatureSource(signature, ctx) { + const param = signature.parameters?.[0]; + if (param == null) { + return null; + } + return signatureIndexSignatureSource( + hasReadonlyFlag(signature), + param.name, + signatureTypeSource(param.type, ctx), + signatureTypeSource(signature.type, ctx), + ctx, + ); +} + +function signatureIndexSignatureSource( + isReadonly, + name, + parameterType, + valueType, + ctx, +) { + return `${isReadonly ? 'readonly ' : ''}[${signatureParameterSource( + ctx, + name, + )}: ${parameterType}]: ${valueType}`; +} + +function signatureTypedPropertySource(name, optional, type, ctx) { + return `${signaturePropertyNameSource(name, ctx)}${ + optional ? '?' : '' + }: ${type}`; +} + +function signaturePropertyNameSource(name, ctx) { + return /^[A-Za-z_$][\w$]*$/.test(name) + ? signaturePropertySource(ctx, name) + : JSON.stringify(name); +} + +function signatureTypeNodeSource(node, packagePath, ctx) { + const keyword = typeNodeKeywordNames.get(node.kind); + if (keyword != null) { + return keyword; + } + if (ts.isArrayTypeNode(node)) { + const element = signatureTypeNodeSource(node.elementType, packagePath, ctx); + return ts.isUnionTypeNode(node.elementType) || + ts.isIntersectionTypeNode(node.elementType) || + ts.isFunctionTypeNode(node.elementType) + ? `(${element})[]` + : `${element}[]`; + } + if (ts.isConditionalTypeNode(node)) { + return `${signatureTypeNodeSource( + node.checkType, + packagePath, + ctx, + )} extends ${signatureTypeNodeSource( + node.extendsType, + packagePath, + ctx, + )} ? ${signatureTypeNodeSource( + node.trueType, + packagePath, + ctx, + )} : ${signatureTypeNodeSource(node.falseType, packagePath, ctx)}`; + } + if (ts.isFunctionTypeNode(node)) { + return `(${node.parameters + .map((param) => signatureTypeNodeParameterSource(param, packagePath, ctx)) + .join(', ')}) => ${signatureTypeNodeSource(node.type, packagePath, ctx)}`; + } + if (ts.isIndexedAccessTypeNode(node)) { + return `${signatureTypeNodeSource( + node.objectType, + packagePath, + ctx, + )}[${signatureTypeNodeSource(node.indexType, packagePath, ctx)}]`; + } + if (ts.isLiteralTypeNode(node)) { + return node.literal.getText(); + } + if (ts.isParenthesizedTypeNode(node)) { + return `(${signatureTypeNodeSource(node.type, packagePath, ctx)})`; + } + if (ts.isTypeLiteralNode(node)) { + return signatureInterfaceTypeSource(node, packagePath, ctx); + } + if (ts.isTypeOperatorNode(node)) { + return `${ + node.operator === ts.SyntaxKind.ReadonlyKeyword + ? 'readonly' + : node.operator + } ${signatureTypeNodeSource(node.type, packagePath, ctx)}`; + } + if (ts.isTypeReferenceNode(node)) { + const name = node.typeName.getText(); + const typeArgs = (node.typeArguments ?? []).map((arg) => + signatureTypeNodeSource(arg, packagePath, ctx), + ); + const expanded = signatureSourceTypeName(packagePath, name, ctx, typeArgs); + const typeArgsText = + typeArgs.length === 0 ? '' : `<${typeArgs.join(', ')}>`; + return expanded ?? `${signatureSourceTypeLink(ctx, name)}${typeArgsText}`; + } + if (ts.isTupleTypeNode(node)) { + return `[${node.elements + .map((element) => signatureTypeNodeSource(element, packagePath, ctx)) + .join(', ')}]`; + } + if (ts.isUnionTypeNode(node)) { + return node.types + .map((item) => signatureTypeNodeSource(item, packagePath, ctx)) + .join(' | '); + } + if (ts.isIntersectionTypeNode(node)) { + return node.types + .map((item) => signatureTypeNodeSource(item, packagePath, ctx)) + .join(' & '); + } + + return node.getText(); +} + +function signatureTypeNodeParameterSource(param, packagePath, ctx) { + return `${signatureParameterSource(ctx, param.name.getText())}${ + param.questionToken == null ? '' : '?' + }: ${ + param.type == null + ? 'unknown' + : signatureTypeNodeSource(param.type, packagePath, ctx) + }`; +} + +function isKeywordToken(token) { + return ( + token >= ts.SyntaxKind.FirstKeyword && token <= ts.SyntaxKind.LastKeyword + ); +} + +function keywordLikeIdentifier(token, tokenText) { + return ( + token === ts.SyntaxKind.Identifier && keywordLikeIdentifiers.has(tokenText) + ); +} + +function isLiteralToken(token) { + return literalTokenKinds.has(token); +} + +function arrayElementTypeName(type, options = {}) { + const name = typeName(type, options); + return type?.type === 'union' || type?.type === 'intersection' + ? `(${name})` + : name; +} + +function reflectionType(node, options = {}) { + if (node?.signatures?.length) { + return node.signatures + .map((signature) => signatureType(signature, options)) + .join(' | '); + } + const members = typeLiteralMembers( + node, + options, + typeLiteralIndexSignature, + (child) => + `${child.name}${child.flags?.isOptional ? '?' : ''}: ${typeName( + child.type, + options, + )}`, + ); + return objectTypeName(members); +} + +function signatureType(signature, options = {}) { + const params = (signature.parameters ?? []) + .map( + (param) => + `${param.name}${param.flags?.isOptional ? '?' : ''}: ${typeName( + param.type, + options, + )}`, + ) + .join(', '); + return `(${params}): ${typeName(signature.type, options)}`; +} + +function typeLiteralMembers(node, options, renderIndexSignature, renderChild) { + return [ + ...indexSignatures(node) + .map((signature) => renderIndexSignature(signature, options)) + .filter(Boolean), + ...visibleChildren(node).map(renderChild), + ]; +} + +function renderApiType(type, options = {}) { + return ``; +} + +function renderSignatureDeclaration( + signature, + options = {}, + name = signature.name, +) { + const ctx = createSignatureSourceContext(options); + const source = `${signatureNameSource( + ctx, + name, + )}${signatureTypeParametersSource( + signature, + ctx, + )}(${signatureParametersSource(signature, ctx, { + includeDefault: true, + })}): ${signatureTypeSource(signature.type, ctx)};`; + return apiSignature( + renderFormattedSignatureSource(formatInterfaceMemberSource(source), ctx), + ); +} + +function renderConstructorDeclaration(signature, options = {}) { + const ctx = createSignatureSourceContext(options); + const source = `constructor(${signatureParametersSource(signature, ctx, { + includeDefault: true, + })});`; + const constructorSource = signaturePlaceholder( + ctx, + `${signatureKeyword('new')} ${signatureName(signature.name)}`, + ); + return apiSignature( + renderFormattedSignatureSource( + formatClassMemberSource(source).replace( + /^constructor/, + constructorSource, + ), + ctx, + ), + ); +} + +function renderTypeAliasDeclaration(node, options = {}) { + const ctx = createSignatureSourceContext(options); + const source = `type ${signatureNameSource( + ctx, + node.name, + )}${signatureTypeParametersSource(node, ctx)} = ${signatureTypeSource( + node.type, + ctx, + )};`; + return apiSignature( + renderFormattedSignatureSource(formatSignatureSource(source), ctx), + ); +} + +function declarationKind(node, siblings = []) { + if (isEnumLikeDeclaration(node, siblings)) { + return 'Enumerations'; + } + if (node.kind === ReflectionKind.Class) { + return 'Classes'; + } + if (node.kind === ReflectionKind.Function) { + return 'Functions'; + } + if (node.kind === ReflectionKind.Variable) { + return 'Constants'; + } + if (node.kind === ReflectionKind.Enum) { + return 'Enumerations'; + } + if ( + node.kind === ReflectionKind.TypeAlias || + node.kind === ReflectionKind.Interface || + (node.kind === ReflectionKind.Reference && node.variant === 'declaration') + ) { + return 'Types'; + } + return null; +} + +function isEnumLikeDeclaration(node, siblings = []) { + return isEnumNamespace(node) || isEnumLikeConstObject(node, siblings); +} + +function isEnumLikeConstObject(node, siblings = []) { + return ( + node.kind === ReflectionKind.Variable && + hasMatchingTypeAlias(node, siblings) && + enumLikeMembers(node).length > 0 + ); +} + +function isEnumLikeTypeAlias(node, siblings = []) { + return ( + node.kind === ReflectionKind.TypeAlias && + siblings.some( + (sibling) => + sibling !== node && + sibling.name === node.name && + isEnumLikeConstObject(sibling, siblings), + ) + ); +} + +function hasMatchingTypeAlias(node, siblings = []) { + return siblings.some( + (sibling) => + sibling !== node && + sibling.name === node.name && + sibling.kind === ReflectionKind.TypeAlias, + ); +} + +function isEnumNamespace(node) { + if (node.kind !== ReflectionKind.Namespace) { + return false; + } + const children = visibleChildren(node); + const valueNames = new Set( + children + .filter((child) => child.kind === ReflectionKind.Variable) + .map((child) => child.name), + ); + return children.some( + (child) => + child.kind === ReflectionKind.TypeAlias && valueNames.has(child.name), + ); +} + +function enumLikeMembers(node) { + if (node.kind === ReflectionKind.Namespace) { + return visibleChildren(node).filter( + (child) => child.kind === ReflectionKind.Variable, + ); + } + return visibleChildren(node.type?.declaration); +} + +function visibleChildren(node) { + if (node == null) { + return []; + } + + let children = visibleChildrenCache.get(node); + if (children == null) { + children = (node.children ?? []).filter(isVisibleChild); + visibleChildrenCache.set(node, children); + } + return children; +} + +function isVisibleChild(child) { + return ( + child.variant !== 'reference' && + child.kind !== ReflectionKind.IndexSignature && + !child.flags?.isExternal && + !child.flags?.isInherited && + !child.flags?.isPrivate && + !hasReflectionTag(child, '@internal') && + !hasReflectionTag(child, '@private') + ); +} + +function renderComment(node) { + const parts = []; + + const summaryText = summary(node); + if (summaryText) { + parts.push(mdxMarkdown(summaryText)); + } + + const remarks = tagText(node.comment, '@remarks', { + linkCodeSpans: true, + }); + if (remarks) { + parts.push(`**Remarks:** ${mdxMarkdown(remarks)}`); + } + return parts.join('\n\n'); +} + +function renderFields(parent, level, options = {}) { + const children = visibleChildren(parent).filter( + (child) => + child.kind === ReflectionKind.Property || + child.kind === ReflectionKind.Method, + ); + if (children.length === 0) { + return []; + } + + const lines = []; + const rows = []; + for (const child of children) { + if (child.kind === ReflectionKind.Method) { + if (rows.length > 0 || lines.length > 0) { + lines.push('
'); + } + lines.push(...renderCallable(child, level, child.name)); + continue; + } + const defaultValue = defaultText(child, parent, options); + rows.push([ + `${htmlText(child.name)}${child.flags?.isOptional ? '?' : ''}`, + renderApiType(child.type, options), + defaultValue, + summary(child), + ]); + lines.push(...renderExamples(child.comment, `${child.name} Example`)); + } + const members = tableWithOptionalDefault(rows); + if (rows.length === 0) { + return lines; + } + return options.heading + ? [...headingSubsection('Members', level, members), ...lines] + : [...subsection('Members', members), ...lines]; +} + +function renderParams(signature, options = {}) { + const params = signature.parameters ?? []; + if (params.length === 0) { + return []; + } + + const rows = []; + for (const param of signature.parameters ?? []) { + const defaultValue = defaultText(param, signature, options); + rows.push([ + `${htmlText(param.name)}${param.flags?.isOptional ? '?' : ''}`, + renderApiType(param.type, options), + defaultValue, + summary(param), + ]); + } + return subsection('Arguments', tableWithOptionalDefault(rows)); +} + +function tableWithOptionalDefault(rows) { + const hasDefault = rows.some(([, , defaultValue]) => defaultValue !== ''); + const headers = hasDefault + ? ['Name', 'Type', 'Default', 'Description'] + : ['Name', 'Type', 'Description']; + const visibleRows = hasDefault + ? rows + : rows.map(([name, type, , description]) => [name, type, description]); + return table([headers, ...visibleRows]); +} + +function tableWithOptionalDescription(headers, rows) { + const descriptionIndex = headers.indexOf('Description'); + if ( + descriptionIndex === -1 || + rows.some((row) => row[descriptionIndex] !== '') + ) { + return table([headers, ...rows]); + } + + return table([ + headers.filter((_, index) => index !== descriptionIndex), + ...rows.map((row) => row.filter((_, index) => index !== descriptionIndex)), + ]); +} + +function renderExamples(comment, title = 'Example') { + const examples = (comment?.blockTags ?? []).filter( + (block) => block.tag === '@example', + ); + if (examples.length === 0) { + return []; + } + + return examples.flatMap((example, index) => + subsection(examples.length === 1 ? title : `${title} ${index + 1}`, [ + renderParts(example.content).trim(), + ]), + ); +} + +function renderReturns(signature, options = {}) { + if (signature.type == null || typeName(signature.type, options) === 'void') { + return []; + } + const returns = tagText(signature.comment, '@returns', { + linkCodeSpans: true, + }); + if (!returns) { + return []; + } + return subsection('Returns', [ + ...table([ + ['Type', 'Description'], + [renderApiType(signature.type, options), returns], + ]), + ]); +} + +function renderTypeParameters(node, options = {}) { + const typeParameters = node.typeParameters ?? []; + if (typeParameters.length === 0) { + return []; + } + + const rows = typeParameters.map((param) => [ + param.name, + param.type == null ? '' : renderApiType(param.type, options), + param.default == null ? '' : renderApiType(param.default, options), + summary(param), + ]); + return subsection('Type Parameters', [ + ...table([['Name', 'Constraint', 'Default', 'Description'], ...rows]), + ]); +} + +function publishedExtendedTypes(node) { + if (node.kind !== ReflectionKind.Interface) { + return []; + } + + return (node.extendedTypes ?? []).filter((type) => { + const target = targetId(type); + return target != null && targetDoc(target) != null; + }); +} + +function renderInterfaceDeclaration(node, options = {}) { + const extendedTypes = publishedExtendedTypes(node); + if (extendedTypes.length === 0) { + return ''; + } + + const ctx = createSignatureSourceContext(options); + const source = `interface ${signatureNameSource( + ctx, + node.name, + )}${signatureTypeParametersSource(node, ctx)} extends ${extendedTypes + .map((type) => signatureTypeSource(type, ctx)) + .join(', ')} {}`; + return apiSignature( + renderFormattedSignatureSource( + formatSignatureSource(source).replace(/\s*\{\}$/, ''), + ctx, + ), + ); +} + +function renderCallable( + node, + level, + label = `${node.name}()`, + options = sourceOptions(node), +) { + const signatures = node.signatures ?? [node]; + const headingLabel = label.endsWith(')') ? label : `${label}()`; + const lines = [ + heading(level, `${headingLabel}${callableDeprecatedTag(node, signatures)}`), + ]; + + for (const [index, signature] of signatures.entries()) { + const overloadLabel = + signatures.length > 1 ? `Overload ${index + 1}` : null; + if (overloadLabel) { + lines.push( + ...subsection(`${overloadLabel}${deprecatedTag(signature)}`, []), + ); + } + + const comment = renderComment(signature); + if (comment) { + lines.push(comment); + } + lines.push(...renderTypeParameters(signature, options)); + lines.push( + '**Signature:**', + renderSignatureDeclaration(signature, options), + ); + lines.push(...renderParams(signature, options)); + lines.push(...renderReturns(signature, options)); + lines.push(...renderExamples(signature.comment)); + } + return lines; +} + +function renderDeclaration(node, level = 3, siblings = []) { + const lines = []; + const options = sourceOptions(node); + const title = + node.kind === ReflectionKind.Function ? `${node.name}()` : node.name; + + if (node.kind === ReflectionKind.Function) { + return renderCallable(node, level, title, options); + } + + lines.push(heading(level, `${title}${deprecatedTag(node)}`)); + + const comment = renderComment(node); + const label = typeLabel(node, siblings); + if (label != null) { + lines.push(comment ? `**${label}.** ${comment}` : `**${label}.**`); + } else if (comment) { + lines.push(comment); + } + + lines.push(...renderTypeParameters(node, options)); + const examples = renderExamples(node.comment); + + if (isEnumLikeDeclaration(node, siblings)) { + lines.push(enumLikeNote(node)); + lines.push(...examples); + lines.push(...renderEnumMembers(node, options)); + return lines; + } + + const interfaceDeclaration = renderInterfaceDeclaration(node, options); + if (interfaceDeclaration) { + lines.push(interfaceDeclaration); + } + + if (node.kind === ReflectionKind.Variable) { + lines.push(...subsection('Type', [renderApiType(node.type, options)])); + lines.push(...examples); + return lines; + } + + if ( + (node.kind === ReflectionKind.TypeAlias || + node.kind === ReflectionKind.Reference) && + node.type != null + ) { + lines.push(renderTypeAliasDeclaration(node, options)); + } + + if (node.kind === ReflectionKind.Enum) { + lines.push(...examples); + const rows = visibleChildren(node).map((child) => [ + code(child.name), + code(typeName(child.type, options)), + summary(child), + ]); + lines.push( + ...subsection('Members', [ + ...tableWithOptionalDescription(['Name', 'Value', 'Description'], rows), + ]), + ); + return lines; + } + + if (node.kind === ReflectionKind.Class) { + lines.push(...examples); + const constructors = visibleChildren(node).filter( + (child) => child.kind === ReflectionKind.Constructor, + ); + for (const constructor of constructors) { + for (const signature of constructor.signatures ?? []) { + lines.push( + ...headingSubsection( + `Constructor${deprecatedTag(signature)}`, + level + 1, + ), + ); + const signatureComment = renderComment(signature); + if (signatureComment) { + lines.push(signatureComment); + } + lines.push( + '**Signature:**', + renderConstructorDeclaration(signature, options), + ); + lines.push(...renderParams(signature, options)); + } + } + } else { + lines.push(...examples); + } + + lines.push( + ...renderFields(node, level + 1, { + ...options, + heading: node.kind === ReflectionKind.Class, + }), + ); + return lines; +} + +function enumLikeNote(node) { + const runtimeShape = + node.kind === ReflectionKind.Namespace + ? 'namespace object' + : 'const object'; + return `> This is not a TypeScript ${code('enum')}. GraphQL.js exports ${code( + node.name, + )} as both a runtime ${runtimeShape} of literal values and a TypeScript type alias for those values.`; +} + +function renderEnumMembers(node, options = {}) { + const rows = enumLikeMembers(node).map((child) => [ + code(child.name), + code(typeName(child.type, options)), + summary(child), + ]); + if (rows.length === 0) { + return []; + } + return subsection('Members', [ + ...tableWithOptionalDescription(['Name', 'Value', 'Description'], rows), + ]); +} + +function sourceOptions(node) { + const sourcePackagePath = sourceFileName(node); + return sourcePackagePath == null ? {} : { sourcePackagePath }; +} + +function sourceFileName(node) { + const fileName = node?.sources?.[0]?.fileName; + if (fileName == null) { + return null; + } + if (fileName.startsWith('src/')) { + return fileName; + } + const srcSegment = '/src/'; + const srcIndex = fileName.lastIndexOf(srcSegment); + return srcIndex === -1 + ? `src/${fileName.replace(/^\.\//, '')}` + : fileName.slice(srcIndex + 1); +} + +function typeLabel(node, siblings = []) { + if ( + node.kind === ReflectionKind.Enum || + isEnumLikeDeclaration(node, siblings) + ) { + return 'Enumeration'; + } + if (node.kind === ReflectionKind.Interface) { + return 'Interface'; + } + if ( + node.kind === ReflectionKind.TypeAlias || + (node.kind === ReflectionKind.Reference && node.variant === 'declaration') + ) { + return 'Type alias'; + } + return null; +} + +function apiModuleName(module) { + return module.name === 'index' ? 'graphql' : module.name; +} + +function moduleTitle(name) { + return name === 'graphql' ? 'graphql' : `graphql/${name}`; +} + +function moduleItems(module, name) { + return visibleChildren(module).filter( + (item) => + name !== 'graphql' || sourceContext.rootExportNames.has(item.name), + ); +} + +function categorizedItems(items) { + const categories = []; + const byCategory = new Map(); + const categoryByItem = new Map(); + const leftovers = []; + + for (const item of items) { + if (isEnumLikeTypeAlias(item, items)) { + continue; + } + const itemCategory = resolveItemCategory(item, items); + categoryByItem.set(item, itemCategory); + if (itemCategory != null && !byCategory.has(itemCategory)) { + categories.push(itemCategory); + byCategory.set(itemCategory, []); + } + } + + for (const item of items) { + const itemCategory = categoryByItem.has(item) + ? categoryByItem.get(item) + : resolveItemCategory(item, items); + const categoryItems = byCategory.get(itemCategory); + if (categoryItems == null) { + leftovers.push(item); + continue; + } + categoryItems.push(item); + } + return { categories, byCategory, leftovers }; +} + +function moduleDocs(module) { + const name = apiModuleName(module); + const items = moduleItems(module, name); + const { categories, byCategory, leftovers } = categorizedItems(items); + return { + module, + name, + title: moduleTitle(name), + items, + categories, + byCategory, + leftovers, + }; +} + +function createDocsIndex(modules) { + const index = emptyDocsIndex(); + + for (const docs of modules) { + addSymbolDoc(index, docs.name, { page: docs.name }); + for (const child of docs.items) { + const childDoc = { page: docs.name, anchor: slug(child.name) }; + index.docsById.set(child.id, childDoc); + addSymbolDoc(index, child.name, childDoc); + index.typeParameterDefaultsById.set( + child.id, + (child.typeParameters ?? []).map((param) => param.default ?? null), + ); + for (const member of visibleChildren(child)) { + const memberDoc = { page: docs.name, anchor: slug(member.name) }; + index.docsById.set(member.id, memberDoc); + addSymbolDoc(index, `${child.name}.${member.name}`, memberDoc); + } + for (const signature of child.signatures ?? []) { + index.docsById.set(signature.id, childDoc); + } + } + } + + return index; +} + +function addSymbolDoc(index, symbol, doc) { + const docs = index.docsBySymbol.get(symbol); + if (docs == null) { + index.docsBySymbol.set(symbol, [doc]); + return; + } + + if (!docs.some((existing) => sameDoc(existing, doc))) { + docs.push(doc); + } +} + +function sameDoc(left, right) { + return left.page === right.page && left.anchor === right.anchor; +} + +function renderGroup(title, items, level, allItems) { + if (items.length === 0) { + return []; + } + const lines = [heading(level, title)]; + for (const [index, item] of items.entries()) { + if (index > 0) { + lines.push('
'); + } + lines.push(...renderDeclaration(item, level + 1, allItems)); + } + return lines; +} + +function grouped(items) { + const map = new Map(groupOrder.map((name) => [name, []])); + for (const item of items) { + if (isEnumLikeTypeAlias(item, items)) { + continue; + } + const kind = declarationKind(item, items); + if (kind != null) { + map.get(kind).push(item); + } + } + return map; +} + +function renderItems(items, page, level = 2) { + const groups = grouped(items); + const lines = [renderItemToc(groups, page)]; + for (const group of groupOrder) { + lines.push(...renderGroup(group, groups.get(group), level, items)); + } + return lines.filter(Boolean).join('\n\n').trimEnd() + '\n'; +} + +function renderItemToc(groups, page) { + const lines = []; + for (const group of groupOrder) { + const groupItems = groups.get(group); + if (groupItems.length === 0) { + continue; + } + const tocItems = groupItems + .map((item) => tocLink(item, page)) + .join('\n \n '); + lines.push( + `

\n ${group}:
\n ${tocItems}\n

`, + ); + } + return lines.length === 0 + ? '' + : `
\n${lines.join('\n')}\n
`; +} + +function tocLink(item, page) { + const label = + item.kind === ReflectionKind.Function ? `${item.name}()` : item.name; + return `${jsxText(label)}`; +} + +function subsection(title, lines) { + return [ + '
', + `
${title}
`, + ...lines, + ]; +} + +function headingSubsection(title, level, lines = []) { + return [ + '
', + heading(level, title), + ...lines, + ]; +} + +function addApiCodeImport(page, content) { + const imports = apiCodeComponents.filter((component) => + content.includes(`<${component}`), + ); + if (imports.length === 0) { + return content; + } + const importPath = page.includes('/') + ? '../../../components/ApiCode' + : '../../components/ApiCode'; + return `import { ${imports.join(', ')} } from '${importPath}';\n\n${content}`; +} + +function writePage(page, content) { + const path = join(generation.outputDir, `${page}.mdx`); + mkdirSync(dirname(path), { recursive: true }); + writeFileSync(path, stripTrailingWhitespace(addApiCodeImport(page, content))); +} + +function stripTrailingWhitespace(value) { + return value.replace(/[ \t]+$/gm, ''); +} + +function categoryLinks(visibleCategories, moduleName) { + const links = visibleCategories + .map((name) => `- [${name}](${categoryHref(moduleName, name)})`) + .join('\n'); + return [ + 'For documentation purposes, these exports are grouped into the following categories:', + links, + ].join('\n\n'); +} + +function categoryHref(moduleName, categoryName) { + return `${renderContext.docsBasePath}/${moduleName}#${slug( + categoryHeading(categoryName), + )}`; +} + +function categoryHeading(categoryName) { + return `Category: ${categoryName}`; +} + +function categorySection(name, items, moduleName) { + return [ + heading(2, categoryHeading(name)), + renderItems(items, moduleName, 3).trimEnd(), + ].join('\n\n'); +} + +function renderModulePage(docs) { + const content = [summary(docs.module)]; + if (docs.categories.length === 1) { + content.push( + renderItems(docs.byCategory.get(docs.categories[0]), docs.name).trimEnd(), + ); + } else { + content.push(categoryLinks(docs.categories, docs.name)); + content.push( + ...docs.categories.map((name) => + categorySection(name, docs.byCategory.get(name), docs.name), + ), + ); + } + return content.filter(Boolean).join('\n\n') + '\n'; +} + +function addModuleMeta(meta, docs) { + const entry = [docs.name, docs.title]; + if (docs.name === 'graphql') { + meta.unshift(entry); + } else { + meta.push(entry); + } +} + +function assertAllItemsCategorized(docs) { + if (docs.leftovers.length === 0) { + return; + } + + fail( + `Missing @category in ${docs.title}: ` + + docs.leftovers.map((item) => item.name).join(', '), + ); +} + +function writeCategoryMeta(docs) { + if (docs.categories.length <= 1) { + return; + } + + const dir = join(generation.outputDir, docs.name); + mkdirSync(dir, { recursive: true }); + writeMeta( + dir, + docs.categories.map((name) => [ + slug(name), + { title: categoryHeading(name), href: categoryHref(docs.name, name) }, + ]), + ); +} + +function buildApiReference(doc) { + const modules = (doc.children ?? []).map(moduleDocs); + return { + index: createDocsIndex(modules), + modules, + }; +} + +function writeApiReference(reference) { + renderContext.docsBasePath = generation.docsBasePath; + renderContext.docsIndex = reference.index; + + rmSync(generation.outputDir, { recursive: true, force: true }); + mkdirSync(generation.outputDir, { recursive: true }); + + const meta = []; + for (const docs of reference.modules) { + addModuleMeta(meta, docs); + assertAllItemsCategorized(docs); + writePage(docs.name, renderModulePage(docs)); + writeCategoryMeta(docs); + } + + writeMeta(generation.outputDir, meta); +} + +function renderDocs(doc) { + writeApiReference(buildApiReference(doc)); +} + +function addCategory(comment, category) { + if (/@category\b/.test(comment)) { + return comment; + } + + const trailing = comment.match(/\s*$/)?.[0] ?? ''; + const body = comment.slice(0, comment.length - trailing.length); + const oneLine = /^(\s*)\/\*\*\s*(.*?)\s*\*\/$/.exec(body); + if (oneLine != null) { + const [, indent, text] = oneLine; + return `${indent}/**\n${indent} * ${text}\n${indent} *\n${indent} * @category ${category}\n${indent} */${trailing}`; + } + return ( + body.replace(/\n\s*\*\/$/, `\n *\n * @category ${category}\n */`) + trailing + ); +} + +function isLeadingLineCommentTrivia(value) { + return value.replace(/\/\/[^\n\r]*(?:\r?\n|$)/g, '').trim() === ''; +} + +function isExported(node) { + return node.modifiers?.some( + (modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword, + ); +} + +function localExportNames(ast) { + const names = new Set(); + for (const statement of ast.statements) { + if ( + ts.isExportDeclaration(statement) && + statement.moduleSpecifier == null && + statement.exportClause != null && + ts.isNamedExports(statement.exportClause) + ) { + for (const element of statement.exportClause.elements) { + names.add((element.propertyName ?? element.name).text); + } + } + } + return names; +} + +function declarationNames(statement) { + if (ts.isVariableStatement(statement)) { + return statement.declarationList.declarations + .map((declaration) => + ts.isIdentifier(declaration.name) ? declaration.name.text : null, + ) + .filter(Boolean); + } + return statement.name?.text == null ? [] : [statement.name.text]; +} + +function exportedDeclarations(ast) { + const localExports = localExportNames(ast); + return ast.statements.filter( + (statement) => + (ts.isClassDeclaration(statement) || + ts.isEnumDeclaration(statement) || + ts.isFunctionDeclaration(statement) || + ts.isInterfaceDeclaration(statement) || + ts.isTypeAliasDeclaration(statement) || + ts.isVariableStatement(statement)) && + (isExported(statement) || + declarationNames(statement).some((name) => localExports.has(name))), + ); +} + +function inheritFileCategories(dir) { + // A file-level @category is a default for exported declarations in the + // generated snapshot only; the checked-out source tree is not changed. + walkFiles(dir, (path) => { + if (!path.endsWith('.ts')) { + return; + } + + let content = readFileSync(path, 'utf8'); + const category = content + .match(/^\/\*\*([\s\S]*?)\*\//)?.[1] + .match(/@category\s+([^\n*]+)/)?.[1] + .trim(); + if (category == null) { + return; + } + + const declarations = exportedDeclarations(sourceFile(path, content)); + + for (let i = declarations.length - 1; i >= 0; i--) { + const index = declarations[i].getStart(); + const before = content.slice(0, index); + const start = before.lastIndexOf('/**'); + const end = start === -1 ? -1 : before.indexOf('*/', start); + const jsdocEnd = end === -1 ? -1 : end + 2; + + if ( + start === -1 || + jsdocEnd < start || + !isLeadingLineCommentTrivia(before.slice(jsdocEnd)) + ) { + content = + content.slice(0, index) + + `/**\n * @category ${category}\n */\n` + + content.slice(index); + } else { + content = + content.slice(0, start) + + addCategory(before.slice(start, jsdocEnd), category) + + before.slice(jsdocEnd) + + content.slice(index); + } + } + + writeFileSync(path, content); + }); +} + +function prepareSourceSnapshot() { + // Snapshot the source before running TypeDoc so generation-only compatibility + // fixes never mutate the working tree. + copySourceSnapshot(generation.sourceDir, generation.tmpSourceDir); + writeSnapshotTsConfig(generation.sourceDir, generation.tmpSourceDir); + copyOptionalTsdoc(generation.sourceDir, generation.tmpSourceDir); + writeTypedocOptions(); +} + +function copySourceSnapshot(sourceDir, tmpSourceDir) { + mkdirSync(tmpSourceDir, { recursive: true }); + cpSync(join(sourceDir, 'src'), join(tmpSourceDir, 'src'), { + recursive: true, + }); + stripCoverageIgnoreComments(join(tmpSourceDir, 'src')); + inheritFileCategories(join(tmpSourceDir, 'src')); +} + +function stripCoverageIgnoreComments(dir) { + // Coverage hints can sit between public JSDoc and a declaration. They are + // irrelevant to the generated snapshot and can prevent TypeDoc from attaching + // the public docs to the declaration. + walkFiles(dir, (path) => { + if (!path.endsWith('.ts')) { + return; + } + + const content = readFileSync(path, 'utf8'); + const nextContent = content.replace( + /^[ \t]*\/\*\s*c8 ignore [^*]*\*\/\r?\n/gm, + '', + ); + if (nextContent !== content) { + writeFileSync(path, nextContent); + } + }); +} + +function writeSnapshotTsConfig(sourceDir, tmpSourceDir) { + const tsconfig = sanitizeTsConfig( + readTsConfig(join(sourceDir, 'tsconfig.json')), + ); + writeJson(join(tmpSourceDir, 'tsconfig.json'), tsconfig); +} + +function copyOptionalTsdoc(sourceDir, tmpSourceDir) { + const tsdocPath = join(sourceDir, 'tsdoc.json'); + if (existsSync(tsdocPath)) { + cpSync(tsdocPath, join(tmpSourceDir, 'tsdoc.json')); + } +} + +function writeTypedocOptions() { + const typedocOptions = readJson(typedocTemplatePath); + typedocOptions.name = `GraphQL.js v${generation.docsVersionLabel.slice( + 5, + )} API`; + typedocOptions.entryPoints = typedocEntryPoints(generation.tmpSourceDir); + typedocOptions.json = generation.jsonPath; + typedocOptions.tsconfig = join(generation.tmpSourceDir, 'tsconfig.json'); + typedocOptions.disableSources = false; + writeJson(generation.typedocOptionsPath, typedocOptions); +} + +function typedocEntryPoints(sourceRootDir) { + return [ + 'src/error/index.ts', + 'src/execution/index.ts', + 'src/language/index.ts', + 'src/subscription/index.ts', + 'src/type/index.ts', + 'src/utilities/index.ts', + 'src/validation/index.ts', + 'src/index.ts', + ] + .map((path) => join(sourceRootDir, path)) + .filter((path) => existsSync(path)); +} + +function rememberGeneratedMajor(generatedMajors, majorVersion) { + if (generatedMajors.has(majorVersion)) { + fail( + `Multiple refs resolve to v${majorVersion}; refusing to overwrite docs.`, + ); + } + generatedMajors.add(majorVersion); +} + +function runTypedoc(ref) { + console.log( + `[${generation.docsVersionLabel}] Copied source snapshot from:`, + ref, + ); + run( + 'npm', + ['exec', '--', 'typedoc', '--options', generation.typedocOptionsPath], + websiteDir, + ); +} + +function readTypedocOutput() { + if (!existsSync(generation.jsonPath)) { + fail('TypeDoc did not emit JSON docs.'); + } + + return readJson(generation.jsonPath); +} + +function generateForRef(ref, index, generatedMajors) { + const sourceCheckoutDir = checkoutSourceRef(ref, index); + const majorVersion = configureGeneration(ref, sourceCheckoutDir); + rememberGeneratedMajor(generatedMajors, majorVersion); + prepareSourceSnapshot(); + sourceContext = analyzeSourceSnapshot(generation.tmpSourceDir); + runTypedoc(ref); + renderDocs(readTypedocOutput()); +} + +function generateRefs(refs) { + if (refs.length === 0) { + fail('Usage: npm run generate:docs [...branch-or-ref]'); + } + + const generatedMajors = new Set(); + for (const [index, ref] of refs.entries()) { + generateForRef(ref, index, generatedMajors); + } +} + +try { + generateRefs(process.argv.slice(2)); +} catch (error) { + console.error(error.message); + process.exitCode = 1; +} finally { + removeSourceWorktrees(); + if (process.env.GRAPHQL_JS_API_KEEP_TMP === '1') { + console.error('[api-docs] Kept temporary directory:', tmpDir); + } else { + rmSync(tmpDir, { recursive: true, force: true }); + } +} diff --git a/website/package-lock.json b/website/package-lock.json index e7a1aa8e31..553fa16fca 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -19,6 +19,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "tailwindcss": "^3.4.14", + "typedoc": "0.28.19", "typescript": "^5.6.3" } }, @@ -1838,6 +1839,49 @@ "tslib": "^2.7.0" } }, + "node_modules/@gerrit0/mini-shiki": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.23.0.tgz", + "integrity": "sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/engine-oniguruma": "^3.23.0", + "@shikijs/langs": "^3.23.0", + "@shikijs/themes": "^3.23.0", + "@shikijs/types": "^3.23.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@gerrit0/mini-shiki/node_modules/@shikijs/engine-oniguruma": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz", + "integrity": "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@gerrit0/mini-shiki/node_modules/@shikijs/types": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz", + "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@gerrit0/mini-shiki/node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "dev": true, + "license": "MIT" + }, "node_modules/@headlessui/react": { "version": "2.1.10", "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.1.10.tgz", @@ -2566,6 +2610,62 @@ "@shikijs/vscode-textmate": "^9.3.0" } }, + "node_modules/@shikijs/langs": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.23.0.tgz", + "integrity": "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/langs/node_modules/@shikijs/types": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz", + "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/langs/node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@shikijs/themes": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.23.0.tgz", + "integrity": "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/themes/node_modules/@shikijs/types": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz", + "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/themes/node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "dev": true, + "license": "MIT" + }, "node_modules/@shikijs/twoslash": { "version": "1.22.0", "resolved": "https://registry.npmjs.org/@shikijs/twoslash/-/twoslash-1.22.0.tgz", @@ -5668,6 +5768,16 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, "node_modules/local-pkg": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", @@ -5755,6 +5865,13 @@ "yallist": "^2.1.2" } }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true, + "license": "MIT" + }, "node_modules/markdown-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", @@ -5767,6 +5884,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/markdown-it": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/markdown-table": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", @@ -6130,6 +6272,13 @@ "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", "dev": true }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -7695,6 +7844,16 @@ "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", "dev": true }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -8939,6 +9098,69 @@ "integrity": "sha512-5qZLXVYfZ9ABdjqbvPc4RWMr7PrpPaaDSeaYY55vl/w1j6H6kzsWK/urAEIXlzYlyrFmyz1UbwIt+AA0ck+wbg==", "dev": true }, + "node_modules/typedoc": { + "version": "0.28.19", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.19.tgz", + "integrity": "sha512-wKh+lhdmMFivMlc6vRRcMGXeGEHGU2g8a2CkPTJjJlwRf1iXbimWIPcFolCqe4E0d/FRtGszpIrsp3WLpDB8Pw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@gerrit0/mini-shiki": "^3.23.0", + "lunr": "^2.3.9", + "markdown-it": "^14.1.1", + "minimatch": "^10.2.5", + "yaml": "^2.8.3" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 18", + "pnpm": ">= 10" + }, + "peerDependencies": { + "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x || 6.0.x" + } + }, + "node_modules/typedoc/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/typedoc/node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/typedoc/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/typescript": { "version": "5.6.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", @@ -8952,6 +9174,13 @@ "node": ">=14.17" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" + }, "node_modules/ufo": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", @@ -9479,15 +9708,19 @@ "dev": true }, "node_modules/yaml": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", - "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", "dev": true, + "license": "ISC", "bin": { "yaml": "bin.mjs" }, "engines": { - "node": ">= 14" + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" } }, "node_modules/yocto-queue": { diff --git a/website/package.json b/website/package.json index a69e6e4043..f1e55325e0 100644 --- a/website/package.json +++ b/website/package.json @@ -8,7 +8,8 @@ }, "scripts": { "build": "next build", - "dev": "next" + "dev": "next", + "generate:docs": "node generate-api.js" }, "devDependencies": { "@svgr/webpack": "^8.1.0", @@ -22,6 +23,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "tailwindcss": "^3.4.14", + "typedoc": "0.28.19", "typescript": "^5.6.3" } } diff --git a/website/pages/_app.tsx b/website/pages/_app.tsx index c50ff45c1e..d3a35a29cc 100644 --- a/website/pages/_app.tsx +++ b/website/pages/_app.tsx @@ -1,5 +1,6 @@ import type { AppProps } from 'next/app'; import { Roboto_Flex, Roboto_Mono } from 'next/font/google'; +import { useRouter } from 'next/router'; import '../css/globals.css'; @@ -14,8 +15,15 @@ const robotoMono = Roboto_Mono({ // TODO: do we need google analytics? export default function App({ Component, pageProps }: AppProps) { + const { pathname } = useRouter(); + const isApiDocsRoute = ['/api-v16', '/api-v17'].some( + (basePath) => pathname === basePath || pathname.startsWith(`${basePath}/`), + ); + return ( - <> +
- +
); } diff --git a/website/pages/_meta.ts b/website/pages/_meta.ts index 7bf4b6e9cd..4feffb9b7b 100644 --- a/website/pages/_meta.ts +++ b/website/pages/_meta.ts @@ -13,14 +13,34 @@ const meta = { }, }, }, - 'api-v16': { + api: { type: 'menu', title: 'API', items: { - 2: { - title: 'V16', + v17: { + title: 'v17', + href: '/api-v17/graphql', + }, + v16: { + title: 'v16', href: '/api-v16/graphql', }, + 'graphql-http': { + title: 'graphql-http', + href: '/docs/graphql-http', + }, + }, + }, + 'api-v16': { + title: 'v16 API', + theme: { + collapsed: true, + }, + }, + 'api-v17': { + title: 'v17 API', + theme: { + collapsed: true, }, }, }; diff --git a/website/pages/api-v16/_meta.ts b/website/pages/api-v16/_meta.ts index 075de90bca..2bc84ee348 100644 --- a/website/pages/api-v16/_meta.ts +++ b/website/pages/api-v16/_meta.ts @@ -1,12 +1,12 @@ const meta = { - graphql: '', - error: '', - execution: '', - language: '', - type: '', - utilities: '', - validation: '', - 'graphql-http': '', + graphql: 'graphql', + error: 'graphql/error', + execution: 'graphql/execution', + language: 'graphql/language', + subscription: 'graphql/subscription', + type: 'graphql/type', + utilities: 'graphql/utilities', + validation: 'graphql/validation', }; export default meta; diff --git a/website/pages/api-v16/error.mdx b/website/pages/api-v16/error.mdx index 50cb70e4ea..aed9997068 100644 --- a/website/pages/api-v16/error.mdx +++ b/website/pages/api-v16/error.mdx @@ -1,107 +1,704 @@ ---- -title: graphql/error ---- +import { ApiSignature, ApiType } from '../../components/ApiCode'; -{/* title can be removed in Nextra 4, since sidebar title will take from first h1 */} +Create, format, and locate GraphQL errors. -# `graphql/error` +These exports are also available from the root `graphql` package. -The `graphql/error` module is responsible for creating and formatting -GraphQL errors. You can import either from the `graphql/error` module, or from the root `graphql` module. For example: + -```js -import { GraphQLError } from 'graphql'; +## Classes + +### GraphQLError + +A GraphQLError describes an Error found during the parse, validate, or +execute phases of performing a GraphQL operation. In addition to a message +and stack trace, it also includes information about the locations in a +GraphQL document and/or execution result that correspond to the Error. + +
+ +#### Constructor + +Creates a GraphQLError instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
messageHuman-readable error message.
options?Error metadata such as source locations, response path, original error, and extensions.
+This positional-arguments constructor overload is deprecated. Use the
+{"GraphQLError(message, options)"} overload instead.
+ +
+ +#### Constructor Deprecated + +Creates a GraphQLError instance using the legacy positional constructor. +This deprecated overload will be removed in v17. Prefer the +[`GraphQLErrorOptions`](/api-v16/error#graphqlerroroptions) object overload, which keeps optional error metadata +in a single options bag. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
messageHuman-readable error message.
nodes?AST node or nodes associated with this error.
source?Source document used to derive error locations.
positions?Character offsets in the source document associated with
+this error.
path?Response path where this error occurred during execution.
originalError?Original error that caused this GraphQLError, if one
+exists.
extensions?Extension fields to include in the formatted error.
+ +
+ +#### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
locationsAn array of {"{ line, column }"} locations within the source GraphQL document
+which correspond to this error.
+Errors during validation often contain multiple locations, for example to
+point out two things with the same name. Errors during execution include a
+single location, the field which produced the error.
+Enumerable, and appears in the result of JSON.stringify().
pathAn array describing the JSON-path into the execution response which
+corresponds to this error. Only included for errors during execution.
+Enumerable, and appears in the result of JSON.stringify().
nodesAn array of GraphQL AST Nodes corresponding to this error.
sourceThe source GraphQL document for the first location of this error.
+Note that if this Error represents more than one node, the source may not
+represent nodes after the first node.
positionsAn array of character offsets within the source GraphQL document
+which correspond to this error.
originalErrorOriginal error that caused this GraphQLError, if one exists.
extensionsExtension fields to add to the formatted error.
+ +
+ +#### toString() + +Returns this error as a human-readable message with source locations. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The formatted error string.
+ +
+ +
Example
+ +```ts +import { Source } from 'graphql/language'; +import { GraphQLError } from 'graphql/error'; + +const error = new GraphQLError('Cannot query field "name".', { + source: new Source('{ name }'), + positions: [2], +}); + +error.toString(); // => 'Cannot query field "name".\n\nGraphQL request:1:3\n1 | { name }\n | ^' ``` -## Overview - - - -## Errors - -### `GraphQLError` +
+ +#### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
```ts -class GraphQLError extends Error { - constructor( - message: string, - nodes?: any[], - stack?: string, - source?: Source, - positions?: number[], - originalError?: Error, - extensions?: Record, - ); -} +import { GraphQLError } from 'graphql/error'; + +const error = new GraphQLError('Resolver failed.', { + path: ['viewer', 'name'], + extensions: { code: 'INTERNAL' }, +}); + +error.toJSON(); // => { message: 'Resolver failed.', path: ['viewer', 'name'], extensions: { code: 'INTERNAL' } } ``` -A representation of an error that occurred within GraphQL. Contains -information about where in the query the error occurred for debugging. Most -commonly constructed with `locatedError` below. +## Functions + +### printError() Deprecated + +Prints a GraphQLError to a string, representing useful location information +about the error's position in the source. This deprecated helper is retained +for backwards compatibility; call `error.toString()` instead because +printError will be removed in v17. -### `syntaxError` +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
errorThe error to format.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The printed string representation.
+ +
+ +
Example
```ts -function syntaxError( - source: Source, - position: number, - description: string, -): GraphQLError; +import { GraphQLError, printError } from 'graphql/error'; + +const message = printError(new GraphQLError('Example error')); + +message; // => 'Example error' ``` -Produces a GraphQLError representing a syntax error, containing useful -descriptive information about the syntax error's position in the source. +
+ +### formatError() Deprecated + +Given a GraphQLError, format it according to the rules described by the +Response Format, Errors section of the GraphQL Specification. This deprecated +helper is retained for backwards compatibility; call `error.toJSON()` +instead because formatError will be removed in v17. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
errorThe error to format.
+ +
+ +
Returns
-### `locatedError` + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable formatted error.
+ +
+ +
Example
```ts -function locatedError(error: Error, nodes: any[]): GraphQLError; +import { GraphQLError, formatError } from 'graphql/error'; + +const formatted = formatError(new GraphQLError('Example error')); + +formatted; // => { message: 'Example error' } ``` -Given an arbitrary Error, presumably thrown while attempting to execute a +
+ +### locatedError() + +Given an arbitrary value, presumably thrown while attempting to execute a GraphQL operation, produce a new GraphQLError aware of the location in the document responsible for the original Error. -### `formatError` +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
rawOriginalErrorThe original error value to wrap.
nodesThe AST nodes associated with the error.
path?The response path associated with the error.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The GraphQL error.
+ +
+ +
Example
```ts -function formatError(error: GraphQLError): GraphQLFormattedError; +import { parse } from 'graphql/language'; +import { locatedError } from 'graphql/error'; -type GraphQLFormattedError = { - message: string; - locations: GraphQLErrorLocation[]; -}; +const document = parse('{ viewer { name } }'); +const fieldNode = document.definitions[0].selectionSet.selections[0]; +const error = locatedError(new Error('Resolver failed'), fieldNode, [ + 'viewer', +]); -type GraphQLErrorLocation = { - line: number; - column: number; -}; +error.message; // => 'Resolver failed' +error.locations; // => [{ line: 1, column: 3 }] +error.path; // => ['viewer'] ``` -Given a GraphQLError, format it according to the rules described by the -Response Format, Errors section of the GraphQL Specification. +
+ +### syntaxError() + +Produces a GraphQLError representing a syntax error, containing useful +descriptive information about the syntax error's position in the source. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourceThe GraphQL source containing the syntax error.
positionCharacter offset where the syntax error was encountered.
descriptionHuman-readable description of the syntax error.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A GraphQLError located at the syntax error position.
+ +
+ +
Example
+ +```ts +import { Source } from 'graphql/language'; +import { syntaxError } from 'graphql/error'; + +const error = syntaxError(new Source('query {'), 7, 'Expected Name'); + +error.message; // => 'Syntax Error: Expected Name' +error.locations; // => [{ line: 1, column: 8 }] +``` + +## Types + +### GraphQLErrorExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +### GraphQLFormattedErrorExtensions + +**Interface.** Custom formatted extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +### GraphQLErrorOptions + +**Interface.** Options used to construct a GraphQLError. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nodes?AST node or nodes associated with this error.
source?Source document used to derive error locations.
positions?Character offsets in the source document associated with this error.
path?Response path where this error occurred during execution.
originalError?Original error that caused this GraphQLError, if one exists.
extensions?Extension fields to include in the formatted result.
+ +
+ +### GraphQLFormattedError + +**Interface.** See: https://spec.graphql.org/draft/#sec-Errors + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
messageA short, human-readable summary of the problem that **SHOULD NOT** change
+from occurrence to occurrence of the problem, except for purposes of
+localization.
locations?If an error can be associated to a particular point in the requested
+GraphQL document, it should contain a list of locations.
path?If an error can be associated to a particular field in the GraphQL result,
+it _must_ contain an entry with the key {"path"} that details the path of
+the response field which experienced the error. This allows clients to
+identify whether a null result is intentional or caused by a runtime error.
extensions?Reserved for implementors to extend the protocol however they see fit,
+and hence there are no additional restrictions on its contents.
diff --git a/website/pages/api-v16/execution.mdx b/website/pages/api-v16/execution.mdx index c160797aa0..209075915c 100644 --- a/website/pages/api-v16/execution.mdx +++ b/website/pages/api-v16/execution.mdx @@ -1,151 +1,1236 @@ ---- -title: graphql/execution ---- +import { ApiSignature, ApiType } from '../../components/ApiCode'; -{/* title can be removed in Nextra 4, since sidebar title will take from first h1 */} +Execute GraphQL operations and produce GraphQL execution results. -# `graphql/execution` +These exports are also available from the root `graphql` package. -The `graphql/execution` module is responsible for the execution phase of -fulfilling a GraphQL request. You can import either from the `graphql/execution` module, or from the root `graphql` module. For example: +For documentation purposes, these exports are grouped into the following categories: -```js -import { execute } from 'graphql'; -``` +- [Execution](/api-v16/execution#category-execution) +- [Subscriptions](/api-v16/execution#category-subscriptions) +- [Values](/api-v16/execution#category-values) +- [Paths](/api-v16/execution#category-paths) + +## Category: Execution + +
+

+ Functions:
+ execute() + + executeSync() +

+

+ Constants:
+ defaultTypeResolver + + defaultFieldResolver +

+

+ Types:
+ ExecutionResult + + FormattedExecutionResult + + ExecutionArgs +

+
+ +### Functions + +#### execute() + +Implements the "Executing requests" section of the GraphQL specification. + +Returns either a synchronous ExecutionResult (if all encountered resolvers +are synchronous), or a Promise of an ExecutionResult that will eventually be +resolved and never rejected. + +If the arguments to this function do not result in a legal execution context, +a GraphQLError will be thrown immediately explaining the invalid input. + +Field errors are collected into the response instead of rejecting the +returned promise. Only the field that produced the error and its descendants +are omitted; sibling fields continue to execute. Errors from fields of +non-null type may propagate to the nearest nullable parent, which can be the +entire response data. + +**Signature:** + + + +
-## Overview +
Arguments
- + + + + + + + + + + + + + + + +
NameTypeDescription
argsThe arguments used to perform the operation.
-## Execution +
-### execute +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A completed execution result, or a promise resolving to one when execution is asynchronous.
+ +
+ +
Example 1
```ts -export function execute({ +// Execute an asynchronous operation with variables. +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { execute } from 'graphql/execution'; + +const schema = buildSchema(` + type Query { + greeting(name: String!): String + } +`); + +const result = await execute({ schema, - document - rootValue, - contextValue, - variableValues, - operationName, - options, -}: ExecutionParams): MaybePromise; - -type ExecutionParams = { - schema: GraphQLSchema; - document: Document; - rootValue?: unknown; - contextValue?: unknown; - variableValues?: Record; - operationName?: string; - options?: { - /** Set the maximum number of errors allowed for coercing (defaults to 50). */ - maxCoercionErrors?: number; + document: parse('query ($name: String!) { greeting(name: $name) }'), + rootValue: { + greeting: ({ name }) => `Hello, ${name}!`, + }, + variableValues: { name: 'Ada' }, +}); + +result; // => { data: { greeting: 'Hello, Ada!' } } +``` + +
+ +
Example 2
+ +```ts +// This variant supplies context plus custom field and type resolvers. +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { execute } from 'graphql/execution'; + +const schema = buildSchema(` + interface Named { + name: String! } -}; -type MaybePromise = Promise | T; + type User implements Named { + name: String! + } -interface ExecutionResult< - TData = ObjMap, - TExtensions = ObjMap, -> { - errors?: ReadonlyArray; - data?: TData | null; - extensions?: TExtensions; -} + type Query { + viewer: Named + } +`); + +const result = await execute({ + schema, + document: parse('query Viewer { viewer { __typename name } }'), + rootValue: { viewer: { kind: 'user', name: 'Ada' } }, + contextValue: { locale: 'en' }, + operationName: 'Viewer', + fieldResolver: (source, _args, contextValue, info) => { + contextValue.locale; // => 'en' + return source[info.fieldName]; + }, + typeResolver: (value) => { + return value.kind === 'user' ? 'User' : undefined; + }, +}); + +result; // => { data: { viewer: { __typename: 'User', name: 'Ada' } } } ``` -We have another approach with positional arguments, this is however deprecated and set -to be removed in v17. +
+ +
Example 3
```ts -export function execute( - schema: GraphQLSchema, - documentAST: Document, - rootValue?: unknown, - contextValue?: unknown, - variableValues?: Record, - operationName?: string, -): MaybePromise; +// This variant shows how resolver errors become field errors in the result. +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { execute } from 'graphql/execution'; + +const schema = buildSchema(` + type Query { + broken: String + } +`); +const document = parse('{ broken }'); + +const result = await execute({ + schema, + document, + rootValue: { + broken: () => { + throw new Error('Resolver failed.'); + }, + }, +}); + +result.data.broken; // => null +result.errors[0].message; // => 'Resolver failed.' ``` -Implements the "Evaluating requests" section of the GraphQL specification. +
-Returns a Promise that will eventually be resolved and never rejected. +
Example 4
-If the arguments to this function do not result in a legal execution context, -a GraphQLError will be thrown immediately explaining the invalid input. +```ts +// This variant limits how many variable coercion errors are reported. +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { execute } 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 result = await execute({ + schema, + document, + variableValues: { + first: { stars: 'bad' }, + second: { stars: 'also bad' }, + }, + options: { maxCoercionErrors: 1 }, +}); + +result.errors.length; // => 2 +result.errors[1].message; // matches /error limit reached/ +``` -`ExecutionResult` represents the result of execution. `data` is the result of -executing the query, `errors` is null if no errors occurred, and is a -non-empty array if an error occurred. +
-### executeSync +#### executeSync() -This is a short-hand method that will call `execute` and when the response can -be returned synchronously it will be returned, when a `Promise` is returned this -method will throw an error. +Also implements the "Executing requests" section of the GraphQL specification. +However, it guarantees to complete synchronously (or throw an error) assuming +that all field resolvers are also synchronous. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
argsThe arguments used to perform the operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Completed execution output for a synchronous operation.
+ +
+ +
Example 1
```ts -export function executeSync({ +// Execute an operation synchronously when all resolvers are synchronous. +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { executeSync } from 'graphql/execution'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse('{ greeting }'); + +const result = executeSync({ schema, document, - rootValue, - contextValue, - variableValues, - operationName, - options, -}: ExecutionParams): MaybePromise; - -type ExecutionParams = { - schema: GraphQLSchema; - document: Document; - rootValue?: unknown; - contextValue?: unknown; - variableValues?: Record; - operationName?: string; - options?: { - /** Set the maximum number of errors allowed for coercing (defaults to 50). */ - maxCoercionErrors?: number; + rootValue: { + greeting: 'Hello', + }, +}); + +result; // => { data: { greeting: 'Hello' } } +``` + +
+ +
Example 2
+ +```ts +// This variant shows executeSync throwing when a resolver returns a promise. +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { executeSync } from 'graphql/execution'; + +const schema = buildSchema(` + type Query { + greeting: String } -}; +`); + +executeSync({ + schema, + document: parse('{ greeting }'), + rootValue: { + greeting: async () => 'Hello', + }, +}); // throws an error +``` + +### Constants + +#### defaultTypeResolver + +If a resolveType function is not given, then a default resolve behavior is +used which attempts two strategies: + +First, See if the provided value has a `__typename` field defined, if so, use +that value as name of the resolved type. + +Otherwise, test each possible type for the abstract type by calling +isTypeOf for the object being coerced, returning the first type that matches. + +
+ +
Type
+ + + +
+ +#### defaultFieldResolver + +If a resolve function is not given, then a default resolve behavior is used +which takes the property of the source object of the same name as the field +and returns it as the result, or if it's a function, returns the result +of calling that function while passing along args and context value. + +
+ +
Type
+ + + +### Types + +#### ExecutionResult + +**Interface.** Represents the response produced by executing a GraphQL operation. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TDataShape of the execution data payload.
TExtensionsShape of the extensions payload.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
errors?Errors raised while parsing, validating, or executing the operation.
data?Data returned by execution, or null when execution could not produce data.
extensions?Extension fields to include in the formatted result.
+ +
+ +#### FormattedExecutionResult + +**Interface.** A JSON-serializable GraphQL execution result. + +
+ +
Type Parameters
-type MaybePromise = Promise | T; + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TDataShape of the formatted data payload.
TExtensionsShape of the formatted extensions payload.
-interface ExecutionResult< - TData = ObjMap, - TExtensions = ObjMap, -> { - errors?: ReadonlyArray; - data?: TData | null; - extensions?: TExtensions; +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
errors?Errors raised while parsing, validating, or executing the operation.
data?Data returned by execution, or null when execution could not produce data.
extensions?Extension fields to include in the formatted result.
+ +
+ +#### ExecutionArgs + +**Interface.** Arguments accepted by execute and executeSync. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaThe schema used for validation or execution.
documentThe parsed GraphQL document to execute.
rootValue?Initial root value passed to the operation.
contextValue?Application context value passed to every resolver.
variableValues?Runtime variable values keyed by variable name.
operationName?Name of the operation to execute when the document contains multiple operations.
fieldResolver?Resolver used when a field does not define its own resolver.
typeResolver?Resolver used when an abstract type does not define its own resolver.
subscribeFieldResolver?Resolver used for the root subscription field.
options?Additional execution options.
+ +## Category: Subscriptions + +
+

+ Functions:
+ subscribe() +

+
+ +### Functions + +#### subscribe() + +Implements the "Subscribe" algorithm described in the GraphQL specification. + +Returns a Promise that resolves to either an AsyncIterator (if successful) +or an ExecutionResult (error). The promise will be rejected if the schema or +other arguments to this function are invalid, or if the resolved event stream +is not an async iterable. + +If the client-provided arguments to this function do not result in a +compliant subscription, a GraphQL Response (ExecutionResult) with +descriptive errors and no data will be returned. + +If the source stream could not be created due to faulty subscription +resolver logic or underlying systems, the promise will resolve to a single +ExecutionResult containing `errors` and no `data`. + +If the operation succeeded, the promise resolves to an AsyncIterator, which +yields a stream of ExecutionResults representing the response stream. + +Each payload yielded by the source event stream is executed with the payload +as the root value. This maps the subscription source stream into the response +stream described by the GraphQL specification. + +Accepts an object with named arguments. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
argsThe arguments used to perform the operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A source stream mapped to execution results, or an execution result
+containing subscription errors.
+ +
+ +
Example 1
+ +```ts +// Use a same-named rootValue function to provide the source event stream. +import assert from 'node:assert'; +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { subscribe } from 'graphql/execution'; + +async function* greetings() { + yield { greeting: 'Hello' }; + yield { greeting: 'Bonjour' }; } + +const schema = buildSchema(` + type Query { + noop: String + } + + type Subscription { + greeting: String + } +`); + +const result = await subscribe({ + schema, + document: parse('subscription { greeting }'), + rootValue: { greeting: () => greetings() }, +}); + +assert('next' in result); + +const firstPayload = await result.next(); +firstPayload.value; // => { data: { greeting: 'Hello' } } +``` + +
+ +
Example 2
+ +```ts +// This variant supplies events through a custom subscribeFieldResolver. +import assert from 'node:assert'; +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { subscribe } from 'graphql/execution'; + +async function* defaultGreetings() { + yield { greeting: 'Hello' }; +} + +async function* frenchGreetings() { + yield { greeting: 'Bonjour' }; +} + +const schema = buildSchema(` + type Query { + noop: String + } + + type Subscription { + greeting(locale: String): String + } +`); + +const result = await subscribe({ + schema, + document: parse( + 'subscription Greeting($locale: String) { greeting(locale: $locale) }', + ), + rootValue: { + greeting: (args, contextValue) => { + const locale = args.locale ?? contextValue.defaultLocale; + return locale === 'fr' ? frenchGreetings() : defaultGreetings(); + }, + }, + contextValue: { defaultLocale: 'fr' }, + variableValues: { locale: 'fr' }, + operationName: 'Greeting', + subscribeFieldResolver: (rootValue, args, contextValue, info) => { + args.locale; // => 'fr' + return rootValue[info.fieldName](args, contextValue); + }, +}); + +assert('next' in result); + +const firstPayload = await result.next(); +firstPayload.value; // => { data: { greeting: 'Bonjour' } } +``` + +
+ +
Example 3
+ +```ts +// This variant shows the error result when the schema has no subscription root. +import assert from 'node:assert'; +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { subscribe } from 'graphql/execution'; + +const schema = buildSchema(` + type Query { + noop: String + } +`); + +const result = await subscribe({ + schema, + document: parse('subscription { greeting }'), +}); + +assert('errors' in result); + +result.errors[0].message; // => 'Schema is not configured to execute subscription operation.' +``` + +## Category: Values + + + +### Functions + +#### getVariableValues() + +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 value is a plain Object with a prototype, since it is +exposed to user code. Care should be taken to not pull values from the +Object prototype. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
varDefNodesThe variable definition AST nodes to coerce.
inputsThe runtime variable values keyed by variable name.
options?Optional variable coercion options, including error limits.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Coerced variable values, or request errors.
+ +
+ +
Example 1
+ +```ts +// Coerce provided variables and apply operation defaults. +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' }, +); + +result; // => { coerced: { stars: 5, limit: 10 } } +``` + +
+ +
Example 2
+ +```ts +// This variant uses maxErrors to cap reported coercion errors. +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 }, +); + +result.errors.length; // => 2 +result.errors[1].message; // matches /error limit reached/ +``` + +
+ +#### getArgumentValues() + +Prepares an object map of argument values given a list of argument +definitions and list of argument AST nodes. + +Note: Returned value is a plain Object with a prototype, since it is +exposed to user code. Care should be taken to not pull values from the +Object prototype. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
defThe field or directive definition whose arguments should be coerced.
nodeThe AST node to inspect.
variableValues?The runtime variable values keyed by variable name.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Coerced argument values keyed by argument name.
+ +
+ +
Example 1
+ +```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 2
+ +```ts +// This variant resolves argument values from operation variables. +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { getArgumentValues } 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 fieldNode = document.definitions[0].selectionSet.selections[0]; + +getArgumentValues(fieldDef, fieldNode, { stars: 5 }); // => { stars: 5 } +getArgumentValues(fieldDef, fieldNode, {}); // throws an error +``` + +
+ +#### getDirectiveValues() + +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 is a plain Object with a prototype, since it is +exposed to user code. Care should be taken to not pull values from the +Object prototype. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
directiveDefThe directive definition whose arguments should be coerced.
nodeThe AST node to inspect.
variableValues?The runtime variable values keyed by variable name.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Coerced directive argument values keyed by argument name.
+ +
+ +
Example 1
+ +```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 } ``` -We have another approach with positional arguments, this is however deprecated and set -to be removed in v17. +
+ +
Example 2
```ts -export function executeSync( - schema: GraphQLSchema, - documentAST: Document, - rootValue?: unknown, - contextValue?: unknown, - variableValues?: Record, - operationName?: string, -): ExecutionResult; +// This variant resolves directive arguments from variables and handles absent directives. +import { parse } from 'graphql/language'; +import { GraphQLIncludeDirective } from 'graphql/type'; +import { getDirectiveValues } from 'graphql/execution'; + +const document = parse('query ($includeName: Boolean!) { name @include(if: $includeName) }'); +const fieldNode = document.definitions[0].selectionSet.selections[0]; + +getDirectiveValues(GraphQLIncludeDirective, fieldNode, { + includeName: false, +}); // => { if: false } +getDirectiveValues(GraphQLIncludeDirective, { directives: [] }); // => undefined ``` -#### Execution options +## Category: Paths + +
+

+ Functions:
+ responsePathAsArray() +

+
-##### maxCoercionErrors +### Functions -Set the maximum number of errors allowed for coercing variables, this implements a default limit of 50 errors. +#### responsePathAsArray() + +Given a Path, return an Array of the path keys. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
pathThe linked response path to flatten.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
An array of response path keys from root to leaf.
+ +
+ +
Example
+ +```ts +import { pathToArray } from 'graphql/jsutils/Path'; + +const path = { + prev: { + prev: { + prev: undefined, + key: 'viewer', + typename: 'Query', + }, + key: 'friends', + typename: 'User', + }, + key: 0, + typename: undefined, +}; + +pathToArray(path); // => ['viewer', 'friends', 0] +pathToArray(undefined); // => [] +``` diff --git a/website/pages/api-v16/execution/_meta.ts b/website/pages/api-v16/execution/_meta.ts new file mode 100644 index 0000000000..ac1780ab61 --- /dev/null +++ b/website/pages/api-v16/execution/_meta.ts @@ -0,0 +1,20 @@ +const meta = { + execution: { + title: 'Category: Execution', + href: '/api-v16/execution#category-execution', + }, + subscriptions: { + title: 'Category: Subscriptions', + href: '/api-v16/execution#category-subscriptions', + }, + values: { + title: 'Category: Values', + href: '/api-v16/execution#category-values', + }, + paths: { + title: 'Category: Paths', + href: '/api-v16/execution#category-paths', + }, +}; + +export default meta; diff --git a/website/pages/api-v16/graphql-http.mdx b/website/pages/api-v16/graphql-http.mdx deleted file mode 100644 index 9b8285cd6c..0000000000 --- a/website/pages/api-v16/graphql-http.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: graphql-http ---- - -{/* title can be removed in Nextra 4, since sidebar title will take from first h1 */} - -# `graphql-http` - -The [official `graphql-http` package](https://github.com/graphql/graphql-http) provides a simple way to create a fully compliant GraphQL server. It has a handler for Node.js native [`http`](https://nodejs.org/api/http.html), together with handlers for well-known frameworks like [Express](https://expressjs.com/), [Fastify](https://www.fastify.io/) and [Koa](https://koajs.com/); as well as handlers for different runtimes like [Deno](https://deno.land/) and [Bun](https://bun.sh/). - -## Express - -```js -import { createHandler } from 'graphql-http/lib/use/express'; -``` - -### createHandler - -```ts -function createHandler({ - schema, - rootValue, - context, - formatError, - validationRules, -}: { - rootValue?: any; - context?: any; - formatError?: Function; - validationRules?: any[]; -}): Handler; -``` - -Constructs an Express handler based on a GraphQL schema. - -See the [tutorial](/running-an-express-graphql-server/) for sample usage. - -See the [GitHub README](https://github.com/graphql/graphql-http) for more extensive documentation, including how to use `graphql-http` with other server frameworks and runtimes. diff --git a/website/pages/api-v16/graphql.mdx b/website/pages/api-v16/graphql.mdx index 2c736c87ff..554c6cdd32 100644 --- a/website/pages/api-v16/graphql.mdx +++ b/website/pages/api-v16/graphql.mdx @@ -1,180 +1,381 @@ ---- -title: graphql ---- +import { ApiSignature, ApiType } from '../../components/ApiCode'; -{/* title can be removed in Nextra 4, since sidebar title will take from first h1 */} +The root `graphql` package re-exports the public GraphQL.js API from its +submodules and provides the high-level request pipeline helpers defined in +this module. -# `graphql` +You can import public exports from GraphQL.js modules through the root +`graphql` package or through their module-specific entry point. For example, +these two references resolve to the same [`parse`](/api-v16/language#parse) function: -The `graphql` module exports a core subset of GraphQL functionality for creation -of GraphQL type systems and servers. +```ts +import { parse } from 'graphql'; +import { parse } from 'graphql/language'; +``` + +Use the root package when you want a single import surface, or use submodules +such as `graphql/language`, `graphql/type`, `graphql/execution`, and +`graphql/utilities` when you want module-focused imports. This module also +defines root-only APIs, such as request pipeline helpers and version +metadata, that do not belong to a narrower submodule. + +For documentation purposes, these exports are grouped into the following categories: + +- [Request Pipeline](/api-v16/graphql#category-request-pipeline) +- [Version](/api-v16/graphql#category-version) + +## Category: Request Pipeline + +
+

+ Functions:
+ graphql() + + graphqlSync() +

+

+ Types:
+ GraphQLArgs +

+
+ +### Functions + +#### graphql() + +Parses, validates, and executes a GraphQL document against a schema. + +This is the primary entry point for fulfilling GraphQL operations. Use this +when you want a single-call request lifecycle that returns a promise in all +cases. + +More sophisticated GraphQL servers, such as those which persist queries, may +wish to separate the validation and execution phases to a static-time tooling +step and a server runtime step. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
argsRequest execution arguments, including schema and source.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A promise that resolves to an execution result or validation errors.
+ +
+ +
Example 1
+ +```ts +// Execute a complete asynchronous request with variables. +import { graphql, buildSchema } from 'graphql'; + +const schema = buildSchema(` + type Query { + greeting(name: String!): String + } +`); + +const result = await graphql({ + schema, + source: 'query SayHello($name: String!) { greeting(name: $name) }', + rootValue: { + greeting: ({ name }) => `Hello, ${name}!`, + }, + variableValues: { name: 'Ada' }, + operationName: 'SayHello', +}); + +result; // => { data: { greeting: 'Hello, Ada!' } } +``` + +
+ +
Example 2
+ +```ts +// This variant supplies context plus custom field and type resolvers. +import { graphql, buildSchema } from 'graphql'; + +const schema = buildSchema(` + interface Named { + name: String! + } + + type User implements Named { + name: String! + } + + type Query { + viewer: Named + } +`); + +const result = await graphql({ + schema, + source: '{ viewer { __typename name } }', + rootValue: { viewer: { kind: 'user', name: 'Ada' } }, + contextValue: { locale: 'en' }, + fieldResolver: (source, _args, context, info) => { + context.locale; // => 'en' + return source[info.fieldName]; + }, + typeResolver: (value) => { + return value.kind === 'user' ? 'User' : undefined; + }, +}); -```js -import { graphql } from 'graphql'; +result; // => { data: { viewer: { __typename: 'User', name: 'Ada' } } } ``` -## Overview - -### Entry Point - - - -### Schema - - - -### Type Definitions - - - -### Scalars - - - -### Errors - - - -## Entry Point - -### `graphql` +
+ +#### graphqlSync() + +Parses, validates, and executes a GraphQL document synchronously. + +This function guarantees that execution completes synchronously, or throws an +error, assuming that all field resolvers are also synchronous. It throws when +any resolver returns a promise. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
argsRequest execution arguments, including schema and source.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Completed execution output, or request errors if parsing or
+validation fails.
+ +
+ +
Example 1
+ +```ts +// Execute a complete synchronous request with variables. +import { graphqlSync, buildSchema } from 'graphql'; + +const schema = buildSchema(` + type Query { + greeting(name: String!): String + } +`); + +const result = graphqlSync({ + schema, + source: 'query SayHello($name: String!) { greeting(name: $name) }', + rootValue: { + greeting: ({ name }) => `Hello, ${name}!`, + }, + variableValues: { name: 'Ada' }, + operationName: 'SayHello', +}); + +result; // => { data: { greeting: 'Hello, Ada!' } } +``` + +
+ +
Example 2
```ts -function graphql( - schema: GraphQLSchema, - requestString: string, - rootValue?: any, - contextValue?: any, - variableValues?: { [key: string]: any }, - operationName?: string, -): Promise; - -interface ExecutionResult< - TData = ObjMap, - TExtensions = ObjMap, -> { - errors?: ReadonlyArray; - data?: TData | null; - extensions?: TExtensions; -} +// This variant uses a synchronous custom field resolver and context. +import { graphqlSync, buildSchema } from 'graphql'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); + +const result = graphqlSync({ + schema, + source: '{ greeting }', + fieldResolver: (_source, _args, contextValue) => { + return contextValue.defaultGreeting; + }, + contextValue: { defaultGreeting: 'Hello' }, +}); + +result; // => { data: { greeting: 'Hello' } } ``` -The `graphql` function lexes, parses, validates and executes a GraphQL request. -It requires a `schema` and a `requestString`. Optional arguments include a -`rootValue`, which will get passed as the root value to the executor, a `contextValue`, -which will get passed to all resolve functions, -`variableValues`, which will get passed to the executor to provide values for -any variables in `requestString`, and `operationName`, which allows the caller -to specify which operation in `requestString` will be run, in cases where -`requestString` contains multiple top-level operations. +### Types + +#### GraphQLArgs + +**Interface.** Describes the input object accepted by `graphql` and [`graphqlSync`](/api-v16/graphql#graphqlsync). + +These arguments describe the full parse, validate, and execute lifecycle for +a GraphQL request. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaThe GraphQL type system to use when validating and executing a query.
sourceA GraphQL language-formatted string or source object representing the
+requested operation.
rootValue?The value provided as the first argument to resolver functions on the top
+level type, such as the query object type.
contextValue?Application context value passed to every resolver.
+Use this for shared request data such as the currently logged in user and
+connections to databases or other services.
variableValues?A mapping of variable name to runtime value for variables defined by the operation.
operationName?The operation to execute when the source contains multiple possible
+operations. This can be omitted when the source contains only one operation.
fieldResolver?A resolver function to use when one is not provided by the schema.
+If not provided, the default field resolver is used, which looks for a value
+or method on the source value with the field's name.
typeResolver?A type resolver function to use when none is provided by the schema.
+If not provided, the default type resolver is used, which looks for a
+{"__typename"} field or alternatively calls the {"isTypeOf"} method.
+ +## Category: Version + +
+

+ Constants:
+ version + + versionInfo +

+
+ +### Constants + +#### version + +A string containing the version of the GraphQL.js library + +
-## Schema +
Type
-See the [Type System API Reference](/type#schema). + -## Type Definitions +
-See the [Type System API Reference](/type#definitions). +#### versionInfo -## Scalars +An object containing the components of the GraphQL.js version string -See the [Type System API Reference](/type#scalars). +
-## Errors +
Type
-See the [Errors API Reference](/error) + diff --git a/website/pages/api-v16/graphql/_meta.ts b/website/pages/api-v16/graphql/_meta.ts new file mode 100644 index 0000000000..447d5114f1 --- /dev/null +++ b/website/pages/api-v16/graphql/_meta.ts @@ -0,0 +1,12 @@ +const meta = { + 'request-pipeline': { + title: 'Category: Request Pipeline', + href: '/api-v16/graphql#category-request-pipeline', + }, + version: { + title: 'Category: Version', + href: '/api-v16/graphql#category-version', + }, +}; + +export default meta; diff --git a/website/pages/api-v16/language.mdx b/website/pages/api-v16/language.mdx index fa9587fe0b..342bfe023b 100644 --- a/website/pages/api-v16/language.mdx +++ b/website/pages/api-v16/language.mdx @@ -1,277 +1,5718 @@ ---- -title: graphql/language ---- +import { ApiSignature, ApiType } from '../../components/ApiCode'; -{/* title can be removed in Nextra 4, since sidebar title will take from first h1 */} +Parse, print, and visit GraphQL language source files and AST nodes. -# `graphql/language` +These exports are also available from the root `graphql` package. -The `graphql/language` module is responsible for parsing and operating on the GraphQL language. You can import either from the `graphql/language` module, or from the root `graphql` module. For example: +For documentation purposes, these exports are grouped into the following categories: -```js -import { Source } from 'graphql'; +- [AST](/api-v16/language#category-ast) +- [Kinds](/api-v16/language#category-kinds) +- [Lexing](/api-v16/language#category-lexing) +- [Source](/api-v16/language#category-source) +- [Parsing](/api-v16/language#category-parsing) +- [AST Predicates](/api-v16/language#category-ast-predicates) +- [Printing](/api-v16/language#category-printing) +- [Visiting](/api-v16/language#category-visiting) + +## Category: AST + +
+

+ Classes:
+ Location + + Token +

+

+ Types:
+ ASTNode + + ASTKindToNode + + NameNode + + DocumentNode + + DefinitionNode + + ExecutableDefinitionNode + + OperationDefinitionNode + + VariableDefinitionNode + + VariableNode + + SelectionSetNode + + SelectionNode + + FieldNode + + ArgumentNode + + ConstArgumentNode + + FragmentSpreadNode + + InlineFragmentNode + + FragmentDefinitionNode + + ValueNode + + ConstValueNode + + IntValueNode + + FloatValueNode + + StringValueNode + + BooleanValueNode + + NullValueNode + + EnumValueNode + + ListValueNode + + ConstListValueNode + + ObjectValueNode + + ConstObjectValueNode + + ObjectFieldNode + + ConstObjectFieldNode + + DirectiveNode + + ConstDirectiveNode + + TypeNode + + NamedTypeNode + + ListTypeNode + + NonNullTypeNode + + TypeSystemDefinitionNode + + SchemaDefinitionNode + + OperationTypeDefinitionNode + + TypeDefinitionNode + + ScalarTypeDefinitionNode + + ObjectTypeDefinitionNode + + FieldDefinitionNode + + InputValueDefinitionNode + + InterfaceTypeDefinitionNode + + UnionTypeDefinitionNode + + EnumTypeDefinitionNode + + EnumValueDefinitionNode + + InputObjectTypeDefinitionNode + + DirectiveDefinitionNode + + TypeSystemExtensionNode + + SchemaExtensionNode + + TypeExtensionNode + + ScalarTypeExtensionNode + + ObjectTypeExtensionNode + + InterfaceTypeExtensionNode + + UnionTypeExtensionNode + + EnumTypeExtensionNode + + InputObjectTypeExtensionNode + + DirectiveExtensionNode + + SchemaCoordinateNode + + TypeCoordinateNode + + MemberCoordinateNode + + ArgumentCoordinateNode + + DirectiveCoordinateNode + + DirectiveArgumentCoordinateNode +

+
+ +### Classes + +#### Location + +Contains a range of UTF-8 character offsets and token references that +identify the region of the source from which the AST derived. + +
+ +##### Constructor + +Creates a Location instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
startTokenThe start token.
endTokenThe end token.
sourceSource document used to derive error locations.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
startThe character offset at which this Node begins.
endThe character offset at which this Node ends.
startTokenThe Token at which this Node begins.
endTokenThe Token at which this Node ends.
sourceThe Source document the AST represents.
+ +
+ +##### toJSON() + +Returns a JSON representation of this location. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; + +const document = parse('{ hello }'); +const location = document.loc?.toJSON(); + +location; // => { start: 0, end: 9 } +``` + +
+ +#### Token + +Represents a range of characters represented by a lexical token +within a Source. + +
+ +##### Constructor + +Creates a Token instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindToken kind produced by lexical analysis.
startCharacter offset where this token begins.
endCharacter offset where this token ends.
lineOne-indexed line number where this token begins.
columnOne-indexed column number where this token begins.
value?Interpreted value for non-punctuation tokens.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe kind of Token.
startThe character offset at which this Node begins.
endThe character offset at which this Node ends.
lineThe 1-indexed line number on which this Token appears.
columnThe 1-indexed column number at which this Token begins.
valueFor non-punctuation tokens, represents the interpreted value of the token.
+Note: is undefined for punctuation tokens, but typed as string for
+convenience in the parser.
prevTokens exist as nodes in a double-linked-list amongst all tokens
+including ignored tokens. <SOF> is always the first node and <EOF>
+the last.
nextNext token in the token stream, including ignored tokens.
+ +
+ +##### toJSON() + +Returns a JSON representation of this token. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { Lexer, Source } from 'graphql/language'; + +const lexer = new Lexer(new Source('{ hello }')); +const token = lexer.advance().toJSON(); + +token; // => { kind: '{', value: undefined, line: 1, column: 1 } +``` + +### Types + +#### ASTNode + +**Type alias.** The list of all possible AST node types. + + + +
+ +#### ASTKindToNode + +**Type alias.** Utility type listing all nodes indexed by their kind. + + + +
+ +#### NameNode + +**Interface.** An identifier in a GraphQL document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
valueParsed value represented by this node.
+ +
+ +#### DocumentNode + +**Interface.** The root AST node for a parsed GraphQL document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
definitionsTop-level executable and type-system definitions in this document.
tokenCount?The number of lexical tokens parsed for this document, if token counting was enabled.
+ +
+ +#### DefinitionNode + +**Type alias.** Any top-level definition that may appear in a GraphQL document. + + + +
+ +#### ExecutableDefinitionNode + +**Type alias.** Any executable definition that may appear in an operation document. + + + +
+ +#### OperationDefinitionNode + +**Interface.** A query, mutation, or subscription operation definition. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
description?The optional GraphQL description associated with this definition.
loc?The source location for this AST node, if location tracking was enabled.
operationThe operation selected for execution.
name?Name node identifying this AST node.
variableDefinitions?Variable definitions declared by this operation or fragment.
directives?Directives available in this schema or applied to this AST node.
selectionSetSelections made by this operation, field, or fragment.
+ +
+ +#### VariableDefinitionNode + +**Interface.** A variable declaration in an operation or legacy fragment definition. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
description?The optional GraphQL description associated with this definition.
loc?The source location for this AST node, if location tracking was enabled.
variableThe variable being defined or referenced.
typeThe GraphQL type reference or runtime type for this element.
defaultValue?Default value used when no explicit value is supplied.
directives?Directives available in this schema or applied to this AST node.
+ +
+ +#### VariableNode + +**Interface.** A variable reference, such as `$id`. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
+ +
+ +#### SelectionSetNode + +**Interface.** A set of fields and fragments selected from an object, interface, or union. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
selectionsFields and fragments contained in this selection set.
+ +
+ +#### SelectionNode + +**Type alias.** Any selection that may appear inside a selection set. + + + +
+ +#### FieldNode + +**Interface.** A field selected in an executable GraphQL document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
alias?The response-key alias for this field, if one was supplied.
nameName node identifying this AST node.
arguments?Arguments supplied to this field, directive, or coordinate.
directives?Directives available in this schema or applied to this AST node.
selectionSet?Selections made by this operation, field, or fragment.
+ +
+ +#### ArgumentNode + +**Interface.** An argument supplied to a field or directive. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
valueParsed value represented by this node.
+ +
+ +#### ConstArgumentNode + +**Interface.** An argument node whose value is guaranteed to be constant. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
valueParsed value represented by this node.
+ +
+ +#### FragmentSpreadNode + +**Interface.** A named fragment spread, such as `...userFields`. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
+ +
+ +#### InlineFragmentNode + +**Interface.** An inline fragment spread with an optional type condition. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
typeCondition?The type condition that limits where this fragment applies.
directives?Directives available in this schema or applied to this AST node.
selectionSetSelections made by this operation, field, or fragment.
+ +
+ +#### FragmentDefinitionNode + +**Interface.** A reusable fragment definition declared in an executable document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
description?The optional GraphQL description associated with this definition.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
variableDefinitions?Deprecated variable definitions declared by this legacy fragment
+definition. This legacy fragment variable syntax will be removed in v17.
+Move variable definitions to operations for spec-compliant documents; if
+you need variables or arguments scoped to fragments, v17 has a more
+complete experimental fragment-arguments feature.
typeConditionThe type condition that limits where this fragment applies.
directives?Directives available in this schema or applied to this AST node.
selectionSetSelections made by this operation, field, or fragment.
+ +
+ +#### ValueNode + +**Type alias.** Any value literal that may appear in an executable GraphQL document. + + + +
+ +#### ConstValueNode + +**Type alias.** Any value literal that is guaranteed not to contain a variable reference. + + + +
+ +#### IntValueNode + +**Interface.** An integer value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
valueParsed value represented by this node.
+ +
+ +#### FloatValueNode + +**Interface.** A floating-point value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
valueParsed value represented by this node.
+ +
+ +#### StringValueNode + +**Interface.** A string value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
valueParsed value represented by this node.
block?Whether this string was parsed from block string syntax.
+ +
+ +#### BooleanValueNode + +**Interface.** A boolean value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
valueParsed value represented by this node.
+ +
+ +#### NullValueNode + +**Interface.** A null value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
+ +
+ +#### EnumValueNode + +**Interface.** An enum value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
valueParsed value represented by this node.
+ +
+ +#### ListValueNode + +**Interface.** A list value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
valuesValues contained in this enum, list, or input-object definition.
+ +
+ +#### ConstListValueNode + +**Interface.** A list value literal whose elements are all constant values. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
valuesValues contained in this enum, list, or input-object definition.
+ +
+ +#### ObjectValueNode + +**Interface.** An input object value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
fieldsFields declared by this object, interface, input object, or literal.
+ +
+ +#### ConstObjectValueNode + +**Interface.** An input object value literal whose fields are all constant values. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
fieldsFields declared by this object, interface, input object, or literal.
+ +
+ +#### ObjectFieldNode + +**Interface.** A field inside an input object value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
valueParsed value represented by this node.
+ +
+ +#### ConstObjectFieldNode + +**Interface.** A field inside a constant input object value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
valueParsed value represented by this node.
+ +
+ +#### DirectiveNode + +**Interface.** A directive applied to an executable or type-system location. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
arguments?Arguments supplied to this field, directive, or coordinate.
+ +
+ +#### ConstDirectiveNode + +**Interface.** A directive whose arguments are all constant values. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
arguments?Arguments supplied to this field, directive, or coordinate.
+ +
+ +#### TypeNode + +**Type alias.** Any GraphQL type reference AST node. + + + +
+ +#### NamedTypeNode + +**Interface.** A named type reference. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
+ +
+ +#### ListTypeNode + +**Interface.** A list type reference. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
typeThe GraphQL type reference or runtime type for this element.
+ +
+ +#### NonNullTypeNode + +**Interface.** A non-null type reference. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
typeThe GraphQL type reference or runtime type for this element.
+ +
+ +#### TypeSystemDefinitionNode + +**Type alias.** Any type-system definition that may appear in a schema document. + + + +
+ +#### SchemaDefinitionNode + +**Interface.** A schema definition in a type-system document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
directives?Directives available in this schema or applied to this AST node.
operationTypesRoot operation types declared by this schema definition or extension.
+ +
+ +#### OperationTypeDefinitionNode + +**Interface.** A root operation type declaration inside a schema definition or extension. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
operationThe operation selected for execution.
typeThe GraphQL type reference or runtime type for this element.
+ +
+ +#### TypeDefinitionNode + +**Type alias.** Any named type definition that may appear in a schema document. + + + +
+ +#### ScalarTypeDefinitionNode + +**Interface.** A scalar type definition in a type-system document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
+ +
+ +#### ObjectTypeDefinitionNode + +**Interface.** An object type definition in a type-system document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
interfaces?Interfaces implemented by this object or interface type.
directives?Directives available in this schema or applied to this AST node.
fields?Fields declared by this object, interface, input object, or literal.
+ +
+ +#### FieldDefinitionNode + +**Interface.** A field definition declared by an object or interface type. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
arguments?Arguments supplied to this field, directive, or coordinate.
typeThe GraphQL type reference or runtime type for this element.
directives?Directives available in this schema or applied to this AST node.
+ +
+ +#### InputValueDefinitionNode + +**Interface.** An argument or input-field definition. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
typeThe GraphQL type reference or runtime type for this element.
defaultValue?Default value used when no explicit value is supplied.
directives?Directives available in this schema or applied to this AST node.
+ +
+ +#### InterfaceTypeDefinitionNode + +**Interface.** An interface type definition in a type-system document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
interfaces?Interfaces implemented by this object or interface type.
directives?Directives available in this schema or applied to this AST node.
fields?Fields declared by this object, interface, input object, or literal.
+ +
+ +#### UnionTypeDefinitionNode + +**Interface.** A union type definition in a type-system document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
types?Object types that belong to this union type.
+ +
+ +#### EnumTypeDefinitionNode + +**Interface.** An enum type definition in a type-system document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
values?Values contained in this enum, list, or input-object definition.
+ +
+ +#### EnumValueDefinitionNode + +**Interface.** An enum value definition. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
+ +
+ +#### InputObjectTypeDefinitionNode + +**Interface.** An input object type definition in a type-system document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
fields?Fields declared by this object, interface, input object, or literal.
+ +
+ +#### DirectiveDefinitionNode + +**Interface.** A directive definition in a type-system document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
arguments?Arguments supplied to this field, directive, or coordinate.
directives?Directives available in this schema or applied to this AST node.
repeatableWhether this directive may appear more than once at the same location.
locationsLocations where this directive may be applied.
+ +
+ +#### TypeSystemExtensionNode + +**Type alias.** Any type-system extension that may appear in a schema extension document. + + + +
+ +#### SchemaExtensionNode + +**Interface.** A schema extension in a type-system document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
directives?Directives available in this schema or applied to this AST node.
operationTypes?Root operation types declared by this schema definition or extension.
+ +
+ +#### TypeExtensionNode + +**Type alias.** Any named type extension that may appear in a schema extension document. + + + +
+ +#### ScalarTypeExtensionNode + +**Interface.** A scalar type extension. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
+ +
+ +#### ObjectTypeExtensionNode + +**Interface.** An object type extension. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
interfaces?Interfaces implemented by this object or interface type.
directives?Directives available in this schema or applied to this AST node.
fields?Fields declared by this object, interface, input object, or literal.
+ +
+ +#### InterfaceTypeExtensionNode + +**Interface.** An interface type extension. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
interfaces?Interfaces implemented by this object or interface type.
directives?Directives available in this schema or applied to this AST node.
fields?Fields declared by this object, interface, input object, or literal.
+ +
+ +#### UnionTypeExtensionNode + +**Interface.** A union type extension. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
types?Object types that belong to this union type.
+ +
+ +#### EnumTypeExtensionNode + +**Interface.** An enum type extension. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
values?Values contained in this enum, list, or input-object definition.
+ +
+ +#### InputObjectTypeExtensionNode + +**Interface.** An input object type extension. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
fields?Fields declared by this object, interface, input object, or literal.
+ +
+ +#### DirectiveExtensionNode + +**Interface.** A directive extension. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
+ +
+ +#### SchemaCoordinateNode + +**Type alias.** Any AST node representing a GraphQL schema coordinate. + + + +
+ +#### TypeCoordinateNode + +**Interface.** A schema coordinate that refers to a named type. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
+ +
+ +#### MemberCoordinateNode + +**Interface.** A schema coordinate that refers to a member of a named type. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
memberNameThe member name referenced by this schema coordinate.
+ +
+ +#### ArgumentCoordinateNode + +**Interface.** A schema coordinate that refers to a field or directive argument. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
fieldNameThe field name referenced by this schema coordinate.
argumentNameThe argument name referenced by this schema coordinate.
+ +
+ +#### DirectiveCoordinateNode + +**Interface.** A schema coordinate that refers to a directive. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
+ +
+ +#### DirectiveArgumentCoordinateNode + +**Interface.** A schema coordinate that refers to a directive argument. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
argumentNameThe argument name referenced by this schema coordinate.
+ +## Category: Kinds + +
+

+ Enumerations:
+ OperationTypeNode + + DirectiveLocation + + Kind +

+

+ Types:
+ DirectiveLocationEnum + + KindEnum +

+
+ +### Enumerations + +#### OperationTypeNode + +**Enumeration.** The operation types supported by GraphQL executable definitions. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameValueDescription
{"QUERY"}{"\"query\""}A query operation.
{"MUTATION"}{"\"mutation\""}A mutation operation.
{"SUBSCRIPTION"}{"\"subscription\""}A subscription operation.
+ +
+ +#### DirectiveLocation + +**Enumeration.** The set of allowed directive location values. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameValueDescription
{"QUERY"}{"\"QUERY\""}Directive location for query operations.
{"MUTATION"}{"\"MUTATION\""}Directive location for mutation operations.
{"SUBSCRIPTION"}{"\"SUBSCRIPTION\""}Directive location for subscription operations.
{"FIELD"}{"\"FIELD\""}Directive location for field selections.
{"FRAGMENT_DEFINITION"}{"\"FRAGMENT_DEFINITION\""}Directive location for fragment definitions.
{"FRAGMENT_SPREAD"}{"\"FRAGMENT_SPREAD\""}Directive location for fragment spreads.
{"INLINE_FRAGMENT"}{"\"INLINE_FRAGMENT\""}Directive location for inline fragments.
{"VARIABLE_DEFINITION"}{"\"VARIABLE_DEFINITION\""}Directive location for variable definitions.
{"SCHEMA"}{"\"SCHEMA\""}Directive location for schema definitions and extensions.
{"SCALAR"}{"\"SCALAR\""}Directive location for scalar type definitions and extensions.
{"OBJECT"}{"\"OBJECT\""}Directive location for object type definitions and extensions.
{"FIELD_DEFINITION"}{"\"FIELD_DEFINITION\""}Directive location for field definitions.
{"ARGUMENT_DEFINITION"}{"\"ARGUMENT_DEFINITION\""}Directive location for argument definitions.
{"INTERFACE"}{"\"INTERFACE\""}Directive location for interface type definitions and extensions.
{"UNION"}{"\"UNION\""}Directive location for union type definitions and extensions.
{"ENUM"}{"\"ENUM\""}Directive location for enum type definitions and extensions.
{"ENUM_VALUE"}{"\"ENUM_VALUE\""}Directive location for enum value definitions.
{"INPUT_OBJECT"}{"\"INPUT_OBJECT\""}Directive location for input object type definitions and extensions.
{"INPUT_FIELD_DEFINITION"}{"\"INPUT_FIELD_DEFINITION\""}Directive location for input object field definitions.
{"DIRECTIVE_DEFINITION"}{"\"DIRECTIVE_DEFINITION\""}Directive location for directive definitions and extensions.
+ +
+ +#### Kind + +**Enumeration.** The set of allowed kind values for AST nodes. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameValueDescription
{"NAME"}{"\"Name\""}AST kind for name nodes.
{"DOCUMENT"}{"\"Document\""}AST kind for document nodes.
{"OPERATION_DEFINITION"}{"\"OperationDefinition\""}AST kind for operation definition nodes.
{"VARIABLE_DEFINITION"}{"\"VariableDefinition\""}AST kind for variable definition nodes.
{"SELECTION_SET"}{"\"SelectionSet\""}AST kind for selection set nodes.
{"FIELD"}{"\"Field\""}AST kind for field selection nodes.
{"ARGUMENT"}{"\"Argument\""}AST kind for argument nodes.
{"FRAGMENT_SPREAD"}{"\"FragmentSpread\""}AST kind for fragment spread nodes.
{"INLINE_FRAGMENT"}{"\"InlineFragment\""}AST kind for inline fragment nodes.
{"FRAGMENT_DEFINITION"}{"\"FragmentDefinition\""}AST kind for fragment definition nodes.
{"VARIABLE"}{"\"Variable\""}AST kind for variable reference nodes.
{"INT"}{"\"IntValue\""}AST kind for integer value nodes.
{"FLOAT"}{"\"FloatValue\""}AST kind for floating-point value nodes.
{"STRING"}{"\"StringValue\""}AST kind for string value nodes.
{"BOOLEAN"}{"\"BooleanValue\""}AST kind for boolean value nodes.
{"NULL"}{"\"NullValue\""}AST kind for null value nodes.
{"ENUM"}{"\"EnumValue\""}AST kind for enum value nodes.
{"LIST"}{"\"ListValue\""}AST kind for list value nodes.
{"OBJECT"}{"\"ObjectValue\""}AST kind for object value nodes.
{"OBJECT_FIELD"}{"\"ObjectField\""}AST kind for object field nodes.
{"DIRECTIVE"}{"\"Directive\""}AST kind for directive nodes.
{"NAMED_TYPE"}{"\"NamedType\""}AST kind for named type reference nodes.
{"LIST_TYPE"}{"\"ListType\""}AST kind for list type reference nodes.
{"NON_NULL_TYPE"}{"\"NonNullType\""}AST kind for non-null type reference nodes.
{"SCHEMA_DEFINITION"}{"\"SchemaDefinition\""}AST kind for schema definition nodes.
{"OPERATION_TYPE_DEFINITION"}{"\"OperationTypeDefinition\""}AST kind for operation type definition nodes.
{"SCALAR_TYPE_DEFINITION"}{"\"ScalarTypeDefinition\""}AST kind for scalar type definition nodes.
{"OBJECT_TYPE_DEFINITION"}{"\"ObjectTypeDefinition\""}AST kind for object type definition nodes.
{"FIELD_DEFINITION"}{"\"FieldDefinition\""}AST kind for field definition nodes.
{"INPUT_VALUE_DEFINITION"}{"\"InputValueDefinition\""}AST kind for input value definition nodes.
{"INTERFACE_TYPE_DEFINITION"}{"\"InterfaceTypeDefinition\""}AST kind for interface type definition nodes.
{"UNION_TYPE_DEFINITION"}{"\"UnionTypeDefinition\""}AST kind for union type definition nodes.
{"ENUM_TYPE_DEFINITION"}{"\"EnumTypeDefinition\""}AST kind for enum type definition nodes.
{"ENUM_VALUE_DEFINITION"}{"\"EnumValueDefinition\""}AST kind for enum value definition nodes.
{"INPUT_OBJECT_TYPE_DEFINITION"}{"\"InputObjectTypeDefinition\""}AST kind for input object type definition nodes.
{"DIRECTIVE_DEFINITION"}{"\"DirectiveDefinition\""}AST kind for directive definition nodes.
{"SCHEMA_EXTENSION"}{"\"SchemaExtension\""}AST kind for schema extension nodes.
{"DIRECTIVE_EXTENSION"}{"\"DirectiveExtension\""}AST kind for directive extension nodes.
{"SCALAR_TYPE_EXTENSION"}{"\"ScalarTypeExtension\""}AST kind for scalar type extension nodes.
{"OBJECT_TYPE_EXTENSION"}{"\"ObjectTypeExtension\""}AST kind for object type extension nodes.
{"INTERFACE_TYPE_EXTENSION"}{"\"InterfaceTypeExtension\""}AST kind for interface type extension nodes.
{"UNION_TYPE_EXTENSION"}{"\"UnionTypeExtension\""}AST kind for union type extension nodes.
{"ENUM_TYPE_EXTENSION"}{"\"EnumTypeExtension\""}AST kind for enum type extension nodes.
{"INPUT_OBJECT_TYPE_EXTENSION"}{"\"InputObjectTypeExtension\""}AST kind for input object type extension nodes.
{"TYPE_COORDINATE"}{"\"TypeCoordinate\""}AST kind for type coordinate nodes.
{"MEMBER_COORDINATE"}{"\"MemberCoordinate\""}AST kind for member coordinate nodes.
{"ARGUMENT_COORDINATE"}{"\"ArgumentCoordinate\""}AST kind for argument coordinate nodes.
{"DIRECTIVE_COORDINATE"}{"\"DirectiveCoordinate\""}AST kind for directive coordinate nodes.
{"DIRECTIVE_ARGUMENT_COORDINATE"}{"\"DirectiveArgumentCoordinate\""}AST kind for directive argument coordinate nodes.
+ +### Types + +#### DirectiveLocationEnum Deprecated + +**Type alias.** Deprecated legacy alias for the enum type representing directive location +values. This alias will be removed in v17. In v17, [`DirectiveLocation`](/api-v16/language#directivelocation) is +exported as the single public symbol for both the runtime object and the +corresponding TypeScript type. + + + +
+ +#### KindEnum Deprecated + +**Type alias.** Deprecated legacy alias for the enum type representing the possible kind +values of AST nodes. This alias will be removed in v17. In v17, [`Kind`](/api-v16/language#kind) is +exported as the single public symbol for both the runtime object and the +corresponding TypeScript type. + + + +## Category: Lexing + +
+

+ Classes:
+ Lexer +

+

+ Enumerations:
+ TokenKind +

+

+ Types:
+ TokenKindEnum +

+
+ +### Classes + +#### Lexer + +Given a Source object, creates a Lexer for that source. +A Lexer is a stateful stream generator in that every time +it is advanced, it returns the next token in the Source. Assuming the +source lexes, the final Token emitted by the lexer will be of kind +EOF, after which the lexer will repeatedly return the same EOF token +whenever called. + +
+ +##### Constructor + +Creates a Lexer instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
sourceSource document used to derive error locations.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourceSource document used to derive error locations.
lastTokenMost recent non-ignored token returned by the lexer.
tokenCurrent non-ignored token at the lexer cursor.
lineThe (1-indexed) line containing the current token.
lineStartCharacter offset where the current line starts.
+ +
+ +##### advance() + +Advances the token stream to the next non-ignored token. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The next non-ignored token.
+ +
+ +
Example
+ +```ts +import { Lexer, Source } from 'graphql/language'; + +const lexer = new Lexer(new Source('{ hello }')); +const token = lexer.advance(); + +token.kind; // => '{' +lexer.token; // => token +``` + +
+ +##### lookahead() + +Looks ahead and returns the next non-ignored token, but does not change +the state of Lexer. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The next non-ignored token without advancing the lexer.
+ +
+ +
Example
+ +```ts +import { Lexer, Source } from 'graphql/language'; + +const lexer = new Lexer(new Source('{ hello }')); +const token = lexer.lookahead(); + +token.kind; // => '{' +lexer.token.kind; // => '' +``` + +### Enumerations + +#### TokenKind + +**Enumeration.** An exported enum describing the different kinds of tokens that the +lexer emits. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameValueDescription
{"SOF"}{"\"\""}Start-of-file token.
{"EOF"}{"\"\""}End-of-file token.
{"BANG"}{"\"!\""}The {"!"} punctuation token.
{"DOLLAR"}{"\"$\""}The {"$"} punctuation token.
{"AMP"}{"\"&\""}The {"&"} punctuation token.
{"PAREN_L"}{"\"(\""}The {"("} punctuation token.
{"PAREN_R"}{"\")\""}The {")"} punctuation token.
{"DOT"}{"\".\""}The {"."} punctuation token.
{"SPREAD"}{"\"...\""}The {"..."} spread punctuation token.
{"COLON"}{"\":\""}The {":"} punctuation token.
{"EQUALS"}{"\"=\""}The {"="} punctuation token.
{"AT"}{"\"@\""}The {"@"} punctuation token.
{"BRACKET_L"}{"\"[\""}The {"["} punctuation token.
{"BRACKET_R"}{"\"]\""}The {"]"} punctuation token.
{"BRACE_L"}{"\"{\""}The {"{"} punctuation token.
{"PIPE"}{"\"\u007c\""}The {"\u007c"} punctuation token.
{"BRACE_R"}{"\"}\""}The {"}"} punctuation token.
{"NAME"}{"\"Name\""}A GraphQL name token or name AST node.
{"INT"}{"\"Int\""}An integer value token or AST node.
{"FLOAT"}{"\"Float\""}A floating-point value token or AST node.
{"STRING"}{"\"String\""}A string value token or AST node.
{"BLOCK_STRING"}{"\"BlockString\""}A block string value token.
{"COMMENT"}{"\"Comment\""}A comment token.
+ +### Types + +#### TokenKindEnum Deprecated + +**Type alias.** Deprecated legacy alias for the enum type representing token kind values. +This alias will be removed in v17. In v17, [`TokenKind`](/api-v16/language#tokenkind) is exported as the +single public symbol for both the runtime object and the corresponding +TypeScript type. + + + +## Category: Source + +
+

+ Classes:
+ Source +

+

+ Functions:
+ getLocation() + + printLocation() + + printSourceLocation() +

+

+ Types:
+ SourceLocation +

+
+ +### Classes + +#### Source + +A representation of source input to GraphQL. The `name` and `locationOffset` parameters are +optional, but they are useful for clients who store GraphQL documents in source files. +For example, if the GraphQL input starts at line 40 in a file named `Foo.graphql`, it might +be useful for `name` to be `"Foo.graphql"` and location to be `{ line: 40, column: 1 }`. +The `line` and `column` properties in `locationOffset` are 1-indexed. + +
+ +##### Constructor + +Creates a Source instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
bodyThe GraphQL source text.
nameName used in diagnostics for this source.
locationOffsetOne-indexed line and column where this source begins.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
bodyThe GraphQL source text.
nameName used in diagnostics for this source, such as a file path or request name.
locationOffsetOne-indexed line and column where this source begins.
+ +### Functions + +#### getLocation() + +Takes a Source and a UTF-8 character offset, and returns the corresponding +line and column as a SourceLocation. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourceThe source document that contains the position.
positionThe UTF-8 character offset in the source body.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The 1-indexed line and column for the given source position.
+ +
+ +
Example
+ +```ts +import { Source, getLocation } from 'graphql/language'; + +const source = new Source('type Query { hello: String }'); +const location = getLocation(source, 13); + +location; // => { line: 1, column: 14 } +``` + +
+ +#### printLocation() + +Render a helpful description of the location in the GraphQL Source document. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
locationThe AST location to print.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A formatted source excerpt with line and column information.
+ +
+ +
Example
+ +```ts +import { parse, printLocation } from 'graphql/language'; + +const document = parse('type Query { hello: String }'); +const location = document.definitions[0].loc; + +if (location) { + const printed = printLocation(location); + + printed; // => 'GraphQL request:1:1\n1 | type Query { hello: String }\n | ^' +} +``` + +
+ +#### printSourceLocation() + +Render a helpful description of the location in the GraphQL Source document. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourceThe source document that contains the location.
sourceLocationThe 1-indexed line and column to print.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A formatted source excerpt with line and column information.
+ +
+ +
Example
+ +```ts +import { Source, printSourceLocation } from 'graphql/language'; + +const source = new Source('type Query { hello: String }'); +const printed = printSourceLocation(source, { line: 1, column: 14 }); + +printed; // => 'GraphQL request:1:14\n1 | type Query { hello: String }\n | ^' +``` + +### Types + +#### SourceLocation + +**Interface.** Represents a location in a Source. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
lineOne-indexed line number in the source document.
columnOne-indexed column number in the source document.
+ +## Category: Parsing + +
+

+ Functions:
+ parse() + + parseValue() + + parseConstValue() + + parseType() + + parseSchemaCoordinate() +

+

+ Types:
+ ParseOptions +

+
+ +### Functions + +#### parse() + +Given a GraphQL source, parses it into a Document. +Throws GraphQLError if a syntax error is encountered. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourceA GraphQL source string or source object.
options?Optional parser configuration.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The parsed GraphQL document AST.
+ +
+ +
Example 1
+ +```ts +// Parse a GraphQL document with the default parser options. +import { parse } from 'graphql/language'; + +const document = parse('{ hero { name } }'); + +document.kind; // => 'Document' +``` + +
+ +
Example 2
+ +```ts +// This variant enables parser options and provides an explicit lexer. +import { Lexer, Source, parse } from 'graphql/language'; + +const document = parse('fragment A($var: Boolean) on Query { field }', { + allowLegacyFragmentVariables: true, + maxTokens: 20, + noLocation: true, +}); +const directiveDocument = parse('directive @foo @bar on FIELD', { + experimentalDirectivesOnDirectiveDefinitions: true, +}); +const source = new Source('{ hero }'); +const lexerDocument = parse(source, { lexer: new Lexer(source) }); + +document.definitions[0].kind; // => 'FragmentDefinition' +document.loc; // => undefined +directiveDocument.definitions[0].kind; // => 'DirectiveDefinition' +lexerDocument.definitions[0].kind; // => 'OperationDefinition' +``` + +
+ +#### parseValue() + +Given a string containing a GraphQL value (ex. `[42]`), parse the AST for +that value. +Throws GraphQLError if a syntax error is encountered. + +This is useful within tools that operate upon GraphQL Values directly and +in isolation of complete GraphQL documents. + +Consider providing the results to the utility function: valueFromAST(). + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourceA GraphQL source string or source object containing a value.
options?Optional parser configuration.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The parsed GraphQL value AST.
+ +
+ +
Example
+ +```ts +import { parseValue } from 'graphql/language'; + +const value = parseValue('[42]'); + +value.kind; // => 'ListValue' +``` + +
+ +#### parseConstValue() + +Similar to parseValue(), but raises a parse error if it encounters a +variable. The return type will be a constant value. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourceA GraphQL source string or source object containing a constant value.
options?Optional parser configuration.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The parsed GraphQL constant value AST.
+ +
+ +
Example
+ +```ts +import { parseConstValue } from 'graphql/language'; + +const value = parseConstValue('{ enabled: true }'); + +value.kind; // => 'ObjectValue' +parseConstValue('$variable'); // throws an error +``` + +
+ +#### parseType() + +Given a string containing a GraphQL Type (ex. `[Int!]`), parse the AST for +that type. +Throws GraphQLError if a syntax error is encountered. + +This is useful within tools that operate upon GraphQL Types directly and +in isolation of complete GraphQL documents. + +Consider providing the results to the utility function: typeFromAST(). + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourceA GraphQL source string or source object containing a type reference.
options?Optional parser configuration.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The parsed GraphQL type AST.
+ +
+ +
Example
+ +```ts +import { parseType } from 'graphql/language'; + +const type = parseType('[String!]'); + +type.kind; // => 'ListType' +``` + +
+ +#### parseSchemaCoordinate() + +Given a string containing a GraphQL Schema Coordinate (ex. `Type.field`), +parse the AST for that schema coordinate. +Throws GraphQLError if a syntax error is encountered. + +Consider providing the results to the utility function: +resolveASTSchemaCoordinate(). Or calling resolveSchemaCoordinate() directly +with an unparsed source. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
sourceA GraphQL source string or source object containing a schema coordinate.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The parsed GraphQL schema coordinate AST.
+ +
+ +
Example
+ +```ts +import { parseSchemaCoordinate } from 'graphql/language'; + +const coordinate = parseSchemaCoordinate('Query.hero'); + +coordinate.kind; // => 'MemberCoordinate' +``` + +### Types + +#### ParseOptions + +**Interface.** Configuration options to control parser behavior + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
noLocation?By default, the parser creates AST nodes that know the location
+in the source that they correspond to. This configuration flag
+disables that behavior for performance or testing.
maxTokens?Parser CPU and memory usage is linear to the number of tokens in a document
+however in extreme cases it becomes quadratic due to memory exhaustion.
+Parsing happens before validation so even invalid queries can burn lots of
+CPU time and memory.
+To prevent this you can set a maximum number of tokens allowed within a document.
allowLegacyFragmentVariables?Deprecated option that allows legacy fragment variable definitions to be
+parsed. This legacy fragment variable syntax will be removed in v17. Move
+variable definitions to operations for spec-compliant documents; if you
+need variables or arguments scoped to fragments, v17 has a more complete
+experimental fragment-arguments feature.
experimentalDirectivesOnDirectiveDefinitions?EXPERIMENTAL:
+If enabled, the parser will parse directives on directive definitions.
+This syntax is not part of the GraphQL specification and may change.
+ +
+ +
allowLegacyFragmentVariables Example
+ +The syntax is identical to normal, query-defined variables. + +```graphql +fragment A($var: Boolean = false) on T { + ... +} ``` -## Overview - -### Source - - - -### Lexer - - - -### Parser - - - -### Visitor - - - -### Printer - - - -## Source - -### Source +
+ +
experimentalDirectivesOnDirectiveDefinitions Example
+ +```graphql +directive @foo @bar on FIELD +``` + +## Category: AST Predicates + + + +### Functions + +#### isDefinitionNode() + +Returns true when the AST node is a definition node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a definition node.
+ +
+ +
Example
```ts -export class Source { - constructor(body: string, name?: string); -} +import { parse, isDefinitionNode } from 'graphql/language'; + +const document = parse('{ hello }'); + +isDefinitionNode(document.definitions[0]); // => true +isDefinitionNode(document); // => false ``` -A representation of source input to GraphQL. The name is optional, -but is mostly useful for clients who store GraphQL documents in -source files; for example, if the GraphQL input is in a file Foo.graphql, -it might be useful for name to be "Foo.graphql". +
+ +#### isExecutableDefinitionNode() + +Returns true when the AST node is an executable definition node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is an executable definition node.
+ +
-### getLocation +
Example
```ts -function getLocation(source: Source, position: number): SourceLocation; +import { parse, isExecutableDefinitionNode } from 'graphql/language'; -type SourceLocation = { - line: number; - column: number; -}; +const query = parse('{ hello }'); +const schema = parse('type Query { hello: String }'); + +isExecutableDefinitionNode(query.definitions[0]); // => true +isExecutableDefinitionNode(schema.definitions[0]); // => false ``` -Takes a Source and a UTF-8 character offset, and returns the corresponding -line and column as a SourceLocation. +
+ +#### isSelectionNode() + +Returns true when the AST node is a selection node. + +**Signature:** + + + +
-## Lexer +
Arguments
-### `lex` + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a selection node.
+ +
+ +
Example
```ts -function lex(source: Source): Lexer; +import { Kind, isSelectionNode } from 'graphql/language'; -type Lexer = (resetPosition?: number) => Token; +const field = { kind: Kind.FIELD, name: { kind: Kind.NAME, value: 'hello' } }; +const document = { kind: Kind.DOCUMENT, definitions: [] }; -export type Token = { - kind: number; - start: number; - end: number; - value: string; -}; +isSelectionNode(field); // => true +isSelectionNode(document); // => false ``` -Given a Source object, this returns a Lexer for that source. -A Lexer is a function that acts like a generator in that every time -it is called, it returns the next token in the Source. Assuming the -source lexes, the final Token emitted by the lexer will be of kind -EOF, after which the lexer will repeatedly return EOF tokens whenever -called. +
+ +#### isValueNode() + +Returns true when the AST node is a value node. -The argument to the lexer function is optional, and can be used to -rewind or fast forward the lexer to a new position in the source. +**Signature:** -## Parser + -### `parse` +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a value node.
+ +
+ +
Example
```ts -export function parse( - source: Source | string, - options?: ParseOptions, -): Document; +import { parseType, parseValue, isValueNode } from 'graphql/language'; + +const value = parseValue('[42]'); +const type = parseType('[String!]'); + +isValueNode(value); // => true +isValueNode(type); // => false ``` -Given a GraphQL source, parses it into a Document. +
-Throws GraphQLError if a syntax error is encountered. +#### isConstValueNode() + +Returns true when the AST node is a constant value node. + +**Signature:** + + + +
+ +
Arguments
-### `parseValue` + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a constant value node.
+ +
+ +
Example
```ts -export function parseValue( - source: Source | string, - options?: ParseOptions, -): Value; +import { parseConstValue, parseValue, isConstValueNode } from 'graphql/language'; + +const value = parseConstValue('[42]'); +const variable = parseValue('$id'); + +isConstValueNode(value); // => true +isConstValueNode(variable); // => false ``` -Given a string containing a GraphQL value, parse the AST for that value. +
-Throws GraphQLError if a syntax error is encountered. +#### isTypeNode() -This is useful within tools that operate upon GraphQL Values directly and -in isolation of complete GraphQL documents. +Returns true when the AST node is a type node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
-### `Kind` +
Returns
-An enum that describes the different kinds of AST nodes. + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a type node.
-## Visitor +
-### `visit` +
Example
```ts -function visit(root, visitor, keyMap); +import { parseType, parseValue, isTypeNode } from 'graphql/language'; + +const type = parseType('[String!]'); +const value = parseValue('[42]'); + +isTypeNode(type); // => true +isTypeNode(value); // => false ``` -visit() will walk through an AST using a depth first traversal, calling -the visitor's enter function at each node in the traversal, and calling the -leave function after visiting that node and all of its child nodes. - -By returning different values from the enter and leave functions, the -behavior of the visitor can be altered, including skipping over a sub-tree of -the AST (by returning false), editing the AST by returning a value or null -to remove the value, or to stop the whole traversal by returning BREAK. - -When using visit() to edit an AST, the original AST will not be modified, and -a new version of the AST with the changes applied will be returned from the -visit function. - -```js -const editedAST = visit(ast, { - enter(node, key, parent, path, ancestors) { - // @return - // undefined: no action - // false: skip visiting this node - // visitor.BREAK: stop visiting altogether - // null: delete this node - // any value: replace this node with the returned value - }, - leave(node, key, parent, path, ancestors) { - // @return - // undefined: no action - // false: no action - // visitor.BREAK: stop visiting altogether - // null: delete this node - // any value: replace this node with the returned value - }, -}); +
+ +#### isTypeSystemDefinitionNode() + +Returns true when the AST node is a type system definition node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a type system definition node.
+ +
+ +
Example
+ +```ts +import { parse, isTypeSystemDefinitionNode } from 'graphql/language'; + +const schema = parse('type Query { hello: String }'); +const query = parse('{ hello }'); + +isTypeSystemDefinitionNode(schema.definitions[0]); // => true +isTypeSystemDefinitionNode(query.definitions[0]); // => false ``` -Alternatively to providing enter() and leave() functions, a visitor can -instead provide functions named the same as the kinds of AST nodes, or -enter/leave visitors at a named key, leading to three permutations of -visitor API: +
-1. Named visitors triggered when entering a node a specific kind. +#### isTypeDefinitionNode() -```js -visit(ast, { - Kind(node) { - // enter the "Kind" node - }, -}); +Returns true when the AST node is a type definition node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a type definition node.
+ +
+ +
Example
+ +```ts +import { parse, isTypeDefinitionNode } from 'graphql/language'; + +const typeDefinition = parse('type Query { hello: String }'); +const directiveDefinition = parse('directive @cache on FIELD'); + +isTypeDefinitionNode(typeDefinition.definitions[0]); // => true +isTypeDefinitionNode(directiveDefinition.definitions[0]); // => false ``` -2. Named visitors that trigger upon entering and leaving a node of - a specific kind. - -```js -visit(ast, { - Kind: { - enter(node) { - // enter the "Kind" node - }, - leave(node) { - // leave the "Kind" node - }, - }, -}); +
+ +#### isTypeSystemExtensionNode() + +Returns true when the AST node is a type system extension node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a type system extension node.
+ +
+ +
Example
+ +```ts +import { parse, isTypeSystemExtensionNode } from 'graphql/language'; + +const extension = parse('extend type Query { hello: String }'); +const definition = parse('type Query { hello: String }'); + +isTypeSystemExtensionNode(extension.definitions[0]); // => true +isTypeSystemExtensionNode(definition.definitions[0]); // => false ``` -3. Generic visitors that trigger upon entering and leaving any node. +
-```js -visit(ast, { - enter(node) { - // enter any node - }, - leave(node) { - // leave any node - }, -}); +#### isTypeExtensionNode() + +Returns true when the AST node is a type extension node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a type extension node.
+ +
+ +
Example
+ +```ts +import { parse, isTypeExtensionNode } from 'graphql/language'; + +const extension = parse('extend type Query { hello: String }'); +const schemaExtension = parse('extend schema { query: Query }'); + +isTypeExtensionNode(extension.definitions[0]); // => true +isTypeExtensionNode(schemaExtension.definitions[0]); // => false ``` -### `BREAK` +
+ +#### isSchemaCoordinateNode() + +Returns true when the AST node is a schema coordinate node. + +**Signature:** + + + +
-The sentinel `BREAK` value described in the documentation of `visitor`. +
Arguments
-## Printer + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
-### `print` +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a schema coordinate node.
+ +
+ +
Example
```ts -function print(ast): string; +import { + parse, + parseSchemaCoordinate, + isSchemaCoordinateNode, +} from 'graphql/language'; + +const coordinate = parseSchemaCoordinate('Query.hero'); +const document = parse('{ hero }'); + +isSchemaCoordinateNode(coordinate); // => true +isSchemaCoordinateNode(document); // => false ``` +## Category: Printing + +
+

+ Functions:
+ print() +

+
+ +### Functions + +#### print() + Converts an AST into a string, using one set of reasonable formatting rules. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
astThe GraphQL AST node to print.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A stable string representation of the AST.
+ +
+ +
Example
+ +```ts +import { parse, print } from 'graphql'; + +const ast = parse('{ hero { name } }'); +const text = print(ast); + +text; // => '{\n hero {\n name\n }\n}' +``` + +## Category: Visiting + +
+

+ Functions:
+ visitInParallel() + + getEnterLeaveForKind() + + getVisitFn() +

+

+ Constants:
+ BREAK +

+

+ Types:
+ ASTVisitor + + ASTVisitFn + + ASTVisitorKeyMap +

+
+ +### Functions + +#### visitInParallel() + +Creates a new visitor instance which delegates to many visitors to run in +parallel. Each visitor will be visited for each node before moving on. + +If a prior visitor edits a node, no following visitors will see that node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
visitorsThe visitors to merge into one parallel visitor.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that delegates traversal to each provided visitor.
+ +
+ +
Example
+ +```ts +import { parse, visit, visitInParallel } from 'graphql/language'; + +const document = parse('{ hero { name } }'); +const events = []; + +visit( + document, + visitInParallel([ + { Field: (node) => { events.push(`field:${node.name.value}`); } }, + { Name: (node) => { events.push(`name:${node.value}`); } }, + ]), +); + +events; // => ['field:hero', 'name:hero', 'field:name', 'name:name'] +``` + +
+ +#### getEnterLeaveForKind() + +Given a visitor instance and a node kind, return EnterLeaveVisitor for that kind. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
visitorThe visitor object to inspect.
kindThe AST node kind to resolve handlers for.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The enter and leave handlers that apply for the given node kind.
+ +
+ +
Example
+ +```ts +import { Kind, getEnterLeaveForKind } from 'graphql/language'; + +const handlers = getEnterLeaveForKind({ Field: () => {} }, Kind.FIELD); + +typeof handlers.enter; // => 'function' +handlers.leave; // => undefined +``` + +
+ +#### getVisitFn() Deprecated + +Given a visitor instance, if it is leaving or not, and a node kind, return +the function the visitor runtime should call. This deprecated compatibility +helper delegates to [`getEnterLeaveForKind`](/api-v16/language#getenterleaveforkind); call [`getEnterLeaveForKind`](/api-v16/language#getenterleaveforkind) +directly because getVisitFn will be removed in v17. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
visitorThe visitor object to inspect.
kindThe AST node kind to resolve a handler for.
isLeavingWhether to resolve the leave handler instead of the enter handler.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The visit function that applies for the given node kind and traversal phase, if one exists.
+ +
+ +
Example
+ +```ts +import { Kind, getVisitFn } from 'graphql/language'; + +const enter = getVisitFn({ Field: () => {} }, Kind.FIELD, false); +const leave = getVisitFn({ Field: () => {} }, Kind.FIELD, true); + +typeof enter; // => 'function' +leave; // => undefined +``` + +### Constants + +#### BREAK + +A value that can be returned from a visitor function to stop traversal. + +
+ +
Type
+ + + +### Types + +#### ASTVisitor + +**Type alias.** A visitor defines the callbacks called during AST traversal. + + + +
+ +#### ASTVisitFn + +**Type alias.** A visitor is composed of visit functions called for each node during traversal. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TVisitedNodeAST node type handled by this visitor function.
+ + + +
+ +#### ASTVisitorKeyMap Deprecated + +**Type alias.** Deprecated visitor key map type retained for compatibility. Inline this +mapped type at use sites because ASTVisitorKeyMap will be removed in v17. + + diff --git a/website/pages/api-v16/language/_meta.ts b/website/pages/api-v16/language/_meta.ts new file mode 100644 index 0000000000..084d87f3c8 --- /dev/null +++ b/website/pages/api-v16/language/_meta.ts @@ -0,0 +1,36 @@ +const meta = { + ast: { + title: 'Category: AST', + href: '/api-v16/language#category-ast', + }, + kinds: { + title: 'Category: Kinds', + href: '/api-v16/language#category-kinds', + }, + lexing: { + title: 'Category: Lexing', + href: '/api-v16/language#category-lexing', + }, + source: { + title: 'Category: Source', + href: '/api-v16/language#category-source', + }, + parsing: { + title: 'Category: Parsing', + href: '/api-v16/language#category-parsing', + }, + 'ast-predicates': { + title: 'Category: AST Predicates', + href: '/api-v16/language#category-ast-predicates', + }, + printing: { + title: 'Category: Printing', + href: '/api-v16/language#category-printing', + }, + visiting: { + title: 'Category: Visiting', + href: '/api-v16/language#category-visiting', + }, +}; + +export default meta; diff --git a/website/pages/api-v16/subscription.mdx b/website/pages/api-v16/subscription.mdx new file mode 100644 index 0000000000..fa8476ae76 --- /dev/null +++ b/website/pages/api-v16/subscription.mdx @@ -0,0 +1,31 @@ +import { ApiSignature } from '../../components/ApiCode'; + +NOTE: the `graphql/subscription` module has been deprecated with its +exported functions integrated into the `graphql/execution` module, to +better conform with the terminology of the GraphQL specification. + +For backwards compatibility, the `graphql/subscription` module +currently re-exports the moved functions from the `graphql/execution` +module. In v17, the `graphql/subscription` module will be dropped entirely. + +These exports are also available from the root `graphql` package. + +
+

+ Types:
+ SubscriptionArgs +

+
+ +## Types + +### SubscriptionArgs Deprecated + +**Interface.** Deprecated legacy alias for ExecutionArgs retained by the subscription +module. Use [`ExecutionArgs`](/api-v16/execution#executionargs) directly instead because SubscriptionArgs will be +removed in v17. + +ExecutionArgs has been broadened to include all properties within SubscriptionArgs. +The SubscriptionArgs type is retained for backwards compatibility. + + diff --git a/website/pages/api-v16/type.mdx b/website/pages/api-v16/type.mdx index c829d9708d..07c243b495 100644 --- a/website/pages/api-v16/type.mdx +++ b/website/pages/api-v16/type.mdx @@ -1,672 +1,9912 @@ ---- -title: graphql/type ---- - -{/* title can be removed in Nextra 4, since sidebar title will take from first h1 */} - -# `graphql/type` - -The `graphql/type` module is responsible for defining GraphQL types and schema. You can import either from the `graphql/type` module, or from the root `graphql` module. For example: - -```js -import { GraphQLSchema } from 'graphql'; -``` - -## Overview - -### Schema - - - -### Definitions - - - -### Predicates - - - -### Un-modifiers - - - -### Scalars - - - -## Schema - -### GraphQLSchema - -```ts -class GraphQLSchema { - constructor(config: GraphQLSchemaConfig); -} - -type GraphQLSchemaConfig = { - query: GraphQLObjectType; - mutation?: GraphQLObjectType; +import { ApiSignature, ApiType } from '../../components/ApiCode'; + +Create and inspect GraphQL type definitions and schemas. + +These exports are also available from the root `graphql` package. + +For documentation purposes, these exports are grouped into the following categories: + +- [Paths](/api-v16/type#category-paths) +- [Names](/api-v16/type#category-names) +- [Types](/api-v16/type#category-types) +- [Directives](/api-v16/type#category-directives) +- [Introspection](/api-v16/type#category-introspection) +- [Scalars](/api-v16/type#category-scalars) +- [Schema](/api-v16/type#category-schema) +- [Validation](/api-v16/type#category-validation) + +## Category: Paths + +
+

+ Types:
+ ResponsePath +

+
+ +### Types + +#### ResponsePath + +**Interface.** Represents a linked response path from a field back to the root response. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
prevThe previous segment in the linked response path, or undefined at the root.
keyThe field name or list index for this response path segment.
typenameThe runtime object type name associated with this path segment, if known.
+ +## Category: Names + +
+

+ Functions:
+ assertName() + + assertEnumValueName() +

+
+ +### Functions + +#### assertName() + +Upholds the spec rules about naming. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name to validate.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The validated GraphQL name.
+ +
+ +
Example
+ +```ts +import { assertName } from 'graphql/type'; + +assertName('User'); // => 'User' +assertName('123User'); // throws an error +``` + +
+ +#### assertEnumValueName() + +Upholds the spec rules about naming enum values. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name to validate.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The validated GraphQL name.
+ +
+ +
Example
+ +```ts +import { assertEnumValueName } from 'graphql/type'; + +assertEnumValueName('ACTIVE'); // => 'ACTIVE' +assertEnumValueName('true'); // throws an error +``` + +## Category: Types + +
+

+ Classes:
+ GraphQLList + + GraphQLNonNull + + GraphQLScalarType + + GraphQLObjectType + + GraphQLInterfaceType + + GraphQLUnionType + + GraphQLEnumType + + GraphQLInputObjectType +

+

+ Functions:
+ isType() + + assertType() + + isScalarType() + + assertScalarType() + + isObjectType() + + assertObjectType() + + isInterfaceType() + + assertInterfaceType() + + isUnionType() + + assertUnionType() + + isEnumType() + + assertEnumType() + + isInputObjectType() + + assertInputObjectType() + + assertListType() + + assertNonNullType() + + isInputType() + + assertInputType() + + isOutputType() + + assertOutputType() + + isLeafType() + + assertLeafType() + + isCompositeType() + + assertCompositeType() + + isAbstractType() + + assertAbstractType() + + isWrappingType() + + assertWrappingType() + + isNullableType() + + assertNullableType() + + isNamedType() + + assertNamedType() + + resolveReadonlyArrayThunk() + + resolveObjMapThunk() + + isRequiredArgument() + + isRequiredInputField() +

+

+ Types:
+ GraphQLType + + GraphQLInputType + + GraphQLOutputType + + GraphQLLeafType + + GraphQLCompositeType + + GraphQLAbstractType + + GraphQLWrappingType + + GraphQLNullableType + + GraphQLNamedType + + GraphQLNamedInputType + + GraphQLNamedOutputType + + ThunkReadonlyArray + + ThunkObjMap + + GraphQLScalarTypeExtensions + + GraphQLScalarSerializer + + GraphQLScalarValueParser + + GraphQLScalarLiteralParser + + GraphQLScalarTypeConfig + + GraphQLObjectTypeExtensions + + GraphQLObjectTypeConfig + + GraphQLTypeResolver + + GraphQLIsTypeOfFn + + GraphQLFieldResolver + + GraphQLResolveInfo + + GraphQLFieldExtensions + + GraphQLFieldConfig + + GraphQLFieldConfigArgumentMap + + GraphQLArgumentExtensions + + GraphQLArgumentConfig + + GraphQLFieldConfigMap + + GraphQLField + + GraphQLArgument + + GraphQLFieldMap + + GraphQLInterfaceTypeExtensions + + GraphQLInterfaceTypeConfig + + GraphQLUnionTypeExtensions + + GraphQLUnionTypeConfig + + GraphQLEnumTypeExtensions + + GraphQLEnumTypeConfig + + GraphQLEnumValueConfigMap + + GraphQLEnumValueExtensions + + GraphQLEnumValueConfig + + GraphQLEnumValue + + GraphQLInputObjectTypeExtensions + + GraphQLInputObjectTypeConfig + + GraphQLInputFieldExtensions + + GraphQLInputFieldConfig + + GraphQLInputFieldConfigMap + + GraphQLInputField + + GraphQLInputFieldMap +

+
+ +### Classes + +#### GraphQLList + +List Type Wrapper + +A list is a wrapping type which points to another type. +Lists are often created within the context of defining the fields of +an object type. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TThe GraphQL type wrapped by this list type.
+ +
+ +
Example
+ +```ts +const PersonType = new GraphQLObjectType({ + name: 'Person', + fields: () => ({ + parents: { type: new GraphQLList(PersonType) }, + children: { type: new GraphQLList(PersonType) }, + }) +}) +``` + +
+ +##### Constructor + +Creates a GraphQLList instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
ofTypeThe type to wrap.
+ +
+ +##### Members + + + + + + + + + + + + + + + + +
NameTypeDescription
ofTypeThe type wrapped by this list or non-null type.
+ +
+ +##### toString() + +Returns this wrapping type as a GraphQL type-reference string. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The GraphQL type-reference string.
+ +
+ +
Example
+ +```ts +import { GraphQLList, GraphQLNonNull, GraphQLString } from 'graphql/type'; + +const stringList = new GraphQLList(GraphQLString); +const requiredStringList = new GraphQLList(new GraphQLNonNull(GraphQLString)); + +stringList.toString(); // => '[String]' +requiredStringList.toString(); // => '[String!]' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { GraphQLList, GraphQLString } from 'graphql/type'; + +const stringList = new GraphQLList(GraphQLString); + +stringList.toJSON(); // => '[String]' +JSON.stringify({ type: stringList }); // => '{"type":"[String]"}' +``` + +
+ +#### GraphQLNonNull + +Non-Null Type Wrapper + +A non-null is a wrapping type which points to another type. +Non-null types enforce that their values are never null and can ensure +an error is raised if this ever occurs during a request. It is useful for +fields which you can make a strong guarantee on non-nullability, for example +usually the id field of a database row will never be null. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TThe nullable GraphQL type wrapped by this non-null type.
+ +
+ +
Example
+ +```ts +const RowType = new GraphQLObjectType({ + name: 'Row', + fields: () => ({ + id: { type: new GraphQLNonNull(GraphQLString) }, + }) +}) +``` + +Note: the enforcement of non-nullability occurs within the executor. + +
+ +##### Constructor + +Creates a GraphQLNonNull instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
ofTypeThe type to wrap.
+ +
+ +##### Members + + + + + + + + + + + + + + + + +
NameTypeDescription
ofTypeThe type wrapped by this list or non-null type.
+ +
+ +##### toString() + +Returns this wrapping type as a GraphQL type-reference string. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The GraphQL type-reference string.
+ +
+ +
Example
+ +```ts +import { GraphQLList, GraphQLNonNull, GraphQLString } from 'graphql/type'; + +const requiredString = new GraphQLNonNull(GraphQLString); +const requiredStringList = new GraphQLNonNull( + new GraphQLList(GraphQLString), +); + +requiredString.toString(); // => 'String!' +requiredStringList.toString(); // => '[String]!' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { GraphQLNonNull, GraphQLString } from 'graphql/type'; + +const requiredString = new GraphQLNonNull(GraphQLString); + +requiredString.toJSON(); // => 'String!' +JSON.stringify({ type: requiredString }); // => '{"type":"String!"}' +``` + +
+ +#### GraphQLScalarType + +Scalar Type Definition + +Scalar types define the leaf values of a GraphQL response and the input +values accepted by arguments and input object fields. A scalar type has a +name and coercion functions that validate and convert runtime values and +GraphQL literals. + +If a type's serialize function returns `null` or does not return a value +(i.e. it returns `undefined`) then an error will be raised and a `null` +value will be returned in the response. Prefer validating inputs before +execution so clients receive input diagnostics before result coercion fails. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TInternalThe internal runtime representation accepted by this scalar.
TExternalThe serialized representation exposed in GraphQL results.
+ +
+ +
Example
+ +```ts +const OddType = new GraphQLScalarType({ + name: 'Odd', + serialize: (value) => { + if (!Number.isFinite(value)) { + throw new Error( + `Scalar "Odd" cannot represent "${value}" since it is not a finite number.`, + ); + } + + if (value % 2 === 0) { + throw new Error(`Scalar "Odd" cannot represent "${value}" since it is even.`); + } + return value; + } +}); +``` + +
+ +##### Constructor + +Creates a GraphQLScalarType instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
configConfiguration describing this object.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
specifiedByURLURL identifying the behavior specified for this custom scalar.
serializeFunction that converts internal values to externally visible scalar values.
parseValueFunction that converts variable input into this scalar's internal value.
parseLiteralFunction that converts AST input literals into this scalar's internal value.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
extensionASTNodesAST extension nodes applied to this schema element.
+ +
+ +##### toConfig() + +Returns a normalized configuration object for this object. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this object.
+ +
+ +
Example
+ +```ts +import { GraphQLScalarType } from 'graphql/type'; + +const Url = new GraphQLScalarType({ + name: 'Url', + description: 'An absolute URL string.', + specifiedByURL: 'https://url.spec.whatwg.org/', +}); + +const config = Url.toConfig(); +const UrlCopy = new GraphQLScalarType(config); + +config.name; // => 'Url' +config.specifiedByURL; // => 'https://url.spec.whatwg.org/' +UrlCopy.name; // => Url.name +``` + +
+ +##### toString() + +Returns the schema coordinate identifying this scalar type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema coordinate for this scalar type.
+ +
+ +
Example
+ +```ts +import { GraphQLScalarType } from 'graphql/type'; + +const DateTime = new GraphQLScalarType({ name: 'DateTime' }); + +DateTime.toString(); // => 'DateTime' +String(DateTime); // => 'DateTime' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { GraphQLScalarType } from 'graphql/type'; + +const DateTime = new GraphQLScalarType({ name: 'DateTime' }); + +DateTime.toJSON(); // => 'DateTime' +JSON.stringify({ type: DateTime }); // => '{"type":"DateTime"}' +``` + +
+ +#### GraphQLObjectType + +Object Type Definition + +Almost all of the GraphQL types you define will be object types. Object types +have a name, but most importantly describe their fields. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
+ +
+ +
Example 1
+ +```ts +const AddressType = new GraphQLObjectType({ + name: 'Address', + fields: { + street: { type: GraphQLString }, + number: { type: GraphQLInt }, + formatted: { + type: GraphQLString, + resolve: (obj) => { + return obj.number + ' ' + obj.street + } + } + } +}); +``` + +
+ +
Example 2
+ +When two types need to refer to each other, or a type needs to refer to +itself in a field, you can use a function expression (aka a closure or a +thunk) to supply the fields lazily. + +```ts +const PersonType = new GraphQLObjectType({ + name: 'Person', + fields: () => ({ + name: { type: GraphQLString }, + bestFriend: { type: PersonType }, + }) +}); +``` + +
+ +##### Constructor + +Creates a GraphQLObjectType instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
configConfiguration describing this object.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
isTypeOfPredicate used to determine whether a runtime value belongs to this object type.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
extensionASTNodesAST extension nodes applied to this schema element.
+ +
+ +##### getFields() + +Returns the fields defined by this type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The fields keyed by field name.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertObjectType } from 'graphql/type'; + +const schema = buildSchema(` + type User { + id: ID! + name: String + } + + type Query { + viewer: User + } +`); + +const User = assertObjectType(schema.getType('User')); +const fields = User.getFields(); + +Object.keys(fields); // => ['id', 'name'] +String(fields.id.type); // => 'ID!' +``` + +
+ +##### getInterfaces() + +Returns the interfaces implemented by this type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The implemented interfaces.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertObjectType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Query { + viewer: User + } +`); + +const User = assertObjectType(schema.getType('User')); + +User.getInterfaces().map((type) => type.name); // => ['Node'] +``` + +
+ +##### toConfig() + +Returns a normalized configuration object for this object. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this object.
+ +
+ +
Example
+ +```ts +import { GraphQLObjectType, GraphQLString } from 'graphql/type'; + +const User = new GraphQLObjectType({ + name: 'User', + fields: { + name: { type: GraphQLString }, + }, +}); + +const config = User.toConfig(); +const UserCopy = new GraphQLObjectType(config); + +config.fields.name.type; // => GraphQLString +UserCopy.getFields().name.type; // => GraphQLString +``` + +
+ +##### toString() + +Returns the schema coordinate identifying this object type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema coordinate for this object type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertObjectType } from 'graphql/type'; + +const schema = buildSchema(` + type User { + name: String + } + + type Query { + viewer: User + } +`); + +const User = assertObjectType(schema.getType('User')); + +User.toString(); // => 'User' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { GraphQLObjectType, GraphQLString } from 'graphql/type'; + +const User = new GraphQLObjectType({ + name: 'User', + fields: { name: { type: GraphQLString } }, +}); + +User.toJSON(); // => 'User' +JSON.stringify({ type: User }); // => '{"type":"User"}' +``` + +
+ +#### GraphQLInterfaceType + +Interface Type Definition + +When a field can return one of a heterogeneous set of types, a Interface type +is used to describe what types are possible, what fields are in common across +all types, as well as a function to determine which type is actually used +when the field is resolved. + +
+ +
Example
+ +```ts +const EntityType = new GraphQLInterfaceType({ + name: 'Entity', + fields: { + name: { type: GraphQLString } + } +}); +``` + +
+ +##### Constructor + +Creates a GraphQLInterfaceType instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
configConfiguration describing this object.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
resolveTypeFunction that resolves the concrete object type for this abstract type.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
extensionASTNodesAST extension nodes applied to this schema element.
+ +
+ +##### getFields() + +Returns the fields defined by this type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The fields keyed by field name.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInterfaceType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Query { + node: Node + } +`); + +const Node = assertInterfaceType(schema.getType('Node')); +const fields = Node.getFields(); + +Object.keys(fields); // => ['id'] +String(fields.id.type); // => 'ID!' +``` + +
+ +##### getInterfaces() + +Returns the interfaces implemented by this type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The implemented interfaces.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInterfaceType } from 'graphql/type'; + +const schema = buildSchema(` + interface Resource { + url: String! + } + + interface Image implements Resource { + url: String! + width: Int + } + + type Photo implements Resource & Image { + url: String! + width: Int + } + + type Query { + image: Image + } +`); + +const Image = assertInterfaceType(schema.getType('Image')); + +Image.getInterfaces().map((type) => type.name); // => ['Resource'] +``` + +
+ +##### toConfig() + +Returns a normalized configuration object for this object. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this object.
+ +
+ +
Example
+ +```ts +import { GraphQLID, GraphQLInterfaceType, GraphQLNonNull } from 'graphql/type'; + +const Node = new GraphQLInterfaceType({ + name: 'Node', + fields: { + id: { type: new GraphQLNonNull(GraphQLID) }, + }, +}); + +const config = Node.toConfig(); +const NodeCopy = new GraphQLInterfaceType(config); + +String(config.fields.id.type); // => 'ID!' +String(NodeCopy.getFields().id.type); // => 'ID!' +``` + +
+ +##### toString() + +Returns the schema coordinate identifying this interface type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema coordinate for this interface type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInterfaceType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Query { + node: Node + } +`); + +const Node = assertInterfaceType(schema.getType('Node')); + +Node.toString(); // => 'Node' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { GraphQLInterfaceType, GraphQLString } from 'graphql/type'; + +const Named = new GraphQLInterfaceType({ + name: 'Named', + fields: { name: { type: GraphQLString } }, +}); + +Named.toJSON(); // => 'Named' +JSON.stringify({ type: Named }); // => '{"type":"Named"}' +``` + +
+ +#### GraphQLUnionType + +Union Type Definition + +When a field can return one of a heterogeneous set of types, a Union type +is used to describe what types are possible as well as providing a function +to determine which type is actually used when the field is resolved. + +
+ +
Example
+ +```ts +const PetType = new GraphQLUnionType({ + name: 'Pet', + types: [DogType, CatType], + resolveType: (value) => { + if (value instanceof Dog) { + return DogType; + } + if (value instanceof Cat) { + return CatType; + } + } +}); +``` + +
+ +##### Constructor + +Creates a GraphQLUnionType instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
configConfiguration describing this object.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
resolveTypeFunction that resolves the concrete object type for this abstract type.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
extensionASTNodesAST extension nodes applied to this schema element.
+ +
+ +##### getTypes() + +Returns the object types included in this union. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The union member object types.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertUnionType } from 'graphql/type'; + +const schema = buildSchema(` + type Photo { + url: String! + } + + type Video { + url: String! + } + + union Media = Photo | Video + + type Query { + media: [Media] + } +`); + +const Media = assertUnionType(schema.getType('Media')); + +Media.getTypes().map((type) => type.name); // => ['Photo', 'Video'] +``` + +
+ +##### toConfig() + +Returns a normalized configuration object for this object. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this object.
+ +
+ +
Example
+ +```ts +import { GraphQLObjectType, GraphQLString, GraphQLUnionType } from 'graphql/type'; + +const Photo = new GraphQLObjectType({ + name: 'Photo', + fields: { url: { type: GraphQLString } }, +}); +const Video = new GraphQLObjectType({ + name: 'Video', + fields: { url: { type: GraphQLString } }, +}); +const Media = new GraphQLUnionType({ + name: 'Media', + types: [Photo, Video], +}); + +const config = Media.toConfig(); +const MediaCopy = new GraphQLUnionType(config); + +MediaCopy.getTypes().map((type) => type.name); // => ['Photo', 'Video'] +``` + +
+ +##### toString() + +Returns the schema coordinate identifying this union type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema coordinate for this union type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertUnionType } from 'graphql/type'; + +const schema = buildSchema(` + type Photo { + url: String! + } + + union SearchResult = Photo + + type Query { + search: [SearchResult] + } +`); + +const SearchResult = assertUnionType(schema.getType('SearchResult')); + +SearchResult.toString(); // => 'SearchResult' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { GraphQLObjectType, GraphQLString, GraphQLUnionType } from 'graphql/type'; + +const Photo = new GraphQLObjectType({ + name: 'Photo', + fields: { url: { type: GraphQLString } }, +}); +const SearchResult = new GraphQLUnionType({ + name: 'SearchResult', + types: [Photo], +}); + +SearchResult.toJSON(); // => 'SearchResult' +JSON.stringify({ type: SearchResult }); // => '{"type":"SearchResult"}' +``` + +
+ +#### GraphQLEnumType + +Enum Type Definition + +Enum types define leaf values whose serialized form is one of a fixed set +of GraphQL enum names. Internally, enum values can map to any runtime value, +often integers. + +
+ +
Example
+ +```ts +import { GraphQLEnumType } from 'graphql/type'; + +const RGBType = new GraphQLEnumType({ + name: 'RGB', + values: { + RED: { value: 0 }, + GREEN: { value: 1 }, + BLUE: { value: 2 }, + }, +}); + +RGBType.getValue('GREEN')?.value; // => 1 +``` + +Note: If a value is not provided in a definition, the name of the enum value +will be used as its internal value. + +
+ +##### Constructor + +Creates a GraphQLEnumType instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
configConfiguration describing this object.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
extensionASTNodesAST extension nodes applied to this schema element.
+ +
+ +##### getValues() + +Returns the values defined by this enum type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Enum value definitions in schema order.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertEnumType } from 'graphql/type'; + +const schema = buildSchema(` + enum Episode { + NEW_HOPE + EMPIRE + JEDI + } + + type Query { + episode: Episode + } +`); + +const Episode = assertEnumType(schema.getType('Episode')); + +Episode.getValues().map((value) => value.name); // => ['NEW_HOPE', 'EMPIRE', 'JEDI'] +``` + +
+ +##### getValue() + +Returns the enum value definition for a value name. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name to look up.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The matching enum value definition, if it exists.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertEnumType } from 'graphql/type'; + +const schema = buildSchema(` + enum Episode { + NEW_HOPE + EMPIRE + } + + type Query { + episode: Episode + } +`); + +const Episode = assertEnumType(schema.getType('Episode')); + +Episode.getValue('EMPIRE')?.name; // => 'EMPIRE' +Episode.getValue('JEDI'); // => undefined +``` + +
+ +##### serialize() + +Serializes a runtime enum value as a GraphQL enum name. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
outputValueRuntime enum value to serialize.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The GraphQL enum name for the runtime value.
+ +
+ +
Example
+ +```ts +import { GraphQLEnumType } from 'graphql/type'; + +const RGB = new GraphQLEnumType({ + name: 'RGB', + values: { + RED: { value: 0 }, + GREEN: { value: 1 }, + BLUE: { value: 2 }, + }, +}); + +RGB.serialize(1); // => 'GREEN' +RGB.serialize(3); // throws an error +``` + +
+ +##### parseValue() + +Parses a GraphQL enum name from variable input. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
inputValueRuntime input value to parse.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The internal enum value represented by the input name.
+ +
+ +
Example
+ +```ts +import { GraphQLEnumType } from 'graphql/type'; + +const RGB = new GraphQLEnumType({ + name: 'RGB', + values: { + RED: { value: 0 }, + GREEN: { value: 1 }, + BLUE: { value: 2 }, + }, +}); + +RGB.parseValue('BLUE'); // => 2 +RGB.parseValue('PURPLE'); // throws an error +RGB.parseValue(2); // throws an error +``` + +
+ +##### parseLiteral() + +Parses a GraphQL enum name from an AST value literal. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
valueNodeAST value literal to parse.
_variablesRuntime variable values; ignored because enum literals cannot contain variables.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The internal enum value represented by the literal.
+ +
+ +
Example
+ +```ts +import { parseValue } from 'graphql/language'; +import { GraphQLEnumType } from 'graphql/type'; + +const RGB = new GraphQLEnumType({ + name: 'RGB', + values: { + RED: { value: 0 }, + GREEN: { value: 1 }, + BLUE: { value: 2 }, + }, +}); + +RGB.parseLiteral(parseValue('RED')); // => 0 +RGB.parseLiteral(parseValue('"RED"')); // throws an error +``` + +
+ +##### toConfig() + +Returns a normalized configuration object for this object. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this object.
+ +
+ +
Example
+ +```ts +import { GraphQLEnumType } from 'graphql/type'; + +const RGB = new GraphQLEnumType({ + name: 'RGB', + values: { + RED: { value: 0 }, + GREEN: { value: 1 }, + BLUE: { value: 2 }, + }, +}); + +const config = RGB.toConfig(); +const RGBCopy = new GraphQLEnumType(config); + +config.values.GREEN.value; // => 1 +RGBCopy.serialize(2); // => 'BLUE' +``` + +
+ +##### toString() + +Returns the schema coordinate identifying this enum type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema coordinate for this enum type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertEnumType } from 'graphql/type'; + +const schema = buildSchema(` + enum Episode { + NEW_HOPE + } + + type Query { + episode: Episode + } +`); + +const Episode = assertEnumType(schema.getType('Episode')); + +Episode.toString(); // => 'Episode' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { GraphQLEnumType } from 'graphql/type'; + +const Episode = new GraphQLEnumType({ + name: 'Episode', + values: { + NEW_HOPE: {}, + }, +}); + +Episode.toJSON(); // => 'Episode' +JSON.stringify({ type: Episode }); // => '{"type":"Episode"}' +``` + +
+ +#### GraphQLInputObjectType + +Input Object Type Definition + +An input object defines a structured collection of fields which may be +supplied to a field argument. + +Using `NonNull` will ensure that a value must be provided by the query + +
+ +
Example
+ +```ts +const GeoPoint = new GraphQLInputObjectType({ + name: 'GeoPoint', + fields: { + lat: { type: new GraphQLNonNull(GraphQLFloat) }, + lon: { type: new GraphQLNonNull(GraphQLFloat) }, + alt: { type: GraphQLFloat, defaultValue: 0 }, + } +}); +``` + +
+ +##### Constructor + +Creates a GraphQLInputObjectType instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
configConfiguration describing this object.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
extensionASTNodesAST extension nodes applied to this schema element.
isOneOfWhether this input object uses the experimental OneOf input object semantics.
+ +
+ +##### getFields() + +Returns the fields defined by this type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The fields keyed by field name.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInputObjectType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + commentary: String = "" + } + + type Query { + reviews(filter: ReviewInput): [String] + } +`); + +const ReviewInput = assertInputObjectType(schema.getType('ReviewInput')); +const fields = ReviewInput.getFields(); + +Object.keys(fields); // => ['stars', 'commentary'] +fields.commentary.defaultValue; // => '' +``` + +
+ +##### toConfig() + +Returns a normalized configuration object for this object. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this object.
+ +
+ +
Example
+ +```ts +import { + GraphQLInputObjectType, + GraphQLInt, + GraphQLNonNull, +} from 'graphql/type'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: { + stars: { type: new GraphQLNonNull(GraphQLInt) }, + }, +}); + +const config = ReviewInput.toConfig(); +const ReviewInputCopy = new GraphQLInputObjectType(config); + +String(config.fields.stars.type); // => 'Int!' +String(ReviewInputCopy.getFields().stars.type); // => 'Int!' +``` + +
+ +##### toString() + +Returns the schema coordinate identifying this input object type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema coordinate for this input object type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInputObjectType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + } + + type Query { + reviews(filter: ReviewInput): [String] + } +`); + +const ReviewInput = assertInputObjectType(schema.getType('ReviewInput')); + +ReviewInput.toString(); // => 'ReviewInput' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { GraphQLInputObjectType, GraphQLString } from 'graphql/type'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: { + commentary: { type: GraphQLString }, + }, +}); + +ReviewInput.toJSON(); // => 'ReviewInput' +JSON.stringify({ type: ReviewInput }); // => '{"type":"ReviewInput"}' +``` + +### Functions + +#### isType() + +Returns true when the value is any GraphQL type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is any GraphQL type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { GraphQLList, GraphQLString, isType } from 'graphql/type'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +isType(GraphQLString); // => true +isType(new GraphQLList(GraphQLString)); // => true +isType(schema.getType('Query')); // => true +isType('String'); // => false +``` + +
+ +#### assertType() + +Returns the value as a GraphQL type, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQL type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertType } from 'graphql/type'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const queryType = assertType(schema.getType('Query')); + +queryType.toString(); // => 'Query' +assertType('Query'); // throws an error +``` + +
+ +#### isScalarType() + +There are predicates for each kind of GraphQL type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLScalarType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isScalarType } from 'graphql/type'; + +const schema = buildSchema(` + scalar DateTime + + type Query { + createdAt: DateTime + } +`); + +isScalarType(schema.getType('DateTime')); // => true +isScalarType(schema.getType('Query')); // => false +``` + +
+ +#### assertScalarType() + +Returns the value as a GraphQLScalarType, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLScalarType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertScalarType } from 'graphql/type'; + +const schema = buildSchema(` + scalar DateTime + + type Query { + createdAt: DateTime + } +`); + +const dateTimeType = assertScalarType(schema.getType('DateTime')); + +dateTimeType.name; // => 'DateTime' +assertScalarType(schema.getType('Query')); // throws an error +``` + +
+ +#### isObjectType() + +Returns true when the value is a GraphQLObjectType. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLObjectType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isObjectType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + } + + type User { + name: String + } + + type Query { + user: User + } +`); + +isObjectType(schema.getType('User')); // => true +isObjectType(schema.getType('ReviewInput')); // => false +``` + +
+ +#### assertObjectType() + +Returns the value as a GraphQLObjectType, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLObjectType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertObjectType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + } + + type User { + name: String + } + + type Query { + user: User + } +`); + +const userType = assertObjectType(schema.getType('User')); + +Object.keys(userType.getFields()); // => ['name'] +assertObjectType(schema.getType('ReviewInput')); // throws an error +``` + +
+ +#### isInterfaceType() + +Returns true when the value is a GraphQLInterfaceType. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLInterfaceType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isInterfaceType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Query { + node: Node + } +`); + +isInterfaceType(schema.getType('Node')); // => true +isInterfaceType(schema.getType('User')); // => false +``` + +
+ +#### assertInterfaceType() + +Returns the value as a GraphQLInterfaceType, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLInterfaceType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInterfaceType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Query { + node: Node + } +`); + +const nodeType = assertInterfaceType(schema.getType('Node')); + +nodeType.name; // => 'Node' +assertInterfaceType(schema.getType('User')); // throws an error +``` + +
+ +#### isUnionType() + +Returns true when the value is a GraphQLUnionType. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLUnionType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isUnionType } from 'graphql/type'; + +const schema = buildSchema(` + type Photo { + url: String! + } + + type Video { + url: String! + } + + union Media = Photo | Video + + type Query { + media: [Media] + } +`); + +isUnionType(schema.getType('Media')); // => true +isUnionType(schema.getType('Photo')); // => false +``` + +
+ +#### assertUnionType() + +Returns the value as a GraphQLUnionType, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLUnionType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertUnionType } from 'graphql/type'; + +const schema = buildSchema(` + type Photo { + url: String! + } + + type Video { + url: String! + } + + union Media = Photo | Video + + type Query { + media: [Media] + } +`); + +const mediaType = assertUnionType(schema.getType('Media')); + +mediaType.getTypes().map((type) => type.name); // => ['Photo', 'Video'] +assertUnionType(schema.getType('Photo')); // throws an error +``` + +
+ +#### isEnumType() + +Returns true when the value is a GraphQLEnumType. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLEnumType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isEnumType } from 'graphql/type'; + +const schema = buildSchema(` + enum Episode { + NEW_HOPE + EMPIRE + } + + type Query { + favoriteEpisode: Episode + } +`); + +isEnumType(schema.getType('Episode')); // => true +isEnumType(schema.getType('Query')); // => false +``` + +
+ +#### assertEnumType() + +Returns the value as a GraphQLEnumType, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLEnumType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertEnumType } from 'graphql/type'; + +const schema = buildSchema(` + enum Episode { + NEW_HOPE + EMPIRE + } + + type Query { + favoriteEpisode: Episode + } +`); + +const episodeType = assertEnumType(schema.getType('Episode')); + +episodeType.getValues().map((value) => value.name); // => ['NEW_HOPE', 'EMPIRE'] +assertEnumType(schema.getType('Query')); // throws an error +``` + +
+ +#### isInputObjectType() + +Returns true when the value is a GraphQLInputObjectType. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLInputObjectType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isInputObjectType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + } + + type Review { + stars: Int! + } + + type Query { + review(input: ReviewInput): Review + } +`); + +isInputObjectType(schema.getType('ReviewInput')); // => true +isInputObjectType(schema.getType('Review')); // => false +``` + +
+ +#### assertInputObjectType() + +Returns the value as a GraphQLInputObjectType, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLInputObjectType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInputObjectType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + } + + type Review { + stars: Int! + } + + type Query { + review(input: ReviewInput): Review + } +`); + +const inputType = assertInputObjectType(schema.getType('ReviewInput')); + +Object.keys(inputType.getFields()); // => ['stars'] +assertInputObjectType(schema.getType('Review')); // throws an error +``` + +
+ +#### assertListType() + +Returns the value as a GraphQLList, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLList.
+ +
+ +
Example
+ +```ts +import { GraphQLList, GraphQLString, assertListType } from 'graphql/type'; + +const listType = assertListType(new GraphQLList(GraphQLString)); + +listType.ofType; // => GraphQLString +assertListType(GraphQLString); // throws an error +``` + +
+ +#### assertNonNullType() + +Returns the value as a GraphQLNonNull, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLNonNull.
+ +
+ +
Example
+ +```ts +import { GraphQLNonNull, GraphQLString, assertNonNullType } from 'graphql/type'; + +const nonNullType = assertNonNullType(new GraphQLNonNull(GraphQLString)); + +nonNullType.ofType; // => GraphQLString +assertNonNullType(GraphQLString); // throws an error +``` + +
+ +#### isInputType() + +Returns true when the value can be used as a GraphQL input type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value can be used as a GraphQL input type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isInputType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + } + + type Review { + stars: Int! + } + + type Query { + review(input: ReviewInput): Review + } +`); + +isInputType(schema.getType('ReviewInput')); // => true +isInputType(schema.getType('Review')); // => false +``` + +
+ +#### assertInputType() + +Returns the value as a GraphQL input type, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQL input type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInputType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + } + + type Review { + stars: Int! + } + + type Query { + review(input: ReviewInput): Review + } +`); + +const inputType = assertInputType(schema.getType('ReviewInput')); + +inputType.toString(); // => 'ReviewInput' +assertInputType(schema.getType('Review')); // throws an error +``` + +
+ +#### isOutputType() + +Returns true when the value can be used as a GraphQL output type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value can be used as a GraphQL output type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isOutputType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + } + + type Review { + stars: Int! + } + + type Query { + review(input: ReviewInput): Review + } +`); + +isOutputType(schema.getType('Review')); // => true +isOutputType(schema.getType('ReviewInput')); // => false +``` + +
+ +#### assertOutputType() + +Returns the value as a GraphQL output type, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQL output type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertOutputType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + } + + type Review { + stars: Int! + } + + type Query { + review(input: ReviewInput): Review + } +`); + +const outputType = assertOutputType(schema.getType('Review')); + +outputType.toString(); // => 'Review' +assertOutputType(schema.getType('ReviewInput')); // throws an error +``` + +
+ +#### isLeafType() + +Returns true when the value is a GraphQL scalar or enum type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQL scalar or enum type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isLeafType } from 'graphql/type'; + +const schema = buildSchema(` + enum Episode { + NEW_HOPE + } + + type Review { + stars: Int! + } + + type Query { + episode: Episode + review: Review + } +`); + +isLeafType(schema.getType('Episode')); // => true +isLeafType(schema.getType('String')); // => true +isLeafType(schema.getType('Review')); // => false +``` + +
+ +#### assertLeafType() + +Returns the value as a GraphQL leaf type, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQL leaf type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertLeafType } from 'graphql/type'; + +const schema = buildSchema(` + enum Episode { + NEW_HOPE + } + + type Review { + stars: Int! + } + + type Query { + episode: Episode + review: Review + } +`); + +const episodeType = assertLeafType(schema.getType('Episode')); + +episodeType.toString(); // => 'Episode' +assertLeafType(schema.getType('Review')); // throws an error +``` + +
+ +#### isCompositeType() + +Returns true when the value is a GraphQL object, interface, or union type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQL object, interface, or union type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isCompositeType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + union SearchResult = User + + type Query { + node: Node + search: [SearchResult] + } +`); + +isCompositeType(schema.getType('User')); // => true +isCompositeType(schema.getType('Node')); // => true +isCompositeType(schema.getType('SearchResult')); // => true +isCompositeType(schema.getType('String')); // => false +``` + +
+ +#### assertCompositeType() + +Returns the value as a GraphQL composite type, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQL composite type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertCompositeType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Query { + node: Node + } +`); + +const userType = assertCompositeType(schema.getType('User')); + +userType.toString(); // => 'User' +assertCompositeType(schema.getType('String')); // throws an error +``` + +
+ +#### isAbstractType() + +Returns true when the value is a GraphQL interface or union type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQL interface or union type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isAbstractType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + union SearchResult = User + + type Query { + node: Node + search: [SearchResult] + } +`); + +isAbstractType(schema.getType('Node')); // => true +isAbstractType(schema.getType('SearchResult')); // => true +isAbstractType(schema.getType('User')); // => false +``` + +
+ +#### assertAbstractType() + +Returns the value as a GraphQL abstract type, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQL abstract type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertAbstractType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Query { + node: Node + } +`); + +const nodeType = assertAbstractType(schema.getType('Node')); + +nodeType.toString(); // => 'Node' +assertAbstractType(schema.getType('User')); // throws an error +``` + +
+ +#### isWrappingType() + +Returns true when the value is a GraphQL list or non-null wrapper type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQL list or non-null wrapper type.
+ +
+ +
Example
+ +```ts +import { + GraphQLList, + GraphQLNonNull, + GraphQLString, + isWrappingType, +} from 'graphql/type'; + +isWrappingType(new GraphQLList(GraphQLString)); // => true +isWrappingType(new GraphQLNonNull(GraphQLString)); // => true +isWrappingType(GraphQLString); // => false +``` + +
+ +#### assertWrappingType() + +Returns the value as a GraphQL wrapping type, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQL wrapping type.
+ +
+ +
Example
+ +```ts +import { GraphQLList, GraphQLString, assertWrappingType } from 'graphql/type'; + +const wrappingType = assertWrappingType(new GraphQLList(GraphQLString)); + +wrappingType.toString(); // => '[String]' +assertWrappingType(GraphQLString); // throws an error +``` + +
+ +#### isNullableType() + +Returns true when the value is a GraphQL type that can accept null. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQL type that can accept null.
+ +
+ +
Example
+ +```ts +import { GraphQLNonNull, GraphQLString, isNullableType } from 'graphql/type'; + +isNullableType(GraphQLString); // => true +isNullableType(new GraphQLNonNull(GraphQLString)); // => false +isNullableType(null); // => false +``` + +
+ +#### assertNullableType() + +Returns the value as a nullable GraphQL type, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a nullable GraphQL type.
+ +
+ +
Example
+ +```ts +import { + GraphQLNonNull, + GraphQLString, + assertNullableType, +} from 'graphql/type'; + +const nullableType = assertNullableType(GraphQLString); + +nullableType; // => GraphQLString +assertNullableType(new GraphQLNonNull(GraphQLString)); // throws an error +``` + +
+ +#### isNamedType() + +Returns true when the value is a GraphQL named type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQL named type.
+ +
+ +
Example
+ +```ts +import { GraphQLList, GraphQLString, isNamedType } from 'graphql/type'; + +isNamedType(GraphQLString); // => true +isNamedType(new GraphQLList(GraphQLString)); // => false +isNamedType(null); // => false +``` + +
+ +#### assertNamedType() + +Returns the value as a GraphQL named type, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQL named type.
+ +
+ +
Example
+ +```ts +import { GraphQLList, GraphQLString, assertNamedType } from 'graphql/type'; + +const namedType = assertNamedType(GraphQLString); + +namedType.name; // => 'String' +assertNamedType(new GraphQLList(GraphQLString)); // throws an error +``` + +
+ +#### resolveReadonlyArrayThunk() + +Resolves a thunked readonly array. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TThe element type resolved from the thunk or array.
+ +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
thunkThe thunk or value to resolve.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The resolved readonly array.
+ +
+ +
Example
+ +```ts +import { GraphQLString, resolveReadonlyArrayThunk } from 'graphql/type'; + +const lazyFields = resolveReadonlyArrayThunk(() => [GraphQLString]); +const fields = resolveReadonlyArrayThunk([GraphQLString]); + +lazyFields; // => [GraphQLString] +fields; // => [GraphQLString] +``` + +
+ +#### resolveObjMapThunk() + +Resolves a thunked object map. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TThe object-map value type resolved from the thunk or map.
+ +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
thunkThe thunk or value to resolve.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The resolved object map.
+ +
+ +
Example
+ +```ts +import { GraphQLString, resolveObjMapThunk } from 'graphql/type'; + +const lazyFields = resolveObjMapThunk(() => ({ name: GraphQLString })); +const fields = resolveObjMapThunk({ name: GraphQLString }); + +lazyFields.name; // => GraphQLString +fields.name; // => GraphQLString +``` + +
+ +#### isRequiredArgument() + +Returns true when the argument is non-null and has no default value. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
argThe argument definition to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the argument is non-null and has no default value.
+ +
+ +
Example
+ +```ts +import { + GraphQLInt, + GraphQLNonNull, + GraphQLString, + isRequiredArgument, +} from 'graphql/type'; + +const requiredArgument = { name: 'id', type: new GraphQLNonNull(GraphQLInt) }; +const optionalArgument = { name: 'name', type: GraphQLString }; +const argumentWithDefault = { + name: 'limit', + type: new GraphQLNonNull(GraphQLInt), + defaultValue: 10, +}; + +isRequiredArgument(requiredArgument); // => true +isRequiredArgument(optionalArgument); // => false +isRequiredArgument(argumentWithDefault); // => false +``` + +
+ +#### isRequiredInputField() + +Returns true when the input field is non-null and has no default value. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
fieldThe input field definition to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the input field is non-null and has no default value.
+ +
+ +
Example
+ +```ts +import { + GraphQLInt, + GraphQLNonNull, + GraphQLString, + isRequiredInputField, +} from 'graphql/type'; + +const requiredField = { name: 'id', type: new GraphQLNonNull(GraphQLInt) }; +const optionalField = { name: 'name', type: GraphQLString }; +const fieldWithDefault = { + name: 'limit', + type: new GraphQLNonNull(GraphQLInt), + defaultValue: 10, }; + +isRequiredInputField(requiredField); // => true +isRequiredInputField(optionalField); // => false +isRequiredInputField(fieldWithDefault); // => false +``` + +### Types + +#### GraphQLType + +**Type alias.** These are all of the possible kinds of types. + + + +
+ +#### GraphQLInputType + +**Type alias.** These types may be used as input types for arguments and directives. + + + +
+ +#### GraphQLOutputType + +**Type alias.** These types may be used as output types as the result of fields. + + + +
+ +#### GraphQLLeafType + +**Type alias.** These types may describe types which may be leaf values. + + + +
+ +#### GraphQLCompositeType + +**Type alias.** These types may describe the parent context of a selection set. + + + +
+ +#### GraphQLAbstractType + +**Type alias.** These types may describe the parent context of a selection set. + + + +
+ +#### GraphQLWrappingType + +**Type alias.** These types wrap and modify other types + + + +
+ +#### GraphQLNullableType + +**Type alias.** These types can all accept null as a value. + + + +
+ +#### GraphQLNamedType + +**Type alias.** These named types do not include modifiers like List or NonNull. + + + +
+ +#### GraphQLNamedInputType + +**Type alias.** A named GraphQL type that can be used as an input type. + + + +
+ +#### GraphQLNamedOutputType + +**Type alias.** A named GraphQL type that can be used as an output type. + + + +
+ +#### ThunkReadonlyArray + +**Type alias.** Used while defining GraphQL types to allow for circular references in +otherwise immutable type definitions. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TThe element type returned by the thunk or array.
+ + + +
+ +#### ThunkObjMap + +**Type alias.** A thunk that resolves to an object map. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TValue type stored in the object map.
+ + + +
+ +#### GraphQLScalarTypeExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLScalarSerializer + +**Type alias.** Serializes a runtime value as a scalar output value. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TExternalThe serialized representation returned for GraphQL results.
+ + + +
+ +#### GraphQLScalarValueParser + +**Type alias.** Parses a runtime input value as a scalar input value. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TInternalThe internal runtime representation produced from variable input.
+ + + +
+ +#### GraphQLScalarLiteralParser + +**Type alias.** Parses a GraphQL value literal as a scalar input value. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TInternalThe internal runtime representation produced from literal input.
+ + + +
+ +#### GraphQLScalarTypeConfig + +**Interface.** Configuration used to construct a GraphQLScalarType. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TInternalThe internal runtime representation accepted by this scalar.
TExternalThe serialized representation exposed in GraphQL results.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
specifiedByURL?URL identifying the behavior specified for this custom scalar.
serialize?Serializes an internal value to include in a response.
parseValue?Parses an externally provided value to use as an input.
parseLiteral?Parses an externally provided literal value to use as an input.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
extensionASTNodes?AST extension nodes applied to this schema element.
+ +
+ +#### GraphQLObjectTypeExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. +We've provided these template arguments because this is an open type and +you may find them useful. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
_TSourceReserved source type parameter for extension typing.
_TContextReserved context type parameter for extension typing.
+ +
+ +#### GraphQLObjectTypeConfig + +**Interface.** Configuration used to construct a GraphQLObjectType. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
interfaces?Interfaces implemented by this object or interface type.
fieldsFields declared by this object, interface, input object, or literal.
isTypeOf?Predicate used to determine whether a runtime value belongs to this object type.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
extensionASTNodes?AST extension nodes applied to this schema element.
+ +
+ +#### GraphQLTypeResolver + +**Type alias.** Resolves the concrete object type for an abstract GraphQL type. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
+ + + +
+ +#### GraphQLIsTypeOfFn + +**Type alias.** Checks whether a runtime value belongs to a GraphQL object type. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type tested against this object type.
TContextContext object type passed to resolvers.
+ + + +
+ +#### GraphQLFieldResolver + +**Type alias.** Resolves the runtime value for a GraphQL field. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
TArgsArgument object type passed to resolvers.
TResultResult value type.
+ + + +
+ +#### GraphQLResolveInfo + +**Interface.** Information about the currently executing GraphQL field. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
fieldNameThe field name referenced by this schema coordinate.
fieldNodesAST field nodes that contributed to the current field execution.
returnTypeGraphQL output type declared for the current field.
parentTypeObject type that owns the current field.
pathResponse path where this error occurred during execution.
schemaThe schema used for validation or execution.
fragmentsFragment definitions in the operation document keyed by fragment name.
rootValueInitial root value passed to the operation.
operationThe operation selected for execution.
variableValuesRuntime variable values keyed by variable name.
+ +
+ +#### GraphQLFieldExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. +We've provided these template arguments because this is an open type and +you may find them useful. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
_TSourceReserved source type parameter for extension typing.
_TContextReserved context type parameter for extension typing.
_TArgsReserved argument type parameter for extension typing.
+ +
+ +#### GraphQLFieldConfig + +**Interface.** Configuration used to define a GraphQL field. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
TArgsArgument object type passed to resolvers.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
description?Human-readable description for this schema element, if provided.
typeThe GraphQL type reference or runtime type for this element.
args?Arguments accepted by this field or directive.
resolve?Resolver function used to produce this field value.
subscribe?Resolver function used to create a subscription event stream for this field.
deprecationReason?Reason this element is deprecated, if one was provided.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
+ +
+ +#### GraphQLFieldConfigArgumentMap + +**Type alias.** A map of argument names to argument configuration objects. + + + +
+ +#### GraphQLArgumentExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLArgumentConfig + +**Interface.** Configuration used to define a GraphQL argument. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
description?Human-readable description for this schema element, if provided.
typeThe GraphQL type reference or runtime type for this element.
defaultValue?Default value used when no explicit value is supplied.
deprecationReason?Reason this element is deprecated, if one was provided.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
+ +
+ +#### GraphQLFieldConfigMap + +**Type alias.** A map of field names to field configuration objects. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
+ + + +
+ +#### GraphQLField + +**Interface.** A resolved GraphQL field definition. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
TArgsArgument object type passed to resolvers.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
typeThe GraphQL type reference or runtime type for this element.
argsArguments accepted by this field or directive.
resolve?Resolver function used to produce this field value.
subscribe?Resolver function used to create a subscription event stream for this field.
deprecationReasonReason this element is deprecated, if one was provided.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
+ +
+ +#### GraphQLArgument + +**Interface.** A resolved GraphQL argument definition. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
typeThe GraphQL type reference or runtime type for this element.
defaultValueDefault value used when no explicit value is supplied.
deprecationReasonReason this element is deprecated, if one was provided.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
+ +
+ +#### GraphQLFieldMap + +**Type alias.** A map of field names to resolved field definitions. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
+ + + +
+ +#### GraphQLInterfaceTypeExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLInterfaceTypeConfig + +**Interface.** Configuration used to construct a GraphQLInterfaceType. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
interfaces?Interfaces implemented by this object or interface type.
fieldsFields declared by this object, interface, input object, or literal.
resolveType?Optionally provide a custom type resolver function. If one is not provided,
+the default implementation will call {"isTypeOf"} on each implementing
+Object type.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
extensionASTNodes?AST extension nodes applied to this schema element.
+ +
+ +#### GraphQLUnionTypeExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLUnionTypeConfig + +**Interface.** Configuration used to construct a GraphQLUnionType. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
typesObject types that belong to this union type.
resolveType?Optionally provide a custom type resolver function. If one is not provided,
+the default implementation will call {"isTypeOf"} on each implementing
+Object type.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
extensionASTNodes?AST extension nodes applied to this schema element.
+ +
+ +#### GraphQLEnumTypeExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLEnumTypeConfig + +**Interface.** Configuration used to construct a GraphQLEnumType. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
valuesValues contained in this enum, list, or input-object definition.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
extensionASTNodes?AST extension nodes applied to this schema element.
+ +
+ +#### GraphQLEnumValueConfigMap + +**Type alias.** A map of enum value names to enum value configuration objects. + + + +
+ +#### GraphQLEnumValueExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLEnumValueConfig + +**Interface.** Configuration used to define a GraphQL enum value. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
description?Human-readable description for this schema element, if provided.
value?Parsed value represented by this node.
deprecationReason?Reason this element is deprecated, if one was provided.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
+ +
+ +#### GraphQLEnumValue + +**Interface.** A resolved GraphQL enum value definition. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
valueParsed value represented by this node.
deprecationReasonReason this element is deprecated, if one was provided.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
+ +
+ +#### GraphQLInputObjectTypeExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLInputObjectTypeConfig + +**Interface.** Configuration used to construct a GraphQLInputObjectType. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
fieldsFields declared by this object, interface, input object, or literal.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
extensionASTNodes?AST extension nodes applied to this schema element.
isOneOf?Whether this input object uses the experimental OneOf input object semantics.
+ +
+ +#### GraphQLInputFieldExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLInputFieldConfig + +**Interface.** Configuration used to define a GraphQL input field. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
description?Human-readable description for this schema element, if provided.
typeThe GraphQL type reference or runtime type for this element.
defaultValue?Default value used when no explicit value is supplied.
deprecationReason?Reason this element is deprecated, if one was provided.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
+ +
+ +#### GraphQLInputFieldConfigMap + +**Type alias.** A map of input field names to input field configuration objects. + + + +
+ +#### GraphQLInputField + +**Interface.** A resolved GraphQL input field definition. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
typeThe GraphQL type reference or runtime type for this element.
defaultValueDefault value used when no explicit value is supplied.
deprecationReasonReason this element is deprecated, if one was provided.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
+ +
+ +#### GraphQLInputFieldMap + +**Type alias.** A map of input field names to resolved input field definitions. + + + +## Category: Directives + + + +### Classes + +#### GraphQLDirective + +Directives are used by the GraphQL runtime as a way of modifying execution +behavior. Type system creators will usually not create these directly. + +
+ +##### Constructor + +Creates a GraphQLDirective instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
configConfiguration describing this object.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
locationsLocations where this directive may be applied.
argsArguments accepted by this field or directive.
isRepeatableWhether this directive may appear more than once at the same location.
deprecationReasonReason this element is deprecated, if one was provided.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
extensionASTNodesAST extension nodes applied to this schema element.
+ +
+ +##### toConfig() + +Returns a normalized configuration object for this object. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this object.
+ +
+ +
Example
+ +```ts +import { DirectiveLocation } from 'graphql/language'; +import { GraphQLDirective, GraphQLString } from 'graphql/type'; + +const tag = new GraphQLDirective({ + name: 'tag', + locations: [DirectiveLocation.FIELD_DEFINITION], + args: { + name: { type: GraphQLString }, + }, +}); + +const config = tag.toConfig(); +const tagCopy = new GraphQLDirective(config); + +config.args.name.type; // => GraphQLString +tagCopy.args[0].name; // => 'name' +``` + +
+ +##### toString() + +Returns the schema coordinate identifying this directive. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The directive schema coordinate.
+ +
+ +
Example
+ +```ts +import { DirectiveLocation } from 'graphql/language'; +import { GraphQLDirective } from 'graphql/type'; + +const tag = new GraphQLDirective({ + name: 'tag', + locations: [DirectiveLocation.FIELD_DEFINITION], +}); + +tag.toString(); // => '@tag' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { DirectiveLocation } from 'graphql/language'; +import { GraphQLDirective } from 'graphql/type'; + +const tag = new GraphQLDirective({ + name: 'tag', + locations: [DirectiveLocation.FIELD_DEFINITION], +}); + +tag.toJSON(); // => '@tag' +JSON.stringify({ directive: tag }); // => '{"directive":"@tag"}' +``` + +### Functions + +#### isDirective() + +Test if the given value is a GraphQL directive. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
directiveValue to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLDirective.
+ +
+ +
Example
+ +```ts +import { DirectiveLocation } from 'graphql/language'; +import { GraphQLDirective, GraphQLString, isDirective } from 'graphql/type'; + +const upper = new GraphQLDirective({ + name: 'upper', + locations: [DirectiveLocation.FIELD_DEFINITION], +}); + +isDirective(upper); // => true +isDirective(GraphQLString); // => false +``` + +
+ +#### assertDirective() + +Returns the value as a GraphQLDirective, or throws if it is not a directive. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
directiveValue to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLDirective.
+ +
+ +
Example
+ +```ts +import { DirectiveLocation } from 'graphql/language'; +import { assertDirective, GraphQLDirective, GraphQLString } from 'graphql/type'; + +const upper = new GraphQLDirective({ + name: 'upper', + locations: [DirectiveLocation.FIELD_DEFINITION], +}); + +assertDirective(upper); // => upper +assertDirective(GraphQLString); // throws an error +``` + +
+ +#### isSpecifiedDirective() + +Returns true when the directive is one of the directives specified by GraphQL. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
directiveDirective to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the directive is specified by GraphQL.
+ +
+ +
Example
+ +```ts +import { + GraphQLDirective, + GraphQLIncludeDirective, + isSpecifiedDirective, +} from 'graphql/type'; +import { DirectiveLocation } from 'graphql/language'; + +const customDirective = new GraphQLDirective({ + name: 'auth', + locations: [DirectiveLocation.FIELD_DEFINITION], +}); + +isSpecifiedDirective(GraphQLIncludeDirective); // => true +isSpecifiedDirective(customDirective); // => false +``` + +### Constants + +#### GraphQLIncludeDirective + +Used to conditionally include fields or fragments. + +
+ +
Type
+ + + +
+ +#### GraphQLSkipDirective + +Used to conditionally skip (exclude) fields or fragments. + +
+ +
Type
+ + + +
+ +#### DEFAULT_DEPRECATION_REASON + +Constant string used for default reason for a deprecation. + +
+ +
Type
+ + + +
+ +#### GraphQLDeprecatedDirective + +Used to declare element of a GraphQL schema as deprecated. + +The optional `reason` argument defaults to [`DEFAULT_DEPRECATION_REASON`](/api-v16/type#default_deprecation_reason). + +
+ +
Type
+ + + +
+ +#### GraphQLSpecifiedByDirective + +Used to provide a URL for specifying the behavior of custom scalar definitions. + +
+ +
Type
+ + + +
+ +#### GraphQLOneOfDirective + +Used to indicate an Input Object is a OneOf Input Object. + +
+ +
Type
+ + + +
+ +#### specifiedDirectives + +Full list of stable directives specified by GraphQL.js. + +
+ +
Type
+ + + +### Types + +#### GraphQLDirectiveExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLDirectiveConfig + +**Interface.** Configuration used to construct a GraphQLDirective. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
locationsLocations where this directive may be applied.
args?Arguments accepted by this field or directive.
isRepeatable?Whether this directive may appear more than once at the same location.
deprecationReason?Reason this element is deprecated, if one was provided.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
extensionASTNodes?AST extension nodes applied to this schema element.
+ +## Category: Introspection + +
+

+ Functions:
+ isIntrospectionType() +

+

+ Constants:
+ __Schema + + __Directive + + __DirectiveLocation + + __Type + + __Field + + __InputValue + + __EnumValue + + __TypeKind + + SchemaMetaFieldDef + + TypeMetaFieldDef + + TypeNameMetaFieldDef + + introspectionTypes +

+

+ Enumerations:
+ TypeKind +

+
+ +### Functions + +#### isIntrospectionType() + +Returns true when the type is one of the built-in introspection types. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the type is one of the built-in introspection types.
+ +
+ +
Example
+ +```ts +import { GraphQLString, isIntrospectionType, __Type } from 'graphql/type'; + +isIntrospectionType(__Type); // => true +isIntrospectionType(GraphQLString); // => false +``` + +### Constants + +#### __Schema + +The introspection type describing a GraphQL schema. + +
+ +
Type
+ + + +
+ +#### __Directive + +The introspection type describing a GraphQL directive. + +
+ +
Type
+ + + +
+ +#### __DirectiveLocation + +The introspection enum describing directive locations. + +
+ +
Type
+ + + +
+ +#### __Type + +The introspection type describing GraphQL types. + +
+ +
Type
+ + + +
+ +#### __Field + +The introspection type describing object and interface fields. + +
+ +
Type
+ + + +
+ +#### __InputValue + +The introspection type describing arguments and input fields. + +
+ +
Type
+ + + +
+ +#### __EnumValue + +The introspection type describing enum values. + +
+ +
Type
+ + + +
+ +#### __TypeKind + +The introspection enum describing GraphQL type kinds. + +
+ +
Type
+ + + +
+ +#### SchemaMetaFieldDef + +Note that these are GraphQLField and not GraphQLFieldConfig, +so the format for args is different. + +
+ +
Type
+ + + +
+ +#### TypeMetaFieldDef + +The `__type` meta field definition used by introspection. + +
+ +
Type
+ + + +
+ +#### TypeNameMetaFieldDef + +The `__typename` meta field definition used by execution and introspection. + +
+ +
Type
+ + + +
+ +#### introspectionTypes + +All introspection types defined by the GraphQL specification. + +
+ +
Type
+ + + +### Enumerations + +#### TypeKind + +**Enumeration.** The introspection enum describing the different kinds of GraphQL types. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameValueDescription
{"SCALAR"}{"\"SCALAR\""}A scalar type.
{"OBJECT"}{"\"OBJECT\""}An object type.
{"INTERFACE"}{"\"INTERFACE\""}An interface type.
{"UNION"}{"\"UNION\""}A union type.
{"ENUM"}{"\"ENUM\""}An enum type.
{"INPUT_OBJECT"}{"\"INPUT_OBJECT\""}An input object type.
{"LIST"}{"\"LIST\""}A list wrapper type.
{"NON_NULL"}{"\"NON_NULL\""}A non-null wrapper type.
+ +## Category: Scalars + +
+

+ Functions:
+ isSpecifiedScalarType() +

+

+ Constants:
+ GRAPHQL_MAX_INT + + GRAPHQL_MIN_INT + + GraphQLInt + + GraphQLFloat + + GraphQLString + + GraphQLBoolean + + GraphQLID + + specifiedScalarTypes +

+
+ +### Functions + +#### isSpecifiedScalarType() + +Returns true when the scalar type is one of the scalars specified by GraphQL. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the scalar type is one of the scalars specified by GraphQL.
+ +
+ +
Example
+ +```ts +import { + GraphQLScalarType, + GraphQLString, + isSpecifiedScalarType, +} from 'graphql/type'; + +const DateTime = new GraphQLScalarType({ + name: 'DateTime', +}); + +isSpecifiedScalarType(GraphQLString); // => true +isSpecifiedScalarType(DateTime); // => false +``` + +### Constants + +#### GRAPHQL_MAX_INT + +Maximum possible Int value as per GraphQL Spec (32-bit signed integer). +n.b. This differs from JavaScript's numbers that are IEEE 754 doubles safe up-to 2^53 - 1 + +
+ +
Type
+ + + +
+ +#### GRAPHQL_MIN_INT + +Minimum possible Int value as per GraphQL Spec (32-bit signed integer). +n.b. This differs from JavaScript's numbers that are IEEE 754 doubles safe starting at -(2^53 - 1) + +
+ +
Type
+ + + +
+ +#### GraphQLInt + +The built-in `Int` scalar type. + +
+ +
Type
+ + + +
+ +#### GraphQLFloat + +The built-in `Float` scalar type. + +
+ +
Type
+ + + +
+ +#### GraphQLString + +The built-in `String` scalar type. + +
+ +
Type
+ + + +
+ +#### GraphQLBoolean + +The built-in `Boolean` scalar type. + +
+ +
Type
+ + + +
+ +#### GraphQLID + +The built-in `ID` scalar type. + +
+ +
Type
+ + + +
+ +#### specifiedScalarTypes + +All built-in scalar types defined by the GraphQL specification. + +
+ +
Type
+ + + +## Category: Schema + +
+

+ Classes:
+ GraphQLSchema +

+

+ Functions:
+ isSchema() + + assertSchema() +

+

+ Types:
+ GraphQLSchemaExtensions + + GraphQLSchemaConfig +

+
+ +### Classes + +#### GraphQLSchema + +Schema Definition + +A Schema is created by supplying the root types of each type of operation, +query and mutation (optional). A schema definition is then supplied to the +validator and executor. + +
+ +
Example 1
+ +```ts +const MyAppQueryRootType = new GraphQLObjectType({ + name: 'Query', + fields: { + greeting: { type: GraphQLString }, + }, +}); + +const MyAppMutationRootType = new GraphQLObjectType({ + name: 'Mutation', + fields: { + setGreeting: { type: GraphQLString }, + }, +}); + +const MyAppSchema = new GraphQLSchema({ + query: MyAppQueryRootType, + mutation: MyAppMutationRootType, +}); +``` + +
+ +
Example 2
+ +When the schema is constructed, by default only the types that are reachable +by traversing the root types are included, other types must be explicitly +referenced. + +```ts +const characterInterface = new GraphQLInterfaceType({ + name: 'Character', + fields: { + name: { type: GraphQLString }, + }, +}); + +const humanType = new GraphQLObjectType({ + name: 'Human', + interfaces: [characterInterface], + fields: { + name: { type: GraphQLString }, + }, +}); + +const droidType = new GraphQLObjectType({ + name: 'Droid', + interfaces: [characterInterface], + fields: { + name: { type: GraphQLString }, + }, +}); + +const schema = new GraphQLSchema({ + query: new GraphQLObjectType({ + name: 'Query', + fields: { + hero: { type: characterInterface }, + }, + }), + // Since this schema references only the `Character` interface it's + // necessary to explicitly list the types that implement it if + // you want them to be included in the final schema. + types: [humanType, droidType], +}); ``` -A Schema is created by supplying the root types of each type of operation, -query and mutation (optional). A schema definition is then supplied to the -validator and executor. +
+ +
Example 3
-#### Example +If an array of `directives` are provided to GraphQLSchema, that will be the +exact list of directives represented and allowed. If `directives` is not +provided then a default set of the specified directives (e.g. `@include` and +`@skip`) will be used. If you wish to provide *additional* directives to +these specified directives, you must explicitly declare them. -```js +```ts const MyAppSchema = new GraphQLSchema({ query: MyAppQueryRootType, - mutation: MyAppMutationRootType, + directives: specifiedDirectives.concat([myCustomDirective]), }); ``` -## Definitions - -### GraphQLScalarType +
+ +##### Constructor + +Creates a GraphQLSchema instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
configConfiguration describing this object.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
descriptionHuman-readable description for this schema element, if provided.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
extensionASTNodesAST extension nodes applied to this schema element.
+ +
+ +##### getQueryType() + +Returns the root object type for query operations. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The query root type, if this schema defines one.
+ +
+ +
Example
```ts -class GraphQLScalarType { - constructor(config: GraphQLScalarTypeConfig); -} +import { buildSchema } from 'graphql/utilities'; -type GraphQLScalarTypeConfig = { - name: string; - description?: string; - specifiedByURL?: Maybe; - serialize: (outputValue: unknown) => ExternalType; - parseValue?: (inputValue: unknown) => InternalType; - parseLiteral?: ( - valueAST: Value, - variables?: Maybe>, - ) => InternalType; -}; +const schema = buildSchema(` + type Query { + greeting: String + } +`); + +schema.getQueryType()?.name; // => 'Query' ``` -The leaf values of any request and input values to arguments are -Scalars (or Enums) and are defined with a name and a series of serialization -functions used to ensure validity. +
-#### Example +##### getMutationType() -```js -const OddType = new GraphQLScalarType({ - name: 'Odd', - // Can be used to link to a specification - // for this scalar, for instance the JSON - // specification. - specifiedByURL: '', - description: - 'This custom scalar will only return a value if the passed in value is an odd integer, when it's not it will return null.' - serialize: (outputValue) => { - // This function gets called for response-data, the application returns data - // for a property and in the schema we see that this value has the "Odd" type. - return typeof outputValue === 'number' && outputValue % 2 === 1 ? value : null; - }, - parseValue: (inputValue) => { - // This function gets called for input-data, i.e. variables being passed in - return typeof inputValue === 'number' && outputValue % 2 === 1 ? value : null; - }, - parseLiteral(ast) { - // This function gets called when the value is passed in as a literal on the - // Executable GraphQL Document - if (ast.kind === Kind.INT) { - return oddValue(parseInt(ast.value, 10)); - } - return null; - }, -}); -``` +Returns the root object type for mutation operations. -### GraphQLObjectType +**Signature:** -```ts -class GraphQLObjectType { - constructor(config: GraphQLObjectTypeConfig); -} + -type GraphQLObjectTypeConfig = { - name: string; - interfaces?: GraphQLInterfacesThunk | GraphQLInterfaceType[]; - fields: GraphQLFieldConfigMapThunk | GraphQLFieldConfigMap; - isTypeOf?: (value: any, info?: GraphQLResolveInfo) => boolean; - description?: string; -}; +
-type GraphQLInterfacesThunk = () => Array; - -type GraphQLFieldConfigMapThunk = () => GraphQLFieldConfigMap; - -// See below about resolver functions. -type GraphQLFieldResolveFn = ( - source?: any, - args?: { [argName: string]: any }, - context?: any, - info?: GraphQLResolveInfo, -) => any; - -type GraphQLResolveInfo = { - fieldName: string; - fieldNodes: Array; - returnType: GraphQLOutputType; - parentType: GraphQLCompositeType; - schema: GraphQLSchema; - fragments: { [fragmentName: string]: FragmentDefinition }; - rootValue: any; - operation: OperationDefinition; - variableValues: { [variableName: string]: any }; -}; +
Returns
-type GraphQLFieldConfig = { - type: GraphQLOutputType; - args?: GraphQLFieldConfigArgumentMap; - resolve?: GraphQLFieldResolveFn; - deprecationReason?: string; - description?: string; -}; + + + + + + + + + + + + + +
TypeDescription
The mutation root type, if this schema defines one.
-type GraphQLFieldConfigArgumentMap = { - [argName: string]: GraphQLArgumentConfig; -}; +
-type GraphQLArgumentConfig = { - type: GraphQLInputType; - defaultValue?: any; - description?: string; -}; +
Example
-type GraphQLFieldConfigMap = { - [fieldName: string]: GraphQLFieldConfig; -}; +```ts +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } + + type Mutation { + setGreeting(value: String!): String + } +`); + +schema.getMutationType()?.name; // => 'Mutation' ``` -Almost all of the GraphQL types you define will be object types. Object types -have a name, but most importantly describe their fields. +
-When two types need to refer to each other, or a type needs to refer to -itself in a field, you can use a function expression (aka a closure or a -thunk) to supply the fields lazily. +##### getSubscriptionType() -Note that resolver functions are provided the `source` object as the first parameter. -However, if a resolver function is not provided, then the default resolver is -used, which looks for a method on `source` of the same name as the field. If found, -the method is called with `(args, context, info)`. Since it is a method on `source`, -that value can always be referenced with `this`. +Returns the root object type for subscription operations. -#### Examples +**Signature:** -```js -const AddressType = new GraphQLObjectType({ - name: 'Address', - fields: { - street: { type: GraphQLString }, - number: { type: GraphQLInt }, - formatted: { - type: GraphQLString, - resolve(obj) { - return obj.number + ' ' + obj.street; - }, - }, - }, -}); + -const PersonType = new GraphQLObjectType({ - name: 'Person', - fields: () => ({ - name: { type: GraphQLString }, - bestFriend: { type: PersonType }, - }), -}); -``` +
+ +
Returns
-### GraphQLInterfaceType + + + + + + + + + + + + + +
TypeDescription
The subscription root type, if this schema defines one.
+ +
+ +
Example
```ts -class GraphQLInterfaceType { - constructor(config: GraphQLInterfaceTypeConfig); -} +import { buildSchema } from 'graphql/utilities'; -type GraphQLInterfaceTypeConfig = { - name: string; - fields: GraphQLFieldConfigMapThunk | GraphQLFieldConfigMap; - resolveType?: (value: any, info?: GraphQLResolveInfo) => GraphQLObjectType; - description?: string; -}; +const schema = buildSchema(` + type Query { + greeting: String + } + + type Subscription { + greetings: String + } +`); + +schema.getSubscriptionType()?.name; // => 'Subscription' ``` -When a field can return one of a heterogeneous set of types, a Interface type -is used to describe what types are possible, what fields are in common across -all types, as well as a function to determine which type is actually used -when the field is resolved. +
-#### Example +##### getRootType() -```js -const EntityType = new GraphQLInterfaceType({ - name: 'Entity', - fields: { - name: { type: GraphQLString }, - }, -}); -``` +Returns the root object type for the requested operation kind. -### GraphQLUnionType +**Signature:** -```ts -class GraphQLUnionType { - constructor(config: GraphQLUnionTypeConfig); -} + -type GraphQLUnionTypeConfig = { - name: string; - types: GraphQLObjectsThunk | GraphQLObjectType[]; - resolveType?: (value: any, info?: GraphQLResolveInfo) => GraphQLObjectType; - description?: string; -}; +
-type GraphQLObjectsThunk = () => GraphQLObjectType[]; -``` +
Arguments
-When a field can return one of a heterogeneous set of types, a Union type -is used to describe what types are possible as well as providing a function -to determine which type is actually used when the field is resolved. + + + + + + + + + + + + + + + +
NameTypeDescription
operationOperation kind to resolve.
-### Example +
-```js -const PetType = new GraphQLUnionType({ - name: 'Pet', - types: [DogType, CatType], - resolveType(value) { - if (value instanceof Dog) { - return DogType; - } - if (value instanceof Cat) { - return CatType; - } - }, -}); -``` +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The root object type for the operation kind, if this schema defines one.
+ +
-### GraphQLEnumType +
Example
```ts -class GraphQLEnumType { - constructor(config: GraphQLEnumTypeConfig); -} +import { OperationTypeNode } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } + + type Mutation { + setGreeting(value: String!): String + } +`); + +schema.getRootType(OperationTypeNode.QUERY)?.name; // => 'Query' +schema.getRootType(OperationTypeNode.MUTATION)?.name; // => 'Mutation' +schema.getRootType(OperationTypeNode.SUBSCRIPTION); // => undefined +``` -type GraphQLEnumTypeConfig = { - name: string; - values: GraphQLEnumValueConfigMap; - description?: string; -}; +
-type GraphQLEnumValueConfigMap = { - [valueName: string]: GraphQLEnumValueConfig; -}; +##### getTypeMap() -type GraphQLEnumValueConfig = { - value?: any; - deprecationReason?: string; - description?: string; -}; +Returns all named types known to this schema. -type GraphQLEnumValueDefinition = { - name: string; - value?: any; - deprecationReason?: string; - description?: string; -}; -``` +**Signature:** -Some leaf values of requests and input values are Enums. GraphQL serializes -Enum values as strings, however internally Enums can be represented by any -kind of type, often integers. + -Note: If a value is not provided in a definition, the name of the enum value -will be used as its internal value. +
-#### Example +
Returns
-```js -const RGBType = new GraphQLEnumType({ - name: 'RGB', - values: { - RED: { value: 0 }, - GREEN: { value: 1 }, - BLUE: { value: 2 }, - }, -}); -``` + + + + + + + + + + + + + +
TypeDescription
A map of schema types keyed by type name.
+ +
-### GraphQLInputObjectType +
Example
```ts -class GraphQLInputObjectType { - constructor(config: GraphQLInputObjectConfig); -} +import { buildSchema } from 'graphql/utilities'; -type GraphQLInputObjectConfig = { - name: string; - fields: - | GraphQLInputObjectConfigFieldMapThunk - | GraphQLInputObjectConfigFieldMap; - description?: string; -}; +const schema = buildSchema(` + type User { + name: String + } -type GraphQLInputObjectConfigFieldMapThunk = - () => GraphQLInputObjectConfigFieldMap; + type Query { + viewer: User + } +`); -type GraphQLInputObjectFieldConfig = { - type: GraphQLInputType; - defaultValue?: any; - description?: string; -}; +const typeMap = schema.getTypeMap(); -type GraphQLInputObjectConfigFieldMap = { - [fieldName: string]: GraphQLInputObjectFieldConfig; -}; +typeMap.User.name; // => 'User' +typeMap.Query.name; // => 'Query' +typeMap.String.name; // => 'String' +``` -type GraphQLInputObjectField = { - name: string; - type: GraphQLInputType; - defaultValue?: any; - description?: string; -}; +
-type GraphQLInputObjectFieldMap = { - [fieldName: string]: GraphQLInputObjectField; -}; -``` +##### getType() -An input object defines a structured collection of fields which may be -supplied to a field argument. +Returns the named type with the provided name. -Using `NonNull` will ensure that a value must be provided by the query +**Signature:** -#### Example + -```js -const GeoPoint = new GraphQLInputObjectType({ - name: 'GeoPoint', - fields: { - lat: { type: new GraphQLNonNull(GraphQLFloat) }, - lon: { type: new GraphQLNonNull(GraphQLFloat) }, - alt: { type: GraphQLFloat, defaultValue: 0 }, - }, -}); -``` +
-### GraphQLList +
Arguments
-```ts -class GraphQLList { - constructor(type: GraphQLType); -} -``` + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name to look up.
-A list is a kind of type marker, a wrapping type which points to another -type. Lists are often created within the context of defining the fields of -an object type. +
-#### Example +
Returns
-```js -const PersonType = new GraphQLObjectType({ - name: 'Person', - fields: () => ({ - parents: { type: new GraphQLList(PersonType) }, - children: { type: new GraphQLList(PersonType) }, - }), -}); -``` + + + + + + + + + + + + + +
TypeDescription
The named schema type, if one exists.
-### GraphQLNonNull +
+ +
Example
```ts -class GraphQLNonNull { - constructor(type: GraphQLType); -} -``` +import { buildSchema } from 'graphql/utilities'; -A non-null is a kind of type marker, a wrapping type which points to another -type. Non-null types enforce that their values are never null and can ensure -an error is raised if this ever occurs during a request. It is useful for -fields which you can make a strong guarantee on non-nullability, for example -usually the id field of a database row will never be null. +const schema = buildSchema(` + type User { + name: String + } -#### Example + type Query { + viewer: User + } +`); -```js -const RowType = new GraphQLObjectType({ - name: 'Row', - fields: () => ({ - id: { type: new GraphQLNonNull(String) }, - }), -}); +schema.getType('User')?.toString(); // => 'User' +schema.getType('Missing'); // => undefined ``` -## Predicates +
-### isInputType +##### getPossibleTypes() -```js -function isInputType(type: GraphQLType): boolean -``` +Returns object types that may be returned for an abstract type. -These types may be used as input types for arguments and directives. +**Signature:** -### isOutputType + -```ts -function isOutputType(type: GraphQLType): boolean; -``` +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
abstractTypeInterface or union type to inspect.
+ +
-These types may be used as output types as the result of fields +
Returns
-### isLeafType + + + + + + + + + + + + + +
TypeDescription
Object types that may satisfy the abstract type.
+ +
+ +
Example
```ts -function isLeafType(type: GraphQLType): boolean; +import { buildSchema } from 'graphql/utilities'; +import { assertInterfaceType, assertUnionType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Organization implements Node { + id: ID! + } + + union SearchResult = User | Organization + + type Query { + node: Node + search: [SearchResult] + } +`); + +const Node = assertInterfaceType(schema.getType('Node')); +const SearchResult = assertUnionType(schema.getType('SearchResult')); + +schema.getPossibleTypes(Node).map((type) => type.name); // => ['User', 'Organization'] +schema.getPossibleTypes(SearchResult).map((type) => type.name); // => ['User', 'Organization'] ``` -These types may describe types which may be leaf values +
+ +##### getImplementations() + +Returns objects and interfaces that implement an interface type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
interfaceTypeInterface type to inspect.
-### isCompositeType +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Object and interface implementations of the interface.
+ +
+ +
Example
```ts -function isCompositeType(type: GraphQLType): boolean; +import { buildSchema } from 'graphql/utilities'; +import { assertInterfaceType } from 'graphql/type'; + +const schema = buildSchema(` + interface Resource { + url: String! + } + + interface Image implements Resource { + url: String! + width: Int + } + + type Photo implements Resource & Image { + url: String! + width: Int + } + + type Query { + resource: Resource + } +`); + +const Resource = assertInterfaceType(schema.getType('Resource')); +const implementations = schema.getImplementations(Resource); + +implementations.interfaces.map((type) => type.name); // => ['Image'] +implementations.objects.map((type) => type.name); // => ['Photo'] ``` -These types may describe the parent context of a selection set - -### isAbstractType +
+ +##### isSubType() + +Returns whether one type is a possible runtime subtype of an abstract type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
abstractTypeInterface or union type to inspect.
maybeSubTypeObject or interface type to test as a possible subtype.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the subtype may satisfy the abstract type.
+ +
+ +
Example
```ts -function isAbstractType(type: GraphQLType): boolean; +import { buildSchema } from 'graphql/utilities'; +import { assertInterfaceType, assertObjectType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Review { + body: String + } + + type Query { + node: Node + review: Review + } +`); + +const Node = assertInterfaceType(schema.getType('Node')); +const User = assertObjectType(schema.getType('User')); +const Review = assertObjectType(schema.getType('Review')); + +schema.isSubType(Node, User); // => true +schema.isSubType(Node, Review); // => false ``` -These types may describe a combination of object types +
+ +##### getDirectives() + +Returns directives available in this schema. + +**Signature:** -## Un-modifiers + -### getNullableType +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Directives available in this schema.
+ +
+ +
Example
```ts -function getNullableType(type: GraphQLType): GraphQLNullableType; +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + directive @upper on FIELD_DEFINITION + + type Query { + greeting: String @upper + } +`); + +schema.getDirectives().map((directive) => directive.name); // => ['include', 'skip', 'deprecated', 'specifiedBy', 'oneOf', 'upper'] ``` -If a given type is non-nullable, this strips the non-nullability and -returns the underlying type. +
+ +##### getDirective() -### getNamedType +Returns the current directive definition. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name to look up.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current directive definition, if known.
+ +
+ +
Example
```ts -function getNamedType(type: GraphQLType): GraphQLNamedType; +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + directive @upper on FIELD_DEFINITION + + type Query { + greeting: String @upper + } +`); + +schema.getDirective('upper')?.name; // => 'upper' +schema.getDirective('missing'); // => undefined ``` -If a given type is non-nullable or a list, this repeated strips the -non-nullability and list wrappers and returns the underlying type. +
+ +##### toConfig() + +Returns a normalized configuration object for this object. + +The returned config preserves the original `assumeValid` flag so the schema +can be recreated with the same validation behavior. -## Scalars +**Signature:** -### GraphQLInt + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this object.
+ +
+ +
Example
```ts -let GraphQLInt: GraphQLScalarType; +import { buildSchema } from 'graphql/utilities'; +import { GraphQLSchema } from 'graphql/type'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); + +const config = schema.toConfig(); +const schemaCopy = new GraphQLSchema(config); + +config.query?.name; // => 'Query' +schemaCopy.getQueryType()?.name; // => 'Query' ``` -A `GraphQLScalarType` that represents an int. +### Functions + +#### isSchema() + +Test if the given value is a GraphQL schema. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
schemaValue to inspect.
+ +
-### GraphQLFloat +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLSchema.
+ +
+ +
Example
```ts -let GraphQLFloat: GraphQLScalarType; +import { buildSchema } from 'graphql/utilities'; +import { GraphQLString, isSchema } from 'graphql/type'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); + +isSchema(schema); // => true +isSchema(GraphQLString); // => false ``` -A `GraphQLScalarType` that represents a float. +
+ +#### assertSchema() + +Returns the value as a GraphQLSchema, or throws if it is not a schema. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLSchema.
+ +
-### GraphQLString +
Example
```ts -let GraphQLString: GraphQLScalarType; -``` +import { buildSchema } from 'graphql/utilities'; +import { assertSchema, GraphQLString } from 'graphql/type'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); -A `GraphQLScalarType` that represents a string. +assertSchema(schema); // => schema +assertSchema(GraphQLString); // throws an error +``` -### GraphQLBoolean +### Types + +#### GraphQLSchemaExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLSchemaConfig + +**Interface.** Configuration used to construct a GraphQLSchema. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
description?Human-readable description for this schema element, if provided.
query?Root object type for query operations.
mutation?Root object type for mutation operations.
subscription?Root object type for subscription operations.
types?Object types that belong to this union type.
directives?Directives available in this schema or applied to this AST node.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
extensionASTNodes?AST extension nodes applied to this schema element.
+ +## Category: Validation + +
+

+ Functions:
+ validateSchema() + + assertValidSchema() +

+
+ +### Functions + +#### validateSchema() + +Implements the "Type Validation" sub-sections of the specification's +"Type System" section. + +Validation runs synchronously, returning an array of encountered errors, or +an empty array if no errors were encountered and the Schema is valid. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Schema validation errors, or an empty array when the schema is valid.
+ +
+ +
Example
```ts -let GraphQLBoolean: GraphQLScalarType; +import { validateSchema } from 'graphql/type'; +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + name: String + } +`); +const errors = validateSchema(schema); + +errors; // => [] ``` -A `GraphQLScalarType` that represents a boolean. +
+ +#### assertValidSchema() + +Utility function which asserts a schema is valid by throwing an error if +it is invalid. + +**Signature:** -### GraphQLID + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
+ +
+ +
Example
```ts -let GraphQLID: GraphQLScalarType; -``` +import { assertValidSchema } from 'graphql/type'; +import { buildSchema } from 'graphql/utilities'; -A `GraphQLScalarType` that represents an ID. +const schema = buildSchema(` + type Query { + name: String + } +`); + +assertValidSchema(schema); // does not throw +``` diff --git a/website/pages/api-v16/type/_meta.ts b/website/pages/api-v16/type/_meta.ts new file mode 100644 index 0000000000..e2938604b8 --- /dev/null +++ b/website/pages/api-v16/type/_meta.ts @@ -0,0 +1,36 @@ +const meta = { + paths: { + title: 'Category: Paths', + href: '/api-v16/type#category-paths', + }, + names: { + title: 'Category: Names', + href: '/api-v16/type#category-names', + }, + types: { + title: 'Category: Types', + href: '/api-v16/type#category-types', + }, + directives: { + title: 'Category: Directives', + href: '/api-v16/type#category-directives', + }, + introspection: { + title: 'Category: Introspection', + href: '/api-v16/type#category-introspection', + }, + scalars: { + title: 'Category: Scalars', + href: '/api-v16/type#category-scalars', + }, + schema: { + title: 'Category: Schema', + href: '/api-v16/type#category-schema', + }, + validation: { + title: 'Category: Validation', + href: '/api-v16/type#category-validation', + }, +}; + +export default meta; diff --git a/website/pages/api-v16/utilities.mdx b/website/pages/api-v16/utilities.mdx index 1e646d8be7..dd5e26afc4 100644 --- a/website/pages/api-v16/utilities.mdx +++ b/website/pages/api-v16/utilities.mdx @@ -1,231 +1,4656 @@ ---- -title: graphql/utilities ---- - -{/* title can be removed in Nextra 4, since sidebar title will take from first h1 */} - -# `graphql/utilities` - -The `graphql/utilities` module contains common useful computations to use with -the GraphQL language and type objects. You can import either from the `graphql/utilities` module, or from the root `graphql` module. For example: - -```js -import { introspectionQuery } from 'graphql'; -``` - -## Overview - -### Introspection - - - -### Schema Language - - - -### Visitors - - - -### Value Validation - - - -## Introspection - -### introspectionQuery - -```js -const introspectionQuery: string; -``` - -A GraphQL query that queries a server's introspection system for enough -information to reproduce that server's type system. - -### `buildClientSchema` - -```ts -function buildClientSchema(introspection: IntrospectionQuery): GraphQLSchema; +import { ApiSignature, ApiType } from '../../components/ApiCode'; + +Utilities for building schemas, working with introspection, transforming ASTs, +and comparing GraphQL types. + +These exports are also available from the root `graphql` package. + +For documentation purposes, these exports are grouped into the following categories: + +- [Type Info](/api-v16/utilities#category-type-info) +- [Validation](/api-v16/utilities#category-validation) +- [Values](/api-v16/utilities#category-values) +- [Schema Construction](/api-v16/utilities#category-schema-construction) +- [Introspection](/api-v16/utilities#category-introspection) +- [AST Utilities](/api-v16/utilities#category-ast-utilities) +- [Schema Changes](/api-v16/utilities#category-schema-changes) +- [Operations](/api-v16/utilities#category-operations) +- [Schema Printing](/api-v16/utilities#category-schema-printing) +- [Schema Coordinates](/api-v16/utilities#category-schema-coordinates) +- [Type Comparisons](/api-v16/utilities#category-type-comparisons) +- [Typed Documents](/api-v16/utilities#category-typed-documents) + +## Category: Type Info + +
+

+ Classes:
+ TypeInfo +

+

+ Functions:
+ visitWithTypeInfo() +

+
+ +### Classes + +#### TypeInfo + +TypeInfo is a utility class which, given a GraphQL schema, can keep track +of the current field and type definitions at any point in a GraphQL document +AST during a recursive descent by calling `enter(node)` and `leave(node)`. + +
+ +##### Constructor + +Creates a TypeInfo instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaSchema used for type lookups.
initialType?Optional type to use at the start of traversal.
getFieldDefFn?Optional field definition lookup override.
+ +##### getType() + +Returns the current output type at this point in traversal. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current output type, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + viewer: User + } + + type User { + name: String + } +`); +const typeInfo = new TypeInfo(schema); +const fieldTypes = {}; + +visit( + parse('{ viewer { name } }'), + visitWithTypeInfo(typeInfo, { + Field: (node) => { + fieldTypes[node.name.value] = String(typeInfo.getType()); + }, + }), +); + +fieldTypes; // => { viewer: 'User', name: 'String' } +``` + +
+ +##### getParentType() + +Returns the current parent composite type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current parent composite type, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + viewer: User + } + + type User { + name: String + } +`); +const typeInfo = new TypeInfo(schema); +const parentTypes = {}; + +visit( + parse('{ viewer { name } }'), + visitWithTypeInfo(typeInfo, { + Field: (node) => { + parentTypes[node.name.value] = String(typeInfo.getParentType()); + }, + }), +); + +parentTypes; // => { viewer: 'Query', name: 'User' } +``` + +
+ +##### getInputType() + +Returns the current input type at this point in traversal. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current input type, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + reviews(stars: Int!, sort: Sort = NEWEST): [String] + } + + enum Sort { + NEWEST + OLDEST + } +`); +const typeInfo = new TypeInfo(schema); +const inputTypes = {}; + +visit( + parse('{ reviews(stars: 5, sort: OLDEST) }'), + visitWithTypeInfo(typeInfo, { + Argument: (node) => { + inputTypes[node.name.value] = String(typeInfo.getInputType()); + }, + }), +); + +inputTypes; // => { stars: 'Int!', sort: 'Sort' } +``` + +
+ +##### getParentInputType() + +Returns the parent input type for the current input position. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The parent input type, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + input ReviewFilter { + stars: Int! + } + + type Query { + reviews(filter: ReviewFilter): [String] + } +`); +const typeInfo = new TypeInfo(schema); +const parentInputTypes = {}; + +visit( + parse('{ reviews(filter: { stars: 5 }) }'), + visitWithTypeInfo(typeInfo, { + ObjectField: (node) => { + parentInputTypes[node.name.value] = String(typeInfo.getParentInputType()); + }, + }), +); + +parentInputTypes; // => { stars: 'ReviewFilter' } +``` + +
+ +##### getFieldDef() + +Returns the current field definition. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current field definition, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const typeInfo = new TypeInfo(schema); +let fieldName; + +visit( + parse('{ greeting }'), + visitWithTypeInfo(typeInfo, { + Field: () => { + fieldName = typeInfo.getFieldDef()?.name; + }, + }), +); + +fieldName; // => 'greeting' +``` + +
+ +##### getDefaultValue() + +Returns the default value for the current input position. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current default value, if one is available.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + reviews(limit: Int = 10): [String] + } +`); +const typeInfo = new TypeInfo(schema); +let defaultLimit; + +visit( + parse('{ reviews(limit: 5) }'), + visitWithTypeInfo(typeInfo, { + Argument: () => { + defaultLimit = typeInfo.getDefaultValue(); + }, + }), +); + +defaultLimit; // => 10 +``` + +
+ +##### getDirective() + +Returns the current directive definition. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current directive definition, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const typeInfo = new TypeInfo(schema); +let directiveName; + +visit( + parse('{ greeting @include(if: true) }'), + visitWithTypeInfo(typeInfo, { + Directive: () => { + directiveName = typeInfo.getDirective()?.name; + }, + }), +); + +directiveName; // => 'include' +``` + +
+ +##### getArgument() + +Returns the current argument definition. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current argument definition, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + reviews(limit: Int = 10): [String] + } +`); +const typeInfo = new TypeInfo(schema); +let argumentName; + +visit( + parse('{ reviews(limit: 5) }'), + visitWithTypeInfo(typeInfo, { + Argument: () => { + argumentName = typeInfo.getArgument()?.name; + }, + }), +); + +argumentName; // => 'limit' +``` + +
+ +##### getEnumValue() + +Returns the current enum value definition. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current enum value definition, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + enum Sort { + NEWEST + OLDEST + } + + type Query { + reviews(sort: Sort = NEWEST): [String] + } +`); +const typeInfo = new TypeInfo(schema); +let enumValueName; + +visit( + parse('{ reviews(sort: OLDEST) }'), + visitWithTypeInfo(typeInfo, { + EnumValue: () => { + enumValueName = typeInfo.getEnumValue()?.name; + }, + }), +); + +enumValueName; // => 'OLDEST' +``` + +
+ +##### enter() + +Updates this TypeInfo instance for an entered AST node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeAST node being entered.
+ +
+ +
Example
+ +```ts +import { Kind, parse } from 'graphql/language'; +import { buildSchema, TypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse('{ greeting }'); +const operation = document.definitions[0]; +const selectionSet = operation.selectionSet; +const field = selectionSet.selections[0]; +const typeInfo = new TypeInfo(schema); + +typeInfo.enter(operation); +typeInfo.enter(selectionSet); +typeInfo.enter(field); + +field.kind; // => Kind.FIELD +typeInfo.getParentType()?.name; // => 'Query' +String(typeInfo.getType()); // => 'String' +``` + +
+ +##### leave() + +Updates this TypeInfo instance for a left AST node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeAST node being entered.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { buildSchema, TypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse('{ greeting }'); +const operation = document.definitions[0]; +const selectionSet = operation.selectionSet; +const field = selectionSet.selections[0]; +const typeInfo = new TypeInfo(schema); + +typeInfo.enter(operation); +typeInfo.enter(selectionSet); +typeInfo.enter(field); +String(typeInfo.getType()); // => 'String' + +typeInfo.leave(field); +typeInfo.getType(); // => undefined +``` + +### Functions + +#### visitWithTypeInfo() + +Creates a new visitor instance which maintains a provided TypeInfo instance +along with visiting visitor. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
typeInfoTypeInfo instance to update during traversal.
visitorVisitor callbacks to wrap with TypeInfo updates.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that keeps TypeInfo in sync while delegating callbacks.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const typeInfo = new TypeInfo(schema); +const fields = []; + +visit( + parse('{ greeting }'), + visitWithTypeInfo(typeInfo, { + Field: (node) => { + fields.push({ + name: node.name.value, + parentType: String(typeInfo.getParentType()), + type: String(typeInfo.getType()), + }); + }, + }), +); + +fields; // => [{ name: 'greeting', parentType: 'Query', type: 'String' }] +``` + +## Category: Validation + +
+

+ Functions:
+ assertValidName() + + isValidNameError() +

+
+ +### Functions + +#### assertValidName() Deprecated + +Upholds the spec rules about naming. This deprecated helper is retained for +backwards compatibility; call [`assertName`](/api-v16/type#assertname) instead because assertValidName +will be removed in v17. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name to validate.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The validated GraphQL name.
+ +
+ +
Example
+ +```ts +import { assertValidName } from 'graphql/utilities'; + +assertValidName('User'); // => 'User' +assertValidName('__typename'); // throws an error +``` + +
+ +#### isValidNameError() Deprecated + +Returns an Error if a name is invalid. This deprecated helper is retained for +backwards compatibility; call [`assertName`](/api-v16/type#assertname) and catch the thrown GraphQLError +instead because isValidNameError will be removed in v17. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name to validate.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A GraphQLError if the name is invalid; otherwise undefined.
+ +
+ +
Example
+ +```ts +import { isValidNameError } from 'graphql/utilities'; + +isValidNameError('User'); // => undefined + +const error = isValidNameError('__typename'); +error.message; // => 'Name "__typename" must not begin with "__", which is reserved by GraphQL introspection.' +``` + +## Category: Values + +
+

+ Functions:
+ astFromValue() + + coerceInputValue() + + valueFromAST() + + valueFromASTUntyped() +

+
+ +### Functions + +#### astFromValue() + +Produces a GraphQL Value AST given a JavaScript object. +Function will match JavaScript/JSON values to GraphQL AST schema format +by using suggested GraphQLInputType. + +A GraphQL type must be provided, which will be used to interpret different +JavaScript values. + +| JSON Value | GraphQL Value | +| ------------- | -------------------- | +| Object | Input Object | +| Array | List | +| Boolean | Boolean | +| String | String / Enum Value | +| Number | Int / Float | +| Unknown | Enum Value | +| null | NullValue | + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
valueRuntime value to convert.
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A GraphQL value AST for the provided JavaScript value, or null when no literal can represent it.
+ +
+ +
Example
+ +```ts +import { print } from 'graphql/language'; +import { + GraphQLInputObjectType, + GraphQLInt, + GraphQLList, + GraphQLNonNull, + GraphQLString, +} from 'graphql/type'; +import { astFromValue } from 'graphql/utilities'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: { + stars: { type: new GraphQLNonNull(GraphQLInt) }, + tags: { type: new GraphQLList(GraphQLString) }, + }, +}); + +const valueNode = astFromValue( + { stars: 5, tags: ['featured', 'verified'] }, + ReviewInput, +); + +print(valueNode); // => '{ stars: 5, tags: ["featured", "verified"] }' +astFromValue(undefined, GraphQLString); // => null +astFromValue(null, new GraphQLNonNull(GraphQLString)); // => null +``` + +
+ +#### coerceInputValue() + +Coerces a JavaScript value given a GraphQL Input Type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
inputValueJavaScript value to coerce.
typeGraphQL input type to coerce the value against.
onErrorCallback invoked for each coercion error.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Coerced value, or undefined if coercion failed and errors were reported.
+ +
+ +
Example 1
+ +```ts +// Coerce runtime input values and throw on invalid input by default. +import { + GraphQLInputObjectType, + GraphQLInt, + GraphQLList, + GraphQLNonNull, + GraphQLString, +} from 'graphql/type'; +import { coerceInputValue } from 'graphql/utilities'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: { + stars: { type: new GraphQLNonNull(GraphQLInt) }, + tags: { type: new GraphQLList(GraphQLString) }, + }, +}); + +coerceInputValue({ stars: '5', tags: ['featured'] }, ReviewInput); // => { stars: 5, tags: ['featured'] } +coerceInputValue({ stars: 'bad' }, ReviewInput); // throws an error +``` + +
+ +
Example 2
+ +```ts +// This variant collects coercion errors with a custom onError callback. +import { GraphQLInt, GraphQLNonNull } from 'graphql/type'; +import { coerceInputValue } from 'graphql/utilities'; + +const errors = []; +const value = coerceInputValue( + null, + new GraphQLNonNull(GraphQLInt), + (path, invalidValue, error) => { + errors.push({ path, invalidValue, message: error.message }); + }, +); + +value; // => undefined +errors; // => [ { path: [], invalidValue: null, message: 'Expected non-nullable type "Int!" not to be null.' } ] +``` + +
+ +#### valueFromAST() + +Produces a JavaScript value given a GraphQL Value AST. + +A GraphQL type must be provided, which will be used to interpret different +GraphQL Value literals. + +Returns `undefined` when the value could not be validly coerced according to +the provided type. + +| GraphQL Value | JSON Value | +| -------------------- | ------------- | +| Input Object | Object | +| List | Array | +| Boolean | Boolean | +| String | String | +| Int / Float | Number | +| Enum Value | Unknown | +| NullValue | null | + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
valueNodeGraphQL value AST node to convert.
typeThe GraphQL type to inspect.
variables?Optional runtime variable values keyed by variable name.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The coerced JavaScript value, or undefined if the AST value cannot be coerced to the type.
+ +
+ +
Example 1
+ +```ts +// Coerce literal values without variables. +import { parseValue } from 'graphql/language'; +import { + GraphQLInputObjectType, + GraphQLInt, + GraphQLList, + GraphQLNonNull, + GraphQLString, +} from 'graphql/type'; +import { valueFromAST } from 'graphql/utilities'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: { + stars: { type: new GraphQLNonNull(GraphQLInt) }, + tags: { type: new GraphQLList(GraphQLString) }, + }, +}); + +valueFromAST(parseValue('{ stars: 5, tags: ["featured"] }'), ReviewInput); // => { stars: 5, tags: ['featured'] } +valueFromAST(parseValue('{ stars: "bad" }'), ReviewInput); // => undefined +``` + +
+ +
Example 2
+ +```ts +// This variant resolves variable references from runtime values. +import { parseValue } from 'graphql/language'; +import { GraphQLInt } from 'graphql/type'; +import { valueFromAST } from 'graphql/utilities'; + +valueFromAST(parseValue('$stars'), GraphQLInt, { stars: 5 }); // => 5 +valueFromAST(parseValue('$stars'), GraphQLInt, {}); // => undefined +``` + +
+ +#### valueFromASTUntyped() + +Produces a JavaScript value given a GraphQL Value AST. + +Because no GraphQL type is provided, the returned JavaScript value reflects +the provided GraphQL value AST. + +| GraphQL Value | JavaScript Value | +| -------------------- | ---------------- | +| Input Object | Object | +| List | Array | +| Boolean | Boolean | +| String / Enum | String | +| Int / Float | Number | +| Null | null | + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
valueNodeGraphQL value AST node to convert.
variables?Optional runtime variable values keyed by variable name.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
JavaScript value represented by the GraphQL value AST.
+ +
+ +
Example
+ +```ts +import { parseValue } from 'graphql/language'; +import { valueFromASTUntyped } from 'graphql/utilities'; + +const value = valueFromASTUntyped(parseValue('[1, 2, 3]')); + +value; // => [1, 2, 3] +valueFromASTUntyped(parseValue('$name'), { name: 'Ada' }); // => 'Ada' +``` + +## Category: Schema Construction + +
+

+ Functions:
+ buildASTSchema() + + buildSchema() + + extendSchema() + + lexicographicSortSchema() +

+

+ Types:
+ BuildSchemaOptions +

+
+ +### Functions + +#### buildASTSchema() + +Builds a GraphQLSchema from a parsed schema definition language document. + +If no schema definition is provided, then it will look for types named Query, +Mutation and Subscription. + +The resulting schema has no resolver functions, so execution will use the +default field resolver. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
documentASTThe parsed GraphQL document AST.
options?Optional configuration for this operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema built from the provided SDL document.
+ +
+ +
Example 1
+ +```ts +// Build a schema from a valid parsed SDL document. +import { parse } from 'graphql/language'; +import { buildASTSchema } from 'graphql/utilities'; + +const document = parse('type Query { hello: String }'); +const schema = buildASTSchema(document); + +schema.getQueryType().name; // => 'Query' +``` + +
+ +
Example 2
+ +```ts +// This variant uses validation options when the SDL references unknown types. +import { parse } from 'graphql/language'; +import { buildASTSchema } from 'graphql/utilities'; + +const document = parse('type Query { broken: MissingType }'); + +buildASTSchema(document); // throws an error +buildASTSchema(document, { + assumeValid: true, + assumeValidSDL: true, +}); // does not throw +``` + +
+ +#### buildSchema() + +Builds a GraphQLSchema directly from a schema definition language source. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourceThe GraphQL source text or source object.
options?Optional configuration for this operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema built from the provided SDL document.
+ +
+ +
Example 1
+ +```ts +// Build a schema from SDL source using the default options. +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema('type Query { hello: String }'); + +schema.getQueryType().name; // => 'Query' +``` + +
+ +
Example 2
+ +```ts +// This variant enables parser options and omits source locations. +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema( + 'directive @tag on FIELD_DEFINITION\n' + + 'directive @compose @tag on FIELD_DEFINITION', + { + experimentalDirectivesOnDirectiveDefinitions: true, + noLocation: true, + }, +); + +const directive = schema.getDirective('compose'); + +directive.name; // => 'compose' +directive.astNode.loc; // => undefined +``` + +
+ +#### extendSchema() + +Produces a new schema given an existing schema and a document which may +contain GraphQL type extensions and definitions. The original schema will +remain unaltered. + +Because a schema represents a graph of references, a schema cannot be +extended without effectively making an entire copy. We do not know until it's +too late if subgraphs remain unchanged. + +This algorithm copies the provided schema, applying extensions while +producing the copy. The original schema remains unaltered. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
documentASTThe parsed GraphQL document AST.
options?Optional configuration for this operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A new schema with the extensions and definitions applied.
+ +
+ +
Example 1
+ +```ts +// Extend a schema with new fields and types. +import { parse } from 'graphql/language'; +import { buildSchema, extendSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const extensionAST = parse(` + extend type Query { + farewell: String + } + + type Review { + body: String + } +`); + +const extendedSchema = extendSchema(schema, extensionAST); + +schema.getType('Review'); // => undefined +extendedSchema.getType('Review')?.name; // => 'Review' +Object.keys(extendedSchema.getQueryType().getFields()); // => ['greeting', 'farewell'] +``` + +
+ +
Example 2
+ +```ts +// This variant bypasses validation for an otherwise invalid extension. +import { parse } from 'graphql/language'; +import { buildSchema, extendSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const invalidExtension = parse(` + extend type Missing { + field: String + } +`); + +extendSchema(schema, invalidExtension); // throws an error +extendSchema(schema, invalidExtension, { + assumeValid: true, + assumeValidSDL: true, + }); // does not throw +``` + +
+ +#### lexicographicSortSchema() + +Sort GraphQLSchema. + +This function returns a sorted copy of the given GraphQLSchema. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A copy of the schema with types, fields, arguments, and values sorted lexicographically.
+ +
+ +
Example
+ +```ts +import { buildSchema, lexicographicSortSchema, printSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + zebra: String + apple: String + } + + enum Episode { + JEDI + NEW_HOPE + EMPIRE + } +`); + +const sortedSchema = lexicographicSortSchema(schema); + +printSchema(sortedSchema); +// => +// enum Episode { +// EMPIRE +// JEDI +// NEW_HOPE +// } +// +// type Query { +// apple: String +// zebra: String +// } +``` + +### Types + +#### BuildSchemaOptions + +**Interface.** Options used when building a schema from SDL or a parsed SDL document. + +
+ +
Members
+ + + + + + + + + + + + + + + + +
NameTypeDescription
assumeValidSDL?Set to true to assume the SDL is valid.
+Default: false
+ +## Category: Introspection + + + +### Functions + +#### buildClientSchema() + +Build a GraphQLSchema for use by client tools. + +Given the result of a client running the introspection query, creates and +returns a GraphQLSchema instance which can be then used with all graphql-js +tools, but cannot be used to execute a query, as introspection does not +represent the "resolver", "parse" or "serialize" functions or any other +server-internal mechanisms. + +This function expects a complete introspection result. Don't forget to check +the "errors" field of a server response before calling this function. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
introspectionIntrospection result data to build from.
options?Optional configuration for this operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The client schema represented by the introspection result.
+ +
+ +
Example
+ +```ts +import { buildClientSchema, introspectionFromSchema, buildSchema } from 'graphql/utilities'; + +const schema = buildSchema('type Query { hello: String }'); +const clientSchema = buildClientSchema(introspectionFromSchema(schema), { + assumeValid: true, +}); + +clientSchema.getQueryType().name; // => 'Query' +``` + +
+ +#### getIntrospectionQuery() + +Produce the GraphQL query recommended for a full schema introspection. +Accepts optional IntrospectionOptions. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
options?Optional configuration for this operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The resolved introspection query.
+ +
+ +
Example 1
+ +```ts +// Generate the default introspection query. +import { getIntrospectionQuery } from 'graphql/utilities'; + +const query = getIntrospectionQuery(); + +query; // matches /__schema/ +query; // matches /description/ +query; // does not match /specifiedByURL/ +``` + +
+ +
Example 2
+ +```ts +// This variant customizes optional introspection fields and nesting depth. +import { getIntrospectionQuery } from 'graphql/utilities'; + +const query = getIntrospectionQuery({ + descriptions: false, + specifiedByUrl: true, + directiveIsRepeatable: true, + schemaDescription: true, + inputValueDeprecation: true, + experimentalDirectiveDeprecation: true, + oneOf: true, + typeDepth: 3, +}); + +query; // does not match /description/ +query; // matches /specifiedByURL/ +query; // matches /isRepeatable/ +query; // matches /includeDeprecated: true/ +query; // matches /isOneOf/ +(query.match(/ofType/g)?.length ?? 0) > 0; // => true +``` + +
+ +#### introspectionFromSchema() + +Build an IntrospectionQuery from a GraphQLSchema + +IntrospectionQuery is useful for utilities that care about type and field +relationships, but do not need to traverse through those relationships. + +This is the inverse of buildClientSchema. The primary use case is outside +of the server context, for instance when doing schema comparisons. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
options?Optional configuration for this operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Introspection result data for the schema.
+ +
+ +
Example 1
+ +```ts +// Include schema metadata using the default introspection options. +import { buildSchema, introspectionFromSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + scalar Url @specifiedBy(url: "https://url.spec.whatwg.org/") + + type Query { + homepage: Url + } +`); + +const introspection = introspectionFromSchema(schema); +const urlType = introspection.__schema.types.find((type) => type.name === 'Url'); + +urlType.specifiedByURL; // => 'https://url.spec.whatwg.org/' +``` + +
+ +
Example 2
+ +```ts +// This variant disables optional introspection metadata. +import { buildSchema, introspectionFromSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + scalar Url @specifiedBy(url: "https://url.spec.whatwg.org/") + + type Query { + homepage: Url + } +`); + +const introspection = introspectionFromSchema(schema, { + descriptions: false, + specifiedByUrl: false, + directiveIsRepeatable: false, + schemaDescription: false, + inputValueDeprecation: false, + experimentalDirectiveDeprecation: false, + oneOf: false, +}); +const urlType = introspection.__schema.types.find((type) => type.name === 'Url'); +const deprecatedDirective = introspection.__schema.directives.find( + (directive) => directive.name === 'deprecated', +); + +urlType.specifiedByURL; // => undefined +urlType.description; // => undefined +introspection.__schema.description; // => undefined +deprecatedDirective.isRepeatable; // => undefined +``` + +### Types + +#### IntrospectionOptions + +**Interface.** Options controlling which fields are included in the introspection query. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
descriptions?Whether to include descriptions in the introspection result.
+Default: true
specifiedByUrl?Whether to include {"specifiedByURL"} in the introspection result.
+Default: false
directiveIsRepeatable?Whether to include {"isRepeatable"} flag on directives.
+Default: false
schemaDescription?Whether to include {"description"} field on schema.
+Default: false
inputValueDeprecation?Whether target GraphQL server support deprecation of input values.
+Default: false
experimentalDirectiveDeprecation?Whether target GraphQL server supports deprecation of directives.
+Default: false
oneOf?Whether target GraphQL server supports {"@oneOf"} input objects.
+Default: false
typeDepth?How deep to recurse into nested types, larger values will result in more
+accurate results, but have a higher load on the server.
+Some servers might restrict the maximum query depth or complexity.
+If that's the case, try decreasing this value.
+Default: 9
+ +
+ +#### IntrospectionQuery + +**Interface.** The result shape returned by a full introspection query. + +
+ +
Members
+ + + + + + + + + + + + + + + + +
NameTypeDescription
__schemaThe schema.
+ +
+ +#### IntrospectionSchema + +**Interface.** The introspection representation of a GraphQL schema. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
description?Human-readable description for this schema element, if provided.
queryTypeThe root object type used for query operations.
mutationTypeThe root object type used for mutation operations, if supported.
subscriptionTypeThe root object type used for subscription operations, if supported.
typesObject types that belong to this union type.
directivesDirectives available in this schema or applied to this AST node.
+ +
+ +#### IntrospectionType + +**Type alias.** Any introspection representation of a GraphQL type. + + + +
+ +#### IntrospectionOutputType + +**Type alias.** An introspection type that can appear in output position. + + + +
+ +#### IntrospectionInputType + +**Type alias.** An introspection type that can appear in input position. + + + +
+ +#### IntrospectionScalarType + +**Interface.** The introspection representation of a scalar type. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe introspection kind discriminator for this type reference or type.
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
specifiedByURL?URL identifying the behavior specified for this custom scalar.
+ +
+ +#### IntrospectionObjectType + +**Interface.** The introspection representation of an object type. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe introspection kind discriminator for this type reference or type.
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
fieldsFields declared by this object, interface, input object, or literal.
interfacesInterfaces implemented by this object or interface type.
+ +
+ +#### IntrospectionInterfaceType + +**Interface.** The introspection representation of an interface type. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe introspection kind discriminator for this type reference or type.
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
fieldsFields declared by this object, interface, input object, or literal.
interfacesInterfaces implemented by this object or interface type.
possibleTypesObject types that may be returned for this abstract type.
+ +
+ +#### IntrospectionUnionType + +**Interface.** The introspection representation of a union type. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe introspection kind discriminator for this type reference or type.
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
possibleTypesObject types that may be returned for this abstract type.
+ +
+ +#### IntrospectionEnumType + +**Interface.** The introspection representation of an enum type. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe introspection kind discriminator for this type reference or type.
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
enumValuesValues declared by this enum type.
+ +
+ +#### IntrospectionInputObjectType + +**Interface.** The introspection representation of an input object type. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe introspection kind discriminator for this type reference or type.
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
inputFieldsInput fields declared by this input object type.
isOneOfWhether this input object uses the experimental OneOf input object semantics.
+ +
+ +#### IntrospectionListTypeRef + +**Interface.** The introspection representation of a list type reference. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TThe introspection type reference wrapped by this list type reference.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe introspection kind discriminator for this type reference or type.
ofTypeThe type wrapped by this list or non-null type.
+ +
+ +#### IntrospectionNonNullTypeRef + +**Interface.** The introspection representation of a non-null type reference. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TThe introspection type reference wrapped by this non-null type reference.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe introspection kind discriminator for this type reference or type.
ofTypeThe type wrapped by this list or non-null type.
+ +
+ +#### IntrospectionTypeRef + +**Type alias.** Any introspection representation of a type reference. + + + +
+ +#### IntrospectionOutputTypeRef + +**Type alias.** An introspection type reference that can appear in output position. + + + +
+ +#### IntrospectionInputTypeRef + +**Type alias.** An introspection type reference that can appear in input position. + + + +
+ +#### IntrospectionNamedTypeRef + +**Interface.** The introspection representation of a named type reference. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TThe introspection type represented by this named type reference.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe introspection kind discriminator for this type reference or type.
nameThe GraphQL name for this schema element.
+ +
+ +#### IntrospectionField + +**Interface.** The introspection representation of a field. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
argsArguments accepted by this field or directive.
typeThe GraphQL type reference or runtime type for this element.
isDeprecatedWhether this field, argument, enum value, or input value is deprecated.
deprecationReasonReason this element is deprecated, if one was provided.
+ +
+ +#### IntrospectionInputValue + +**Interface.** The introspection representation of an argument or input field. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
typeThe GraphQL type reference or runtime type for this element.
defaultValueDefault value used when no explicit value is supplied.
isDeprecated?Whether this field, argument, enum value, or input value is deprecated.
deprecationReason?Reason this element is deprecated, if one was provided.
+ +
+ +#### IntrospectionEnumValue + +**Interface.** The introspection representation of an enum value. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
isDeprecatedWhether this field, argument, enum value, or input value is deprecated.
deprecationReasonReason this element is deprecated, if one was provided.
+ +
+ +#### IntrospectionDirective + +**Interface.** The introspection representation of a directive. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
isRepeatable?Whether this directive may appear more than once at the same location.
isDeprecated?Whether this field, argument, enum value, or input value is deprecated.
deprecationReason?Reason this element is deprecated, if one was provided.
locationsLocations where this directive may be applied.
argsArguments accepted by this field or directive.
+ +## Category: AST Utilities + +
+

+ Functions:
+ concatAST() + + separateOperations() + + stripIgnoredCharacters() +

+
+ +### Functions + +#### concatAST() + +Provided a collection of ASTs, presumably each from different files, +concatenate the ASTs together into batched AST, useful for validating many +GraphQL source files which together represent one conceptual application. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
documentsDocument ASTs to concatenate.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A document AST containing all definitions from the provided documents.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { concatAST } from 'graphql/utilities'; + +const document = concatAST([parse('type Query { a: String }'), parse('type User { id: ID }')]); + +document.definitions.length; // => 2 +``` + +
+ +#### separateOperations() + +separateOperations accepts a single AST document which may contain many +operations and fragments and returns a collection of AST documents each of +which contains a single operation as well the fragment definitions it +refers to. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
documentASTThe parsed GraphQL document AST.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A map of operation names to documents containing each operation and its referenced fragments.
+ +
+ +
Example
+ +```ts +import { parse, print } from 'graphql/language'; +import { separateOperations } from 'graphql/utilities'; + +const document = parse(` + query GetUser { + viewer { + ...UserFields + } + } + + query GetStatus { + status + } + + fragment UserFields on User { + id + } +`); + +const separated = separateOperations(document); + +Object.keys(separated); // => ['GetUser', 'GetStatus'] +print(separated.GetUser); // matches /fragment UserFields/ +print(separated.GetStatus); // does not match /fragment UserFields/ +``` + +
+ +#### stripIgnoredCharacters() + +Strips characters that are not significant to the validity or execution +of a GraphQL document: + - UnicodeBOM + - WhiteSpace + - LineTerminator + - Comment + - Comma + - BlockString indentation + +Note: It is required to have a delimiter character between neighboring +non-punctuator tokens and this function always uses single space as delimiter. + +It is guaranteed that both input and output documents if parsed would result +in the exact same AST except for nodes location. + +Warning: It is guaranteed that this function will always produce stable results. +However, it's not guaranteed that it will stay the same between different +releases due to bugfixes or changes in the GraphQL specification. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
sourceThe GraphQL source text or source object.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A semantically equivalent GraphQL source string without ignored characters.
+ +
+ +
Example 1
+ +```graphql +query SomeQuery($foo: String!, $bar: String) { + someField(foo: $foo, bar: $bar) { + a + b { + c + d + } + } +} +``` + +Becomes: + +```graphql +query SomeQuery($foo:String!$bar:String){someField(foo:$foo bar:$bar){a b{c d}}} +``` + +
+ +
Example 2
+ +```graphql +""" +Type description +""" +type Foo { + """ + Field description + """ + bar: String +} ``` -Build a GraphQLSchema for use by client tools. +Becomes: -Given the result of a client running the introspection query, creates and -returns a GraphQLSchema instance which can be then used with all GraphQL.js -tools, but cannot be used to execute a query, as introspection does not -represent the "resolver", "parse" or "serialize" functions or any other -server-internal mechanisms. +```graphql +"""Type description""" type Foo{"""Field description""" bar:String} +``` -## Schema Representation +
-### `buildSchema` +
Example 3
```ts -function buildSchema(source: string | Source): GraphQLSchema; +import { stripIgnoredCharacters } from 'graphql/utilities'; + +const source = stripIgnoredCharacters('query Example { name }'); + +source; // => 'query Example{name}' ``` -Creates a GraphQLSchema object from GraphQL schema language. The schema will use default resolvers. For more detail on the GraphQL schema language, see the [schema language docs](/learn/schema/) or this [schema language cheat sheet](https://wehavefaces.net/graphql-shorthand-notation-cheatsheet-17cd715861b6#.9oztv0a7n). +## Category: Schema Changes + +
+

+ Functions:
+ findBreakingChanges() + + findDangerousChanges() +

+

+ Enumerations:
+ BreakingChangeType + + DangerousChangeType +

+

+ Types:
+ BreakingChange + + DangerousChange +

+
+ +### Functions + +#### findBreakingChanges() + +Given two schemas, returns an Array containing descriptions of all the types +of breaking changes covered by the other functions down below. -### `printSchema` +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oldSchemaSchema before the change.
newSchemaSchema after the change.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Breaking changes between the two schemas.
+ +
+ +
Example
```ts -function printSchema(schema: GraphQLSchema): string; +import { buildSchema, findBreakingChanges } from 'graphql/utilities'; + +const oldSchema = buildSchema(` + type User { + id: ID! + name: String + } + + type Query { + viewer: User + } +`); +const newSchema = buildSchema(` + type User { + id: ID! + } + + type Query { + viewer: User + } +`); + +const changes = findBreakingChanges(oldSchema, newSchema); + +changes[0].type; // => 'FIELD_REMOVED' +changes[0].description; // matches /User.name was removed/ ``` -Prints the provided schema in the Schema Language format. +
+ +#### findDangerousChanges() + +Given two schemas, returns an Array containing descriptions of all the types +of potentially dangerous changes covered by the other functions down below. -### `printIntrospectionSchema` +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oldSchemaSchema before the change.
newSchemaSchema after the change.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Dangerous changes between the two schemas.
+ +
+ +
Example
```ts -function printIntrospectionSchema(schema: GraphQLSchema): string; +import { buildSchema, findDangerousChanges } from 'graphql/utilities'; + +const oldSchema = buildSchema(` + enum Episode { + NEW_HOPE + } + + type Query { + episode: Episode + } +`); +const newSchema = buildSchema(` + enum Episode { + NEW_HOPE + EMPIRE + } + + type Query { + episode: Episode + } +`); + +const changes = findDangerousChanges(oldSchema, newSchema); + +changes[0].type; // => 'VALUE_ADDED_TO_ENUM' +changes[0].description; // matches /EMPIRE was added/ ``` -Prints the built-in introspection schema in the Schema Language format. +### Enumerations + +#### BreakingChangeType + +**Enumeration.** Categories of schema changes that may break existing operations. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameValueDescription
{"TYPE_REMOVED"}{"\"TYPE_REMOVED\""}Breaking change code for type removed.
{"TYPE_CHANGED_KIND"}{"\"TYPE_CHANGED_KIND\""}Breaking change code for type changed kind.
{"TYPE_REMOVED_FROM_UNION"}{"\"TYPE_REMOVED_FROM_UNION\""}Breaking change code for type removed from union.
{"VALUE_REMOVED_FROM_ENUM"}{"\"VALUE_REMOVED_FROM_ENUM\""}Breaking change code for value removed from enum.
{"REQUIRED_INPUT_FIELD_ADDED"}{"\"REQUIRED_INPUT_FIELD_ADDED\""}Breaking change code for required input field added.
{"IMPLEMENTED_INTERFACE_REMOVED"}{"\"IMPLEMENTED_INTERFACE_REMOVED\""}Breaking change code for implemented interface removed.
{"FIELD_REMOVED"}{"\"FIELD_REMOVED\""}Breaking change code for field removed.
{"FIELD_CHANGED_KIND"}{"\"FIELD_CHANGED_KIND\""}Breaking change code for field changed kind.
{"REQUIRED_ARG_ADDED"}{"\"REQUIRED_ARG_ADDED\""}Breaking change code for required arg added.
{"ARG_REMOVED"}{"\"ARG_REMOVED\""}Breaking change code for arg removed.
{"ARG_CHANGED_KIND"}{"\"ARG_CHANGED_KIND\""}Breaking change code for arg changed kind.
{"DIRECTIVE_REMOVED"}{"\"DIRECTIVE_REMOVED\""}Breaking change code for directive removed.
{"DIRECTIVE_ARG_REMOVED"}{"\"DIRECTIVE_ARG_REMOVED\""}Breaking change code for directive arg removed.
{"REQUIRED_DIRECTIVE_ARG_ADDED"}{"\"REQUIRED_DIRECTIVE_ARG_ADDED\""}Breaking change code for required directive arg added.
{"DIRECTIVE_REPEATABLE_REMOVED"}{"\"DIRECTIVE_REPEATABLE_REMOVED\""}Breaking change code for directive repeatable removed.
{"DIRECTIVE_LOCATION_REMOVED"}{"\"DIRECTIVE_LOCATION_REMOVED\""}Breaking change code for directive location removed.
+ +
+ +#### DangerousChangeType + +**Enumeration.** Categories of schema changes that may be dangerous for existing operations. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameValueDescription
{"VALUE_ADDED_TO_ENUM"}{"\"VALUE_ADDED_TO_ENUM\""}Dangerous change code for value added to enum.
{"TYPE_ADDED_TO_UNION"}{"\"TYPE_ADDED_TO_UNION\""}Dangerous change code for type added to union.
{"OPTIONAL_INPUT_FIELD_ADDED"}{"\"OPTIONAL_INPUT_FIELD_ADDED\""}Dangerous change code for optional input field added.
{"OPTIONAL_ARG_ADDED"}{"\"OPTIONAL_ARG_ADDED\""}Dangerous change code for optional arg added.
{"IMPLEMENTED_INTERFACE_ADDED"}{"\"IMPLEMENTED_INTERFACE_ADDED\""}Dangerous change code for implemented interface added.
{"ARG_DEFAULT_VALUE_CHANGE"}{"\"ARG_DEFAULT_VALUE_CHANGE\""}Dangerous change code for arg default value change.
+ +### Types + +#### BreakingChange + +**Interface.** Description of a schema change that may break existing operations. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
typeSpecific kind of breaking schema change.
descriptionHuman-readable description of the breaking schema change.
+ +
-### `buildASTSchema` +#### DangerousChange + +**Interface.** Description of a schema change that may be dangerous for existing operations. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
typeSpecific kind of dangerous schema change.
descriptionHuman-readable description of the dangerous schema change.
+ +## Category: Operations + +
+

+ Functions:
+ getOperationAST() + + getOperationRootType() +

+
+ +### Functions + +#### getOperationAST() + +Returns an operation AST given a document AST and optionally an operation +name. If a name is not provided, an operation is only returned if only one is +provided in the document. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
documentASTThe parsed GraphQL document AST.
operationName?The optional operation name to select.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The resolved operation ast.
+ +
+ +
Example
```ts -function buildASTSchema( - ast: SchemaDocument, - queryTypeName: string, - mutationTypeName: string, -): GraphQLSchema; +import { parse } from 'graphql/language'; +import { getOperationAST } from 'graphql/utilities'; + +const document = parse('query GetName { name }'); +const operation = getOperationAST(document, 'GetName'); + +operation.name.value; // => 'GetName' +getOperationAST(document, 'Missing'); // => undefined ``` -This takes the ast of a schema document produced by `parseSchemaIntoAST` in -`graphql/language/schema` and constructs a GraphQLSchema instance which can be -then used with all GraphQL.js tools, but cannot be used to execute a query, as -introspection does not represent the "resolver", "parse" or "serialize" -functions or any other server-internal mechanisms. +
+ +#### getOperationRootType() Deprecated + +Extracts the root type of the operation from the schema. This deprecated +helper is retained for backwards compatibility; call +[`GraphQLSchema.getRootType`](/api-v16/type#getroottype) instead because getOperationRootType will be +removed in v17. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
operationThe operation definition to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The resolved operation root type.
+ +
-### `typeFromAST` +
Example
```ts -function typeFromAST(schema: GraphQLSchema, inputTypeAST: Type): GraphQLType; +import { buildSchema, getOperationRootType } from 'graphql/utilities'; +import { parse } from 'graphql/language'; + +const schema = buildSchema('type Query { name: String }'); +const operation = parse('{ name }').definitions[0]; +const rootType = getOperationRootType(schema, operation); + +rootType.name; // => 'Query' ``` -Given the name of a Type as it appears in a GraphQL AST and a Schema, return the -corresponding GraphQLType from that schema. +## Category: Schema Printing + +
+

+ Functions:
+ printSchema() + + printIntrospectionSchema() + + printType() +

+
+ +### Functions + +#### printSchema() + +Prints the schema. + +**Signature:** + + -### `astFromValue` +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The printed string representation.
+ +
+ +
Example
```ts -function astFromValue(value: any, type: GraphQLInputType): Value; +import { buildSchema, printSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + directive @upper on FIELD_DEFINITION + + type Query { + greeting: String @upper + } +`); + +printSchema(schema); // => ['directive @upper on FIELD_DEFINITION', '', 'type Query {', ' greeting: String', '}'].join('\n') ``` -Produces a GraphQL Input Value AST given a JavaScript value. +
+ +#### printIntrospectionSchema() + +Prints the introspection schema. + +**Signature:** + + + +
+ +
Arguments
-Optionally, a GraphQL type may be provided, which will be used to -disambiguate between value primitives. + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
-## Visitors +
-### `TypeInfo` +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The printed string representation.
+ +
+ +
Example
```ts -class TypeInfo { - constructor(schema: GraphQLSchema); - getType(): GraphQLOutputType; - getParentType(): GraphQLCompositeType; - getInputType(): GraphQLInputType; - getFieldDef(): GraphQLFieldDefinition; - getDirective(): GraphQLDirective; - getArgument(): GraphQLArgument; -} +import { buildSchema, printIntrospectionSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); + +const printed = printIntrospectionSchema(schema); + +printed; // matches /type __Schema/ +printed; // matches /enum __TypeKind/ +printed; // does not match /type Query/ ``` -TypeInfo is a utility class which, given a GraphQL schema, can keep track -of the current field and type definitions at any point in a GraphQL document -AST during a recursive descent by calling `enter(node)` and `leave(node)`. +
+ +#### printType() + +Prints the type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The printed string representation.
+ +
+ +
Example
+ +```ts +import { buildSchema, printType } from 'graphql/utilities'; + +const schema = buildSchema(` + type User { + id: ID! + name: String + } + + type Query { + viewer: User + } +`); + +printType(schema.getType('User')); // => ['type User {', ' id: ID!', ' name: String', '}'].join('\n') +``` + +## Category: Schema Coordinates + + + +### Functions + +#### resolveSchemaCoordinate() + +A schema coordinate is resolved in the context of a GraphQL schema to +uniquely identify a schema element. It returns undefined if the schema +coordinate does not resolve to a schema element, meta-field, or introspection +schema element. It will throw if the containing schema element (if +applicable) does not exist. + +https://spec.graphql.org/draft/#sec-Schema-Coordinates.Semantics + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
schemaCoordinateThe schema coordinate to resolve.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema element identified by the coordinate, or undefined if none exists.
+ +
+ +
Example
+ +```ts +import { buildSchema, resolveSchemaCoordinate } from 'graphql/utilities'; + +const schema = buildSchema(` + directive @tag(name: String!) on FIELD_DEFINITION + + input ReviewInput { + stars: Int! + } + + enum Episode { + NEW_HOPE + } + + type Query { + reviews(input: ReviewInput): [String] @tag(name: "reviews") + } +`); + +resolveSchemaCoordinate(schema, 'Query').kind; // => 'NamedType' +resolveSchemaCoordinate(schema, 'Query.reviews').kind; // => 'Field' +resolveSchemaCoordinate(schema, 'Query.reviews(input:)').kind; // => 'FieldArgument' +resolveSchemaCoordinate(schema, 'ReviewInput.stars').kind; // => 'InputField' +resolveSchemaCoordinate(schema, 'Episode.NEW_HOPE').kind; // => 'EnumValue' +resolveSchemaCoordinate(schema, '@tag').kind; // => 'Directive' +resolveSchemaCoordinate(schema, '@tag(name:)').kind; // => 'DirectiveArgument' +resolveSchemaCoordinate(schema, 'Query.missing'); // => undefined +``` + +
+ +#### resolveASTSchemaCoordinate() + +Resolves schema coordinate from a parsed SchemaCoordinate node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
schemaCoordinateThe schema coordinate to resolve.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema element identified by the parsed coordinate, or undefined if none exists.
+ +
+ +
Example
+ +```ts +import { parseSchemaCoordinate } from 'graphql/language'; +import { buildSchema, resolveASTSchemaCoordinate } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting(name: String): String + } +`); +const coordinate = parseSchemaCoordinate('Query.greeting(name:)'); +const resolved = resolveASTSchemaCoordinate(schema, coordinate); + +resolved.kind; // => 'FieldArgument' +resolved.field.name; // => 'greeting' +resolved.fieldArgument.name; // => 'name' +``` + +### Types + +#### ResolvedSchemaElement -## Value Validation +**Type alias.** A schema element resolved from a schema coordinate. -### `isValidJSValue` + + +## Category: Type Comparisons + +
+

+ Functions:
+ isEqualType() + + isTypeSubTypeOf() + + doTypesOverlap() +

+
+ +### Functions + +#### isEqualType() + +Provided two types, return true if the types are equal (invariant). + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
typeAThe first GraphQL type to compare.
typeBThe second GraphQL type to compare.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when both types are equal.
+ +
+ +
Example
+ +```ts +import { + GraphQLList, + GraphQLNonNull, + GraphQLString, +} from 'graphql/type'; +import { isEqualType } from 'graphql/utilities'; + +isEqualType(GraphQLString, GraphQLString); // => true +isEqualType(new GraphQLList(GraphQLString), new GraphQLList(GraphQLString)); // => true +isEqualType(new GraphQLNonNull(GraphQLString), GraphQLString); // => false +``` + +
+ +#### isTypeSubTypeOf() + +Provided a type and a super type, return true if the first type is either +equal or a subset of the second super type (covariant). + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
maybeSubTypeThe possible subtype to compare.
superTypeThe possible supertype to compare.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when {"maybeSubType"} is equal to or a subtype of {"superType"}.
+ +
+ +
Example
```ts -function isValidJSValue(value: any, type: GraphQLInputType): string[]; +import { buildSchema } from 'graphql/utilities'; +import { + GraphQLNonNull, + assertInterfaceType, + assertObjectType, +} from 'graphql/type'; +import { isTypeSubTypeOf } from 'graphql/utilities'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Query { + node: Node + } +`); +const Node = assertInterfaceType(schema.getType('Node')); +const User = assertObjectType(schema.getType('User')); + +isTypeSubTypeOf(schema, User, Node); // => true +isTypeSubTypeOf(schema, new GraphQLNonNull(User), Node); // => true +isTypeSubTypeOf(schema, Node, User); // => false ``` -Given a JavaScript value and a GraphQL type, determine if the value will be -accepted for that type. This is primarily useful for validating the -runtime values of query variables. +
+ +#### doTypesOverlap() + +Provided two composite types, determine if they "overlap". Two composite +types overlap when the Sets of possible concrete types for each intersect. + +This is often used to determine if a fragment of a given type could possibly +be visited in a context of another type. + +This function is commutative. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
typeAThe first GraphQL type to compare.
typeBThe second GraphQL type to compare.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the two composite types can apply to at least one common object type.
-### `isValidLiteralValue` +
+ +
Example
```ts -function isValidLiteralValue(type: GraphQLInputType, valueAST: Value): string[]; +import { buildSchema } from 'graphql/utilities'; +import { assertObjectType, assertUnionType } from 'graphql/type'; +import { doTypesOverlap } from 'graphql/utilities'; + +const schema = buildSchema(` + type Photo { + url: String! + } + + type Video { + url: String! + } + + union Media = Photo | Video + union StillImage = Photo + + type Query { + media: [Media] + } +`); +const Media = assertUnionType(schema.getType('Media')); +const StillImage = assertUnionType(schema.getType('StillImage')); +const Video = assertObjectType(schema.getType('Video')); + +doTypesOverlap(schema, Media, StillImage); // => true +doTypesOverlap(schema, StillImage, Video); // => false ``` -Utility for validators which determines if a value literal AST is valid given -an input type. +## Category: Typed Documents + +
+

+ Types:
+ TypedQueryDocumentNode +

+
+ +### Types + +#### TypedQueryDocumentNode + +**Interface.** Wrapper type that contains DocumentNode and types that can be deduced from it. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TResponseDataTyped GraphQL response data shape.
TRequestVariablesTyped GraphQL request variables shape.
+ + + +
+ +
Members
-Note that this only validates literal values, variables are assumed to -provide values of the correct type. + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
definitionsTop-level executable and type-system definitions in this document.
__ensureTypesOfVariablesAndResultMatching?This type is used to ensure that the variables you pass in to the query are assignable to Variables
+and that the Result is assignable to whatever you pass your result to. The method is never actually
+implemented, but the type is valid because we list it as optional
diff --git a/website/pages/api-v16/utilities/_meta.ts b/website/pages/api-v16/utilities/_meta.ts new file mode 100644 index 0000000000..8cf3553390 --- /dev/null +++ b/website/pages/api-v16/utilities/_meta.ts @@ -0,0 +1,52 @@ +const meta = { + 'type-info': { + title: 'Category: Type Info', + href: '/api-v16/utilities#category-type-info', + }, + validation: { + title: 'Category: Validation', + href: '/api-v16/utilities#category-validation', + }, + values: { + title: 'Category: Values', + href: '/api-v16/utilities#category-values', + }, + 'schema-construction': { + title: 'Category: Schema Construction', + href: '/api-v16/utilities#category-schema-construction', + }, + introspection: { + title: 'Category: Introspection', + href: '/api-v16/utilities#category-introspection', + }, + 'ast-utilities': { + title: 'Category: AST Utilities', + href: '/api-v16/utilities#category-ast-utilities', + }, + 'schema-changes': { + title: 'Category: Schema Changes', + href: '/api-v16/utilities#category-schema-changes', + }, + operations: { + title: 'Category: Operations', + href: '/api-v16/utilities#category-operations', + }, + 'schema-printing': { + title: 'Category: Schema Printing', + href: '/api-v16/utilities#category-schema-printing', + }, + 'schema-coordinates': { + title: 'Category: Schema Coordinates', + href: '/api-v16/utilities#category-schema-coordinates', + }, + 'type-comparisons': { + title: 'Category: Type Comparisons', + href: '/api-v16/utilities#category-type-comparisons', + }, + 'typed-documents': { + title: 'Category: Typed Documents', + href: '/api-v16/utilities#category-typed-documents', + }, +}; + +export default meta; diff --git a/website/pages/api-v16/validation.mdx b/website/pages/api-v16/validation.mdx index 1acc121da6..f3ba63e551 100644 --- a/website/pages/api-v16/validation.mdx +++ b/website/pages/api-v16/validation.mdx @@ -1,46 +1,3995 @@ ---- -title: graphql/validation ---- +import { ApiSignature, ApiType } from '../../components/ApiCode'; -{/* title can be removed in Nextra 4, since sidebar title will take from first h1 */} +Validate GraphQL documents and schemas with the specified validation rules. -# `graphql/validation` +These exports are also available from the root `graphql` package. -The `graphql/validation` module fulfills the Validation phase of fulfilling a -GraphQL result. You can import either from the `graphql/validation` module, or from the root `graphql` module. For example: +For documentation purposes, these exports are grouped into the following categories: -```js -import { validate } from 'graphql/validation'; +- [Validation Context](/api-v16/validation#category-validation-context) +- [Validation Rules](/api-v16/validation#category-validation-rules) +- [Custom Rules](/api-v16/validation#category-custom-rules) +- [Validation](/api-v16/validation#category-validation) + +## Category: Validation Context + +
+

+ Classes:
+ ValidationContext +

+

+ Types:
+ ValidationRule +

+
+ +### Classes + +#### ValidationContext + +Validation context passed to query validation rules. + +
+ +##### Constructor + +Creates a ValidationContext instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaSchema used to validate the document.
astDocument AST being validated.
typeInfoTypeInfo instance used to track traversal state.
onErrorCallback invoked for each validation error.
+ +##### getSchema() + +Returns the schema being used by this validation context. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema being validated against.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { buildSchema, TypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const context = new ValidationContext( + schema, + parse('{ greeting }'), + new TypeInfo(schema), + () => {}, +); + +context.getSchema().getQueryType()?.name; // => 'Query' +``` + +
+ +##### getVariableUsages() + +Returns variable usages found directly within this node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to inspect or visit.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Variable usages found directly within this node.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { buildSchema, TypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + greeting(name: String): String + } +`); +const document = parse('query ($name: String) { greeting(name: $name) }'); +const operation = document.definitions[0]; +const context = new ValidationContext( + schema, + document, + new TypeInfo(schema), + () => {}, +); + +const usages = context.getVariableUsages(operation); + +usages[0].node.name.value; // => 'name' +String(usages[0].type); // => 'String' +``` + +
+ +##### getRecursiveVariableUsages() + +Returns variable usages for an operation, including variables used by referenced fragments. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
operationOperation definition to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Variable usages reachable from the operation.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { buildSchema, TypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + viewer: User + } + + type User { + name(prefix: String): String + } +`); +const document = parse(` + query ($prefix: String) { + viewer { + ...UserName + } + } + + fragment UserName on User { + name(prefix: $prefix) + } +`); +const operation = document.definitions[0]; +const context = new ValidationContext( + schema, + document, + new TypeInfo(schema), + () => {}, +); + +const usages = context.getRecursiveVariableUsages(operation); + +usages.map((usage) => usage.node.name.value); // => ['prefix'] +``` + +
+ +##### getType() + +Returns the current output type at this point in traversal. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current output type, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse('{ greeting }'); +const typeInfo = new TypeInfo(schema); +const context = new ValidationContext(schema, document, typeInfo, () => {}); +let typeName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + Field: () => { + typeName = String(context.getType()); + }, + }), +); + +typeName; // => 'String' +``` + +
+ +##### getParentType() + +Returns the current parent composite type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current parent composite type, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse('{ greeting }'); +const typeInfo = new TypeInfo(schema); +const context = new ValidationContext(schema, document, typeInfo, () => {}); +let parentTypeName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + Field: () => { + parentTypeName = context.getParentType()?.name; + }, + }), +); + +parentTypeName; // => 'Query' +``` + +
+ +##### getInputType() + +Returns the current input type at this point in traversal. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current input type, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + reviews(limit: Int): [String] + } +`); +const document = parse('{ reviews(limit: 5) }'); +const typeInfo = new TypeInfo(schema); +const context = new ValidationContext(schema, document, typeInfo, () => {}); +let inputTypeName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + Argument: () => { + inputTypeName = String(context.getInputType()); + }, + }), +); + +inputTypeName; // => 'Int' +``` + +
+ +##### getParentInputType() + +Returns the parent input type for the current input position. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The parent input type, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + input ReviewFilter { + stars: Int + } + + type Query { + reviews(filter: ReviewFilter): [String] + } +`); +const document = parse('{ reviews(filter: { stars: 5 }) }'); +const typeInfo = new TypeInfo(schema); +const context = new ValidationContext(schema, document, typeInfo, () => {}); +let parentInputTypeName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + ObjectField: () => { + parentInputTypeName = String(context.getParentInputType()); + }, + }), +); + +parentInputTypeName; // => 'ReviewFilter' +``` + +
+ +##### getFieldDef() + +Returns the current field definition. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current field definition, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse('{ greeting }'); +const typeInfo = new TypeInfo(schema); +const context = new ValidationContext(schema, document, typeInfo, () => {}); +let fieldName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + Field: () => { + fieldName = context.getFieldDef()?.name; + }, + }), +); + +fieldName; // => 'greeting' +``` + +
+ +##### getDirective() + +Returns the current directive definition. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current directive definition, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse('{ greeting @include(if: true) }'); +const typeInfo = new TypeInfo(schema); +const context = new ValidationContext(schema, document, typeInfo, () => {}); +let directiveName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + Directive: () => { + directiveName = context.getDirective()?.name; + }, + }), +); + +directiveName; // => 'include' +``` + +
+ +##### getArgument() + +Returns the current argument definition. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current argument definition, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + reviews(limit: Int): [String] + } +`); +const document = parse('{ reviews(limit: 5) }'); +const typeInfo = new TypeInfo(schema); +const context = new ValidationContext(schema, document, typeInfo, () => {}); +let argumentName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + Argument: () => { + argumentName = context.getArgument()?.name; + }, + }), +); + +argumentName; // => 'limit' +``` + +
+ +##### getEnumValue() + +Returns the current enum value definition. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current enum value definition, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + enum Sort { + NEWEST + OLDEST + } + + type Query { + reviews(sort: Sort): [String] + } +`); +const document = parse('{ reviews(sort: OLDEST) }'); +const typeInfo = new TypeInfo(schema); +const context = new ValidationContext(schema, document, typeInfo, () => {}); +let enumValueName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + EnumValue: () => { + enumValueName = context.getEnumValue()?.name; + }, + }), +); + +enumValueName; // => 'OLDEST' +``` + +### Types + +#### ValidationRule + +**Type alias.** A function that creates an AST visitor for validating a GraphQL document. + + + +## Category: Validation Rules + +
+

+ Functions:
+ ExecutableDefinitionsRule() + + FieldsOnCorrectTypeRule() + + FragmentsOnCompositeTypesRule() + + KnownArgumentNamesRule() + + KnownDirectivesRule() + + KnownFragmentNamesRule() + + KnownTypeNamesRule() + + LoneAnonymousOperationRule() + + LoneSchemaDefinitionRule() + + MaxIntrospectionDepthRule() + + NoFragmentCyclesRule() + + NoUndefinedVariablesRule() + + NoUnusedFragmentsRule() + + NoUnusedVariablesRule() + + OverlappingFieldsCanBeMergedRule() + + PossibleFragmentSpreadsRule() + + PossibleTypeExtensionsRule() + + ProvidedRequiredArgumentsRule() + + ScalarLeafsRule() + + SingleFieldSubscriptionsRule() + + UniqueArgumentDefinitionNamesRule() + + UniqueArgumentNamesRule() + + UniqueDirectiveNamesRule() + + UniqueDirectivesPerLocationRule() + + UniqueEnumValueNamesRule() + + UniqueFieldDefinitionNamesRule() + + UniqueFragmentNamesRule() + + UniqueInputFieldNamesRule() + + UniqueOperationNamesRule() + + UniqueOperationTypesRule() + + UniqueTypeNamesRule() + + UniqueVariableNamesRule() + + ValuesOfCorrectTypeRule() + + VariablesAreInputTypesRule() + + VariablesInAllowedPositionRule() +

+

+ Constants:
+ recommendedRules + + specifiedRules +

+
+ +### Functions + +#### ExecutableDefinitionsRule() + +Executable definitions + +A GraphQL document is only valid for execution if all definitions are either +operation or fragment definitions. + +See https://spec.graphql.org/draft/#sec-Executable-Definitions + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { ExecutableDefinitionsRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + type Extra { field: String } +`); +const invalidErrors = validate(schema, invalidDocument, [ExecutableDefinitionsRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { name } +`); +const validErrors = validate(schema, validDocument, [ExecutableDefinitionsRule]); + +validErrors; // => [] +``` + +
+ +#### FieldsOnCorrectTypeRule() + +Fields on correct type + +A GraphQL document is only valid if all fields selected are defined by the +parent type, or are an allowed meta field such as __typename. + +See https://spec.graphql.org/draft/#sec-Field-Selections + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { FieldsOnCorrectTypeRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + { missing } +`); +const invalidErrors = validate(schema, invalidDocument, [FieldsOnCorrectTypeRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { name } +`); +const validErrors = validate(schema, validDocument, [FieldsOnCorrectTypeRule]); + +validErrors; // => [] +``` + +
+ +#### FragmentsOnCompositeTypesRule() + +Fragments on composite type + +Fragments use a type condition to determine if they apply, since fragments +can only be spread into a composite type (object, interface, or union), the +type condition must also be a composite type. + +See https://spec.graphql.org/draft/#sec-Fragments-On-Composite-Types + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { FragmentsOnCompositeTypesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + fragment Bad on String { length } +`); +const invalidErrors = validate(schema, invalidDocument, [FragmentsOnCompositeTypesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + fragment Good on Query { name } +`); +const validErrors = validate(schema, validDocument, [FragmentsOnCompositeTypesRule]); + +validErrors; // => [] +``` + +
+ +#### KnownArgumentNamesRule() + +Known argument names + +A GraphQL field is only valid if all supplied arguments are defined by +that field. + +See https://spec.graphql.org/draft/#sec-Argument-Names +See https://spec.graphql.org/draft/#sec-Directives-Are-In-Valid-Locations + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { KnownArgumentNamesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + field(arg: String): String + } +`); + +const invalidDocument = parse(` + { field(unknown: "1") } +`); +const invalidErrors = validate(schema, invalidDocument, [KnownArgumentNamesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { field(arg: "1") } +`); +const validErrors = validate(schema, validDocument, [KnownArgumentNamesRule]); + +validErrors; // => [] +``` + +
+ +#### KnownDirectivesRule() + +Known directives + +A GraphQL document is only valid if all `@directives` are known by the +schema and legally positioned. + +See https://spec.graphql.org/draft/#sec-Directives-Are-Defined + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { KnownDirectivesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + { name @unknown } +`); +const invalidErrors = validate(schema, invalidDocument, [KnownDirectivesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { name @include(if: true) } +`); +const validErrors = validate(schema, validDocument, [KnownDirectivesRule]); + +validErrors; // => [] +``` + +
+ +#### KnownFragmentNamesRule() + +Known fragment names + +A GraphQL document is only valid if all `...Fragment` fragment spreads refer +to fragments defined in the same document. + +See https://spec.graphql.org/draft/#sec-Fragment-spread-target-defined + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { KnownFragmentNamesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + { ...Missing } +`); +const invalidErrors = validate(schema, invalidDocument, [KnownFragmentNamesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + fragment NameFields on Query { name } query { ...NameFields } +`); +const validErrors = validate(schema, validDocument, [KnownFragmentNamesRule]); + +validErrors; // => [] +``` + +
+ +#### KnownTypeNamesRule() + +Known type names + +A GraphQL document is only valid if referenced types (specifically +variable definitions and fragment conditions) are defined by the type schema. + +See https://spec.graphql.org/draft/#sec-Fragment-Spread-Type-Existence + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { KnownTypeNamesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + fragment Bad on Missing { name } +`); +const invalidErrors = validate(schema, invalidDocument, [KnownTypeNamesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + fragment Good on Query { name } +`); +const validErrors = validate(schema, validDocument, [KnownTypeNamesRule]); + +validErrors; // => [] +``` + +
+ +#### LoneAnonymousOperationRule() + +Lone anonymous operation + +A GraphQL document is only valid if when it contains an anonymous operation +(the query short-hand) that it contains only that one operation definition. + +See https://spec.graphql.org/draft/#sec-Lone-Anonymous-Operation + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { LoneAnonymousOperationRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + query { name } query Other { name } +`); +const invalidErrors = validate(schema, invalidDocument, [LoneAnonymousOperationRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { name } +`); +const validErrors = validate(schema, validDocument, [LoneAnonymousOperationRule]); + +validErrors; // => [] +``` + +
+ +#### LoneSchemaDefinitionRule() + +Lone Schema definition + +A GraphQL document is only valid if it contains only one schema definition. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql'; +import { LoneSchemaDefinitionRule } from 'graphql/validation'; + +const invalidSDL = ` + schema { query: Query } schema { query: Query } type Query { name: String } +`; + +LoneSchemaDefinitionRule.name; // => 'LoneSchemaDefinitionRule' +buildSchema(invalidSDL); // throws an error + +const validSDL = ` + schema { query: Query } type Query { name: String } +`; + +buildSchema(validSDL); // does not throw +``` + +
+ +#### MaxIntrospectionDepthRule() + +Implements the max introspection depth validation rule. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { MaxIntrospectionDepthRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + { __schema { types { fields { type { fields { type { fields { name } } } } } } } } +`); +const invalidErrors = validate(schema, invalidDocument, [MaxIntrospectionDepthRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { __schema { queryType { name } } } +`); +const validErrors = validate(schema, validDocument, [MaxIntrospectionDepthRule]); + +validErrors; // => [] +``` + +
+ +#### NoFragmentCyclesRule() + +No fragment cycles + +The graph of fragment spreads must not form any cycles including spreading itself. +Otherwise an operation could infinitely spread or infinitely execute on cycles in the underlying data. + +See https://spec.graphql.org/draft/#sec-Fragment-spreads-must-not-form-cycles + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { NoFragmentCyclesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + fragment A on Query { ...B } fragment B on Query { ...A } query { ...A } +`); +const invalidErrors = validate(schema, invalidDocument, [NoFragmentCyclesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + fragment A on Query { name } query { ...A } +`); +const validErrors = validate(schema, validDocument, [NoFragmentCyclesRule]); + +validErrors; // => [] +``` + +
+ +#### NoUndefinedVariablesRule() + +No undefined variables + +A GraphQL operation is only valid if all variables encountered, both directly +and via fragment spreads, are defined by that operation. + +See https://spec.graphql.org/draft/#sec-All-Variable-Uses-Defined + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { NoUndefinedVariablesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + field(arg: ID): String + } +`); + +const invalidDocument = parse(` + query ($id: ID) { field(arg: $missing) } +`); +const invalidErrors = validate(schema, invalidDocument, [NoUndefinedVariablesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + query ($id: ID) { field(arg: $id) } +`); +const validErrors = validate(schema, validDocument, [NoUndefinedVariablesRule]); + +validErrors; // => [] +``` + +
+ +#### NoUnusedFragmentsRule() + +No unused fragments + +A GraphQL document is only valid if all fragment definitions are spread +within operations, or spread within other fragments spread within operations. + +See https://spec.graphql.org/draft/#sec-Fragments-Must-Be-Used + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { NoUnusedFragmentsRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + fragment Unused on Query { name } query { name } +`); +const invalidErrors = validate(schema, invalidDocument, [NoUnusedFragmentsRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + fragment Used on Query { name } query { ...Used } +`); +const validErrors = validate(schema, validDocument, [NoUnusedFragmentsRule]); + +validErrors; // => [] +``` + +
+ +#### NoUnusedVariablesRule() + +No unused variables + +A GraphQL operation is only valid if all variables defined by an operation +are used, either directly or within a spread fragment. + +See https://spec.graphql.org/draft/#sec-All-Variables-Used + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { NoUnusedVariablesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + field(arg: ID): String + name: String + } +`); + +const invalidDocument = parse(` + query ($id: ID) { name } +`); +const invalidErrors = validate(schema, invalidDocument, [NoUnusedVariablesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + query ($id: ID) { field(arg: $id) } +`); +const validErrors = validate(schema, validDocument, [NoUnusedVariablesRule]); + +validErrors; // => [] +``` + +
+ +#### OverlappingFieldsCanBeMergedRule() + +Overlapping fields can be merged + +A selection set is only valid if all fields (including spreading any +fragments) either correspond to distinct response names or can be merged +without ambiguity. + +See https://spec.graphql.org/draft/#sec-Field-Selection-Merging + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { OverlappingFieldsCanBeMergedRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + dog: Dog + } + + type Dog { + name: String + barkVolume: Int + } +`); + +const invalidDocument = parse(` + { dog { value: barkVolume value: name } } +`); +const invalidErrors = validate(schema, invalidDocument, [OverlappingFieldsCanBeMergedRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { dog { barkVolume name } } +`); +const validErrors = validate(schema, validDocument, [OverlappingFieldsCanBeMergedRule]); + +validErrors; // => [] +``` + +
+ +#### PossibleFragmentSpreadsRule() + +Possible fragment spread + +A fragment spread is only valid if the type condition could ever possibly +be true: if there is a non-empty intersection of the possible parent types, +and possible types which pass the type condition. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { PossibleFragmentSpreadsRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + dog: Dog + } + + type Dog { + barkVolume: Int + } + + type Cat { + meowVolume: Int + } +`); + +const invalidDocument = parse(` + { dog { ... on Cat { meowVolume } } } +`); +const invalidErrors = validate(schema, invalidDocument, [PossibleFragmentSpreadsRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { dog { ... on Dog { barkVolume } } } +`); +const validErrors = validate(schema, validDocument, [PossibleFragmentSpreadsRule]); + +validErrors; // => [] +``` + +
+ +#### PossibleTypeExtensionsRule() + +Possible type extension + +A type extension is only valid if the type is defined and has the same kind. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql'; +import { PossibleTypeExtensionsRule } from 'graphql/validation'; + +const invalidSDL = ` + extend type Missing { name: String } type Query { name: String } +`; + +PossibleTypeExtensionsRule.name; // => 'PossibleTypeExtensionsRule' +buildSchema(invalidSDL); // throws an error + +const validSDL = ` + type Query { name: String } extend type Query { other: String } +`; + +buildSchema(validSDL); // does not throw +``` + +
+ +#### ProvidedRequiredArgumentsRule() + +Provided required arguments + +A field or directive is only valid if all required (non-null without a +default value) field arguments have been provided. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { ProvidedRequiredArgumentsRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + field(required: String!): String + } +`); + +const invalidDocument = parse(` + { field } +`); +const invalidErrors = validate(schema, invalidDocument, [ProvidedRequiredArgumentsRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { field(required: "x") } +`); +const validErrors = validate(schema, validDocument, [ProvidedRequiredArgumentsRule]); + +validErrors; // => [] +``` + +
+ +#### ScalarLeafsRule() + +Scalar leafs + +A GraphQL document is valid only if all leaf fields (fields without +sub selections) are of scalar or enum types. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { ScalarLeafsRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + { name { length } } +`); +const invalidErrors = validate(schema, invalidDocument, [ScalarLeafsRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { name } +`); +const validErrors = validate(schema, validDocument, [ScalarLeafsRule]); + +validErrors; // => [] +``` + +
+ +#### SingleFieldSubscriptionsRule() + +Subscriptions must only include a non-introspection field. + +A GraphQL subscription is valid only if it contains a single root field and +that root field is not an introspection field. + +See https://spec.graphql.org/draft/#sec-Single-root-field + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { SingleFieldSubscriptionsRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } + + type Subscription { + a: String + b: String + } +`); + +const invalidDocument = parse(` + subscription { a b } +`); +const invalidErrors = validate(schema, invalidDocument, [SingleFieldSubscriptionsRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + subscription { a } +`); +const validErrors = validate(schema, validDocument, [SingleFieldSubscriptionsRule]); + +validErrors; // => [] +``` + +
+ +#### UniqueArgumentDefinitionNamesRule() + +Unique argument definition names + +A GraphQL Object or Interface type is only valid if all its fields have uniquely named arguments. +A GraphQL Directive is only valid if all its arguments are uniquely named. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql'; +import { UniqueArgumentDefinitionNamesRule } from 'graphql/validation'; + +const invalidSDL = ` + type Query { field(arg: String, arg: Int): String } +`; + +UniqueArgumentDefinitionNamesRule.name; // => 'UniqueArgumentDefinitionNamesRule' +buildSchema(invalidSDL); // throws an error + +const validSDL = ` + type Query { field(arg: String): String } +`; + +buildSchema(validSDL); // does not throw +``` + +
+ +#### UniqueArgumentNamesRule() + +Unique argument names + +A GraphQL field or directive is only valid if all supplied arguments are +uniquely named. + +See https://spec.graphql.org/draft/#sec-Argument-Names + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { UniqueArgumentNamesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + field(arg: String): String + } +`); + +const invalidDocument = parse(` + { field(arg: "1", arg: "2") } +`); +const invalidErrors = validate(schema, invalidDocument, [UniqueArgumentNamesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { field(arg: "1") } +`); +const validErrors = validate(schema, validDocument, [UniqueArgumentNamesRule]); + +validErrors; // => [] +``` + +
+ +#### UniqueDirectiveNamesRule() + +Unique directive names + +A GraphQL document is only valid if all defined directives have unique names. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql'; +import { UniqueDirectiveNamesRule } from 'graphql/validation'; + +const invalidSDL = ` + directive @tag on FIELD directive @tag on QUERY type Query { name: String } +`; + +UniqueDirectiveNamesRule.name; // => 'UniqueDirectiveNamesRule' +buildSchema(invalidSDL); // throws an error + +const validSDL = ` + directive @tag on FIELD type Query { name: String } +`; + +buildSchema(validSDL); // does not throw +``` + +
+ +#### UniqueDirectivesPerLocationRule() + +Unique directive names per location + +A GraphQL document is only valid if all non-repeatable directives at +a given location are uniquely named. + +See https://spec.graphql.org/draft/#sec-Directives-Are-Unique-Per-Location + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { UniqueDirectivesPerLocationRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + { name @include(if: true) @include(if: false) } +`); +const invalidErrors = validate(schema, invalidDocument, [UniqueDirectivesPerLocationRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { name @include(if: true) } +`); +const validErrors = validate(schema, validDocument, [UniqueDirectivesPerLocationRule]); + +validErrors; // => [] +``` + +
+ +#### UniqueEnumValueNamesRule() + +Unique enum value names + +A GraphQL enum type is only valid if all its values are uniquely named. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql'; +import { UniqueEnumValueNamesRule } from 'graphql/validation'; + +const invalidSDL = ` + enum Status { ACTIVE ACTIVE } type Query { status: Status } +`; + +UniqueEnumValueNamesRule.name; // => 'UniqueEnumValueNamesRule' +buildSchema(invalidSDL); // throws an error + +const validSDL = ` + enum Status { ACTIVE INACTIVE } type Query { status: Status } +`; + +buildSchema(validSDL); // does not throw +``` + +
+ +#### UniqueFieldDefinitionNamesRule() + +Unique field definition names + +A GraphQL complex type is only valid if all its fields are uniquely named. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql'; +import { UniqueFieldDefinitionNamesRule } from 'graphql/validation'; + +const invalidSDL = ` + type Query { name: String name: String } +`; + +UniqueFieldDefinitionNamesRule.name; // => 'UniqueFieldDefinitionNamesRule' +buildSchema(invalidSDL); // throws an error + +const validSDL = ` + type Query { name: String other: String } +`; + +buildSchema(validSDL); // does not throw +``` + +
+ +#### UniqueFragmentNamesRule() + +Unique fragment names + +A GraphQL document is only valid if all defined fragments have unique names. + +See https://spec.graphql.org/draft/#sec-Fragment-Name-Uniqueness + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { UniqueFragmentNamesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + fragment A on Query { name } fragment A on Query { name } query { ...A } +`); +const invalidErrors = validate(schema, invalidDocument, [UniqueFragmentNamesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + fragment A on Query { name } query { ...A } +`); +const validErrors = validate(schema, validDocument, [UniqueFragmentNamesRule]); + +validErrors; // => [] +``` + +
+ +#### UniqueInputFieldNamesRule() + +Unique input field names + +A GraphQL input object value is only valid if all supplied fields are +uniquely named. + +See https://spec.graphql.org/draft/#sec-Input-Object-Field-Uniqueness + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { UniqueInputFieldNamesRule } from 'graphql/validation'; + +const schema = buildSchema(` + input Filter { + name: String + } + + type Query { + search(filter: Filter): String + } +`); + +const invalidDocument = parse(` + { search(filter: { name: "a", name: "b" }) } +`); +const invalidErrors = validate(schema, invalidDocument, [UniqueInputFieldNamesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { search(filter: { name: "a" }) } +`); +const validErrors = validate(schema, validDocument, [UniqueInputFieldNamesRule]); + +validErrors; // => [] +``` + +
+ +#### UniqueOperationNamesRule() + +Unique operation names + +A GraphQL document is only valid if all defined operations have unique names. + +See https://spec.graphql.org/draft/#sec-Operation-Name-Uniqueness + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { UniqueOperationNamesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + query Same { name } query Same { name } +`); +const invalidErrors = validate(schema, invalidDocument, [UniqueOperationNamesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + query One { name } query Two { name } +`); +const validErrors = validate(schema, validDocument, [UniqueOperationNamesRule]); + +validErrors; // => [] +``` + +
+ +#### UniqueOperationTypesRule() + +Unique operation types + +A GraphQL document is only valid if it has only one type per operation. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql'; +import { UniqueOperationTypesRule } from 'graphql/validation'; + +const invalidSDL = ` + schema { query: Query query: Other } type Query { name: String } type Other { name: String } +`; + +UniqueOperationTypesRule.name; // => 'UniqueOperationTypesRule' +buildSchema(invalidSDL); // throws an error + +const validSDL = ` + schema { query: Query } type Query { name: String } +`; + +buildSchema(validSDL); // does not throw +``` + +
+ +#### UniqueTypeNamesRule() + +Unique type names + +A GraphQL document is only valid if all defined types have unique names. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql'; +import { UniqueTypeNamesRule } from 'graphql/validation'; + +const invalidSDL = ` + type Query { name: String } type Query { other: String } +`; + +UniqueTypeNamesRule.name; // => 'UniqueTypeNamesRule' +buildSchema(invalidSDL); // throws an error + +const validSDL = ` + type Query { name: String } type Other { name: String } +`; + +buildSchema(validSDL); // does not throw +``` + +
+ +#### UniqueVariableNamesRule() + +Unique variable names + +A GraphQL operation is only valid if all its variables are uniquely named. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { UniqueVariableNamesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + field(arg: ID): String + } +`); + +const invalidDocument = parse(` + query ($id: ID, $id: ID) { field(arg: $id) } +`); +const invalidErrors = validate(schema, invalidDocument, [UniqueVariableNamesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + query ($id: ID) { field(arg: $id) } +`); +const validErrors = validate(schema, validDocument, [UniqueVariableNamesRule]); + +validErrors; // => [] +``` + +
+ +#### ValuesOfCorrectTypeRule() + +Value literals of correct type + +A GraphQL document is only valid if all value literals are of the type +expected at their position. + +See https://spec.graphql.org/draft/#sec-Values-of-Correct-Type + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { ValuesOfCorrectTypeRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + count(limit: Int): Int + } +`); + +const invalidDocument = parse(` + { count(limit: "many") } +`); +const invalidErrors = validate(schema, invalidDocument, [ValuesOfCorrectTypeRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { count(limit: 1) } +`); +const validErrors = validate(schema, validDocument, [ValuesOfCorrectTypeRule]); + +validErrors; // => [] +``` + +
+ +#### VariablesAreInputTypesRule() + +Variables are input types + +A GraphQL operation is only valid if all the variables it defines are of +input types (scalar, enum, or input object). + +See https://spec.graphql.org/draft/#sec-Variables-Are-Input-Types + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { VariablesAreInputTypesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + field(arg: ID): String + } + + type User { + name: String + } +`); + +const invalidDocument = parse(` + query ($user: User) { field(arg: "1") } +`); +const invalidErrors = validate(schema, invalidDocument, [VariablesAreInputTypesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + query ($id: ID) { field(arg: $id) } +`); +const validErrors = validate(schema, validDocument, [VariablesAreInputTypesRule]); + +validErrors; // => [] +``` + +
+ +#### VariablesInAllowedPositionRule() + +Variables in allowed position + +Variable usages must be compatible with the arguments they are passed to. + +See https://spec.graphql.org/draft/#sec-All-Variable-Usages-are-Allowed + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { VariablesInAllowedPositionRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + field(arg: ID!): String + } +`); + +const invalidDocument = parse(` + query ($id: String) { field(arg: $id) } +`); +const invalidErrors = validate(schema, invalidDocument, [VariablesInAllowedPositionRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + query ($id: ID!) { field(arg: $id) } +`); +const validErrors = validate(schema, validDocument, [VariablesInAllowedPositionRule]); + +validErrors; // => [] +``` + +### Constants + +#### recommendedRules + +Technically these aren't part of the spec but they are strongly encouraged +validation rules. + +
+ +
Type
+ + + +
+ +#### specifiedRules + +This set includes all validation rules defined by the GraphQL spec. + +The order of the rules in this list has been adjusted to lead to the +most clear output when encountering multiple validation errors. + +
+ +
Type
+ + + +## Category: Custom Rules + + + +### Functions + +#### NoDeprecatedCustomRule() + +No deprecated + +A GraphQL document is only valid if all selected fields and all used enum values have not been +deprecated. + +Note: This rule is optional and is not part of the Validation section of the GraphQL +Specification. The main purpose of this rule is detection of deprecated usages and not +necessarily to forbid their use when querying a service. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { + GraphQLObjectType, + GraphQLSchema, + GraphQLString, + parse, + validate, +} from 'graphql'; +import { NoDeprecatedCustomRule } from 'graphql/validation'; + +const schema = new GraphQLSchema({ + query: new GraphQLObjectType({ + name: 'Query', + fields: { + name: { type: GraphQLString }, + oldName: { + type: GraphQLString, + deprecationReason: 'Use name instead.', + }, + }, + }), +}); + +const invalidDocument = parse(` + { oldName } +`); +const invalidErrors = validate(schema, invalidDocument, [NoDeprecatedCustomRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { name } +`); +const validErrors = validate(schema, validDocument, [NoDeprecatedCustomRule]); + +validErrors; // => [] ``` -## Overview +
+ +#### NoSchemaIntrospectionCustomRule() + +Prohibit introspection queries + +A GraphQL document is only valid if all fields selected are not fields that +return an introspection type. + +Note: This rule is optional and is not part of the Validation section of the +GraphQL Specification. This rule effectively disables introspection, which +does not reflect best practices and should only be done if absolutely necessary. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
- +
-## Validation +
Returns
-### `validate` + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
```ts -function validate( - schema: GraphQLSchema, - ast: Document, - rules?: any[], -): GraphQLError[]; +import { buildSchema, parse, validate } from 'graphql'; +import { NoSchemaIntrospectionCustomRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + { __schema { queryType { name } } } +`); +const invalidErrors = validate(schema, invalidDocument, [NoSchemaIntrospectionCustomRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { name } +`); +const validErrors = validate(schema, validDocument, [NoSchemaIntrospectionCustomRule]); + +validErrors; // => [] ``` +## Category: Validation + +
+

+ Functions:
+ validate() +

+
+ +### Functions + +#### validate() + Implements the "Validation" section of the spec. Validation runs synchronously, returning an array of encountered errors, or @@ -49,18 +3998,134 @@ an empty array if no errors were encountered and the document is valid. A list of specific validation rules may be provided. If not provided, the default list of rules defined by the GraphQL specification will be used. -Each validation rules is a function which returns a visitor +Each validation rule is a function that returns a visitor (see the language/visitor API). Visitor methods are expected to return GraphQLErrors, or Arrays of GraphQLErrors when invalid. -Visitors can also supply `visitSpreadFragments: true` which will alter the -behavior of the visitor to skip over top level defined fragments, and instead -visit those fragments at every point a spread is encountered. +Validate will stop validation after a `maxErrors` limit has been reached. +Attackers can send pathologically invalid queries to induce a DoS attack, +so `maxErrors` defaults to 100 errors. + +Optionally a custom TypeInfo instance may be provided. If not provided, one +will be created from the provided schema. + +**Signature:** + + + +
+ +
Arguments
-### `specifiedRules` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
schemaSchema to validate against.
documentASTDocument AST to validate.
rulesValidation rules to apply.
options?Validation options, including error limits.
typeInfoTypeInfo instance to update during traversal.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Validation errors, or an empty array when the document is valid.
+ +
+ +
Example 1
```ts -let specifiedRules: Array<(context: ValidationContext) => any>; +// Validate with the default specified rules. +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { validate } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); + +validate(schema, parse('{ greeting }')); // => [] + +const errors = validate(schema, parse('{ missing }')); +errors[0].message; // => 'Cannot query field "missing" on type "Query".' ``` -This set includes all validation rules defined by the GraphQL spec +
+ +
Example 2
+ +```ts +// This variant uses a custom rule list, TypeInfo, and validation options. +import { parse } from 'graphql/language'; +import { buildSchema, TypeInfo } from 'graphql/utilities'; +import { FieldsOnCorrectTypeRule, validate } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse('{ missingOne missingTwo }'); + +const errors = validate( + schema, + document, + [FieldsOnCorrectTypeRule], + { maxErrors: 1 }, + new TypeInfo(schema), +); + +errors.length; // => 2 +errors[1].message; // => 'Too many validation errors, error limit reached. Validation aborted.' +``` diff --git a/website/pages/api-v16/validation/_meta.ts b/website/pages/api-v16/validation/_meta.ts new file mode 100644 index 0000000000..b52b9df178 --- /dev/null +++ b/website/pages/api-v16/validation/_meta.ts @@ -0,0 +1,20 @@ +const meta = { + 'validation-context': { + title: 'Category: Validation Context', + href: '/api-v16/validation#category-validation-context', + }, + 'validation-rules': { + title: 'Category: Validation Rules', + href: '/api-v16/validation#category-validation-rules', + }, + 'custom-rules': { + title: 'Category: Custom Rules', + href: '/api-v16/validation#category-custom-rules', + }, + validation: { + title: 'Category: Validation', + href: '/api-v16/validation#category-validation', + }, +}; + +export default meta; diff --git a/website/pages/api-v17/_meta.ts b/website/pages/api-v17/_meta.ts new file mode 100644 index 0000000000..69ab7ef3cf --- /dev/null +++ b/website/pages/api-v17/_meta.ts @@ -0,0 +1,11 @@ +const meta = { + graphql: 'graphql', + error: 'graphql/error', + execution: 'graphql/execution', + language: 'graphql/language', + type: 'graphql/type', + utilities: 'graphql/utilities', + validation: 'graphql/validation', +}; + +export default meta; diff --git a/website/pages/api-v17/error.mdx b/website/pages/api-v17/error.mdx new file mode 100644 index 0000000000..1e1bb968b6 --- /dev/null +++ b/website/pages/api-v17/error.mdx @@ -0,0 +1,505 @@ +import { ApiSignature, ApiType } from '../../components/ApiCode'; + +Create, format, and locate GraphQL errors. + +These exports are also available from the root `graphql` package. + +
+

+ Classes:
+ GraphQLError +

+

+ Functions:
+ locatedError() + + syntaxError() +

+

+ Types:
+ GraphQLErrorExtensions + + GraphQLFormattedErrorExtensions + + GraphQLErrorOptions + + GraphQLFormattedError +

+
+ +## Classes + +### GraphQLError + +A GraphQLError describes an Error found during the parse, validate, or +execute phases of performing a GraphQL operation. In addition to a message +and stack trace, it also includes information about the locations in a +GraphQL document and/or execution result that correspond to the Error. + +
+ +#### Constructor + +Creates a GraphQLError instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
messageHuman-readable error message.
optionsError metadata such as source locations, response path, original error, and extensions.
+ +
+ +#### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
locationsAn array of {"{ line, column }"} locations within the source GraphQL document
+which correspond to this error.
+Errors during validation often contain multiple locations, for example to
+point out two things with the same name. Errors during execution include a
+single location, the field which produced the error.
+Enumerable, and appears in the result of JSON.stringify().
pathAn array describing the JSON-path into the execution response which
+corresponds to this error. Only included for errors during execution.
+Enumerable, and appears in the result of JSON.stringify().
nodesAn array of GraphQL AST Nodes corresponding to this error.
sourceThe source GraphQL document for the first location of this error.
+Note that if this Error represents more than one node, the source may not
+represent nodes after the first node.
positionsAn array of character offsets within the source GraphQL document
+which correspond to this error.
originalErrorOriginal error that caused this GraphQLError, if one exists.
extensionsExtension fields to add to the formatted error.
+ +
+ +#### toString() + +Returns this error as a human-readable message with source locations. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The formatted error string.
+ +
+ +
Example
+ +```ts +import { Source } from 'graphql/language'; +import { GraphQLError } from 'graphql/error'; + +const error = new GraphQLError('Cannot query field "name".', { + source: new Source('{ name }'), + positions: [2], +}); + +error.toString(); // => 'Cannot query field "name".\n\nGraphQL request:1:3\n1 | { name }\n | ^' +``` + +
+ +#### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { GraphQLError } from 'graphql/error'; + +const error = new GraphQLError('Resolver failed.', { + path: ['viewer', 'name'], + extensions: { code: 'INTERNAL' }, +}); + +error.toJSON(); // => { message: 'Resolver failed.', path: ['viewer', 'name'], extensions: { code: 'INTERNAL' } } +``` + +## Functions + +### locatedError() + +Given an arbitrary value, presumably thrown while attempting to execute a +GraphQL operation, produce a new GraphQLError aware of the location in the +document responsible for the original Error. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
rawOriginalErrorThe original error value to wrap.
nodesThe AST nodes associated with the error.
path?The response path associated with the error.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The GraphQL error.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { locatedError } from 'graphql/error'; + +const document = parse('{ viewer { name } }'); +const fieldNode = document.definitions[0].selectionSet.selections[0]; +const error = locatedError(new Error('Resolver failed'), fieldNode, [ + 'viewer', +]); + +error.message; // => 'Resolver failed' +error.locations; // => [{ line: 1, column: 3 }] +error.path; // => ['viewer'] +``` + +
+ +### syntaxError() + +Produces a GraphQLError representing a syntax error, containing useful +descriptive information about the syntax error's position in the source. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourceThe GraphQL source containing the syntax error.
positionCharacter offset where the syntax error was encountered.
descriptionHuman-readable description of the syntax error.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A GraphQLError located at the syntax error position.
+ +
+ +
Example
+ +```ts +import { Source } from 'graphql/language'; +import { syntaxError } from 'graphql/error'; + +const error = syntaxError(new Source('query {'), 7, 'Expected Name'); + +error.message; // => 'Syntax Error: Expected Name' +error.locations; // => [{ line: 1, column: 8 }] +``` + +## Types + +### GraphQLErrorExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +### GraphQLFormattedErrorExtensions + +**Interface.** Custom formatted extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +### GraphQLErrorOptions + +**Interface.** Options used to construct a GraphQLError. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nodes?AST node or nodes associated with this error.
source?Source document used to derive error locations.
positions?Character offsets in the source document associated with this error.
path?Response path where this error occurred during execution.
originalError?Original error that caused this GraphQLError, if one exists.
extensions?Extension fields to include in the formatted result.
+ +
+ +### GraphQLFormattedError + +**Interface.** See: https://spec.graphql.org/draft/#sec-Errors + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
messageA short, human-readable summary of the problem that **SHOULD NOT** change
+from occurrence to occurrence of the problem, except for purposes of
+localization.
locations?If an error can be associated to a particular point in the requested
+GraphQL document, it should contain a list of locations.
path?If an error can be associated to a particular field in the GraphQL result,
+it _must_ contain an entry with the key {"path"} that details the path of
+the response field which experienced the error. This allows clients to
+identify whether a null result is intentional or caused by a runtime error.
extensions?Reserved for implementors to extend the protocol however they see fit,
+and hence there are no additional restrictions on its contents.
diff --git a/website/pages/api-v17/execution.mdx b/website/pages/api-v17/execution.mdx new file mode 100644 index 0000000000..613a823e93 --- /dev/null +++ b/website/pages/api-v17/execution.mdx @@ -0,0 +1,4174 @@ +import { ApiSignature, ApiType } from '../../components/ApiCode'; + +Execute GraphQL operations and produce GraphQL execution results. + +These exports are also available from the root `graphql` package. + +For documentation purposes, these exports are grouped into the following categories: + +- [Execution](/api-v17/execution#category-execution) +- [Incremental Execution](/api-v17/execution#category-incremental-execution) +- [Legacy Incremental Execution](/api-v17/execution#category-legacy-incremental-execution) +- [Values](/api-v17/execution#category-values) +- [Paths](/api-v17/execution#category-paths) + +## Category: Execution + + + +### Classes + +#### AbortedGraphQLExecutionError + +Error thrown when GraphQL execution is aborted. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TResultResult value type.
+ +
+ +##### Constructor + +Creates an error for an aborted GraphQL execution. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
reasonAbort reason used as the error cause.
resultPartial execution result available when execution stopped.
+ +
+ +##### Members + + + + + + + + + + + + + + + + +
NameTypeDescription
abortedResultPartial execution result available when execution was aborted.
+ +### Functions + +#### execute() + +Implements the "Executing requests" section of the GraphQL specification. + +Returns either a synchronous ExecutionResult (if all encountered resolvers +are synchronous), or a Promise of an ExecutionResult that will eventually be +resolved and never rejected. + +If the arguments to this function do not result in a legal execution context, +a GraphQLError will be thrown immediately explaining the invalid input. + +Field errors are collected into the response instead of rejecting the +returned promise. Only the field that produced the error and its descendants +are omitted; sibling fields continue to execute. Errors from fields of +non-null type may propagate to the nearest nullable parent, which can be the +entire response data. + +This function does not support incremental delivery (`@defer` and `@stream`). +Use [`experimentalExecuteIncrementally`](/api-v17/execution#experimentalexecuteincrementally) to execute operations with +incremental delivery enabled. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
argsThe arguments used to perform the operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A completed execution result, or a promise resolving to one when execution is asynchronous.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { execute } from 'graphql/execution'; + +const schema = buildSchema(` + type Query { + greeting(name: String!): String + } +`); + +const result = await execute({ + schema, + document: parse('query ($name: String!) { greeting(name: $name) }'), + rootValue: { + greeting: ({ name }) => `Hello, ${name}!`, + }, + variableValues: { name: 'Ada' }, +}); + +result; // => { data: { greeting: 'Hello, Ada!' } } +``` + +
+ +#### executeRootSelectionSet() + +Implements the "Executing operations" section of the spec. + +Returns a Promise that will eventually resolve to the data described by +The "Response" section of the GraphQL specification. + +If errors are encountered while executing a GraphQL field, only that +field and its descendants will be omitted, and sibling fields will still +be executed. An execution which encounters errors will still result in a +resolved Promise. + +Errors from sub-fields of a NonNull type may propagate to the top level, +at which point we still log the error and null the parent field, which +in this case is the entire response. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
validatedExecutionArgsValidated execution arguments.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Execution result for the operation root selection set.
+ +
+ +
Example
+ +```ts +import assert from 'node:assert'; +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { executeRootSelectionSet, validateExecutionArgs } from 'graphql/execution'; + +const schema = buildSchema('type Query { greeting: String }'); +const validatedArgs = validateExecutionArgs({ + schema, + document: parse('{ greeting }'), + rootValue: { greeting: 'Hello' }, +}); + +assert('schema' in validatedArgs); + +const result = await executeRootSelectionSet(validatedArgs); +result; // => { data: { greeting: 'Hello' } } +``` + +
+ +#### executeSync() + +Also implements the "Executing requests" section of the GraphQL specification. +However, it guarantees to complete synchronously (or throw an error) assuming +that all field resolvers are also synchronous. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
argsThe arguments used to perform the operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Completed execution output for a synchronous operation.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { executeSync } from 'graphql/execution'; + +const schema = buildSchema('type Query { greeting: String }'); + +const result = executeSync({ + schema, + document: parse('{ greeting }'), + rootValue: { greeting: 'Hello' }, +}); + +result; // => { data: { greeting: 'Hello' } } +``` + +
+ +#### executeSubscriptionEvent() + +Executes a subscription operation once for a single source event. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
validatedExecutionArgsValidated subscription execution arguments.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Execution result for the subscription event.
+ +
+ +
Example
+ +```ts +import assert from 'node:assert'; +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { executeSubscriptionEvent, validateSubscriptionArgs } from 'graphql/execution'; + +const schema = buildSchema(` + type Query { + noop: String + } + + type Subscription { + greeting: String + } +`); +const validatedArgs = validateSubscriptionArgs({ + schema, + document: parse('subscription { greeting }'), + rootValue: { greeting: 'Hello' }, +}); + +assert('schema' in validatedArgs); + +const result = await executeSubscriptionEvent(validatedArgs); +result; // => { data: { greeting: 'Hello' } } +``` + +
+ +#### subscribe() + +Implements the "Subscribe" algorithm described in the GraphQL specification. + +Returns a Promise that resolves to either an AsyncIterator (if successful) +or an ExecutionResult (error). The promise will be rejected if the schema or +other arguments to this function are invalid, or if the resolved event stream +is not an async iterable. + +If the client-provided arguments to this function do not result in a +compliant subscription, a GraphQL Response (ExecutionResult) with descriptive +errors and no data will be returned. + +If the source stream could not be created due to faulty subscription resolver +logic or underlying systems, the promise will resolve to a single +ExecutionResult containing `errors` and no `data`. + +If the operation succeeded, the promise resolves to an AsyncIterator, which +yields a stream of ExecutionResults representing the response stream. + +This function does not support incremental delivery (`@defer` and `@stream`). +If an operation which would defer or stream data is executed with this +function, a field error will be raised at the location of the `@defer` or +`@stream` directive. + +Accepts an object with named arguments. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
argsExecution arguments for the subscription operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A response stream for a valid subscription, or an execution result containing errors.
+ +
+ +
Example 1
+ +```ts +// Use a same-named rootValue function to provide the source event stream. +import assert from 'node:assert'; +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { subscribe } from 'graphql/execution'; + +async function* greetings() { + yield { greeting: 'Hello' }; + yield { greeting: 'Bonjour' }; +} + +const schema = buildSchema(` + type Query { + noop: String + } + + type Subscription { + greeting: String + } +`); + +const result = await subscribe({ + schema, + document: parse('subscription { greeting }'), + rootValue: { greeting: () => greetings() }, +}); + +assert('next' in result); + +const firstPayload = await result.next(); +firstPayload.value; // => { data: { greeting: 'Hello' } } +``` + +
+ +
Example 2
+ +```ts +// This variant supplies events through a custom subscribeFieldResolver. +import assert from 'node:assert'; +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { subscribe } from 'graphql/execution'; + +async function* defaultGreetings() { + yield { greeting: 'Hello' }; +} + +async function* frenchGreetings() { + yield { greeting: 'Bonjour' }; +} + +const schema = buildSchema(` + type Query { + noop: String + } + + type Subscription { + greeting(locale: String): String + } +`); + +const result = await subscribe({ + schema, + document: parse( + 'subscription Greeting($locale: String) { greeting(locale: $locale) }', + ), + rootValue: { + greeting: (args, contextValue) => { + const locale = args.locale ?? contextValue.defaultLocale; + return locale === 'fr' ? frenchGreetings() : defaultGreetings(); + }, + }, + contextValue: { defaultLocale: 'fr' }, + variableValues: { locale: 'fr' }, + operationName: 'Greeting', + subscribeFieldResolver: (rootValue, args, contextValue, info) => { + args.locale; // => 'fr' + return rootValue[info.fieldName](args, contextValue); + }, +}); + +assert('next' in result); + +const firstPayload = await result.next(); +firstPayload.value; // => { data: { greeting: 'Bonjour' } } +``` + +
+ +#### createSourceEventStream() + +Implements the "CreateSourceEventStream" algorithm described in the +GraphQL specification, resolving the subscription source event stream for a +previously validated subscription request. + +Returns a Promise that resolves to either an AsyncIterable (if successful) +or an ExecutionResult (error). The promise will be rejected if the validated +execution arguments are invalid, or if the resolved event stream is not an +async iterable. + +If the client-provided arguments to this function do not result in a +compliant subscription, a GraphQL Response (ExecutionResult) with +descriptive errors and no data will be returned. + +If the source stream could not be created due to faulty subscription +resolver logic or underlying systems, the promise will resolve to a single +ExecutionResult containing `errors` and no `data`. + +If the operation succeeded, the promise resolves to the AsyncIterable for the +event stream returned by the resolver. + +A Source Event Stream represents a sequence of events, each of which triggers +a GraphQL execution for that event. + +This may be useful when hosting the stateful subscription service in a +different process or machine than the stateless GraphQL execution engine, +or otherwise separating these two steps. For more on this, see the +"Supporting Subscriptions at Scale" information in the GraphQL specification. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
validatedExecutionArgsValidated subscription execution arguments.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A source event stream, or an execution result containing errors.
+ +
+ +
Example
+ +```ts +import assert from 'node:assert'; +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { createSourceEventStream, validateSubscriptionArgs } from 'graphql/execution'; + +async function* greetings() { + yield { greeting: 'Hello' }; +} + +const schema = buildSchema(` + type Query { + noop: String + } + + type Subscription { + greeting: String + } +`); +const validatedArgs = validateSubscriptionArgs({ + schema, + document: parse('subscription { greeting }'), + rootValue: { greeting: () => greetings() }, +}); + +assert('schema' in validatedArgs); + +const stream = await createSourceEventStream(validatedArgs); +Symbol.asyncIterator in stream; // => true +``` + +
+ +#### validateExecutionArgs() + +Constructs a ExecutionContext object from the arguments passed to +execute, which we will pass throughout the other execution methods. + +Throws a GraphQLError if a valid execution context cannot be created. + +TODO: consider no longer exporting this function + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
argsExecution arguments to validate.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Validated execution arguments, or validation errors.
+ +
+ +
Example
+ +```ts +import assert from 'node:assert'; +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { validateExecutionArgs } from 'graphql/execution'; + +const schema = buildSchema(` + interface Named { + name: String! + } + + type User implements Named { + name: String! + } + + type Query { + viewer: Named + } +`); +const abortController = new AbortController(); +const validatedArgs = validateExecutionArgs({ + schema, + document: parse('query Viewer { viewer { __typename name } }'), + rootValue: { viewer: { kind: 'user', name: 'Ada' } }, + contextValue: { locale: 'en' }, + operationName: 'Viewer', + fieldResolver: (source, _args, contextValue, info) => { + contextValue.locale; // => 'en' + return source[info.fieldName]; + }, + typeResolver: (value) => { + return value.kind === 'user' ? 'User' : undefined; + }, + hideSuggestions: true, + abortSignal: abortController.signal, + enableEarlyExecution: true, + hooks: { + asyncWorkFinished: () => {}, + }, + options: { maxCoercionErrors: 1 }, +}); + +assert('operation' in validatedArgs); + +validatedArgs.operation.name?.value; // => 'Viewer' +validatedArgs.hideSuggestions; // => true +``` + +
+ +#### validateSubscriptionArgs() + +Validates execution arguments for a subscription operation. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
argsExecution arguments to validate.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Validated subscription execution arguments, or validation errors.
+ +
+ +
Example
+ +```ts +import assert from 'node:assert'; +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { validateSubscriptionArgs } from 'graphql/execution'; + +const schema = buildSchema(` + type Query { + noop: String + } + + type Subscription { + greeting: String + } +`); +const validatedArgs = validateSubscriptionArgs({ + schema, + document: parse('subscription { greeting }'), +}); + +assert('operation' in validatedArgs); + +validatedArgs.operation.operation; // => 'subscription' +``` + +
+ +#### mapSourceToResponseEvent() + +Implements the "MapSourceToResponseEvent" algorithm described in the +GraphQL specification, mapping each event from a subscription source event +stream to an ExecutionResult in the response stream. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
validatedExecutionArgsValidated subscription execution arguments.
sourceEventStreamSource event stream returned by the subscription resolver.
rootSelectionSetExecutorFunction used to execute each source event.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A response stream of execution results.
+ +
+ +
Example
+ +```ts +import assert from 'node:assert'; +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { mapSourceToResponseEvent, validateSubscriptionArgs } from 'graphql/execution'; + +async function* events() { + yield { greeting: 'Hello' }; +} + +const schema = buildSchema(` + type Query { + noop: String + } + + type Subscription { + greeting: String + } +`); +const validatedArgs = validateSubscriptionArgs({ + schema, + document: parse('subscription { greeting }'), +}); + +assert('schema' in validatedArgs); + +const responseStream = mapSourceToResponseEvent(validatedArgs, events()); +const firstPayload = await responseStream.next(); + +firstPayload.value; // => { data: { greeting: 'Hello' } } +``` + +### Constants + +#### defaultTypeResolver + +If a resolveType function is not given, then a default resolve behavior is +used which attempts two strategies: + +First, See if the provided value has a `__typename` field defined, if so, use +that value as name of the resolved type. + +Otherwise, test each possible type for the abstract type by calling +isTypeOf for the object being coerced, returning the first type that matches. + +
+ +
Type
+ + + +
+ +#### defaultFieldResolver + +If a resolve function is not given, then a default resolve behavior is used +which takes the property of the source object of the same name as the field +and returns it as the result, or if it's a function, returns the result +of calling that function while passing along args and context value. + +
+ +
Type
+ + + +### Types + +#### ValidatedExecutionArgs + +**Interface.** Data that must be available at all points during query execution. + +Namely, schema of the type system that is currently executing, +and the fragments defined in the query document + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaSchema used for execution.
fragmentDefinitionsFragment definitions keyed by fragment name.
fragmentsFragment details keyed by fragment name.
rootValueRoot value passed to the operation.
contextValueApplication context value passed to every resolver.
operationOperation definition selected for execution.
variableValuesOperation variable values with source metadata and coerced runtime values.
fieldResolverResolver used for fields without an explicit resolver.
typeResolverResolver used for abstract types without an explicit type resolver.
subscribeFieldResolverResolver used for subscription fields without an explicit subscribe resolver.
hideSuggestionsWhether suggestion text should be omitted from execution errors.
errorPropagationWhether execution should use error propagation.
externalAbortSignalExternal signal that may abort execution.
enableEarlyExecutionWhether incremental execution may begin eligible work early.
hooksExecution hooks supplied by the caller.
+ +
+ +#### ValidatedSubscriptionArgs + +**Interface.** Validated execution arguments for a subscription operation. + + + +
+ +
Members
+ + + + + + + + + + + + + + + + +
NameTypeDescription
operationSubscription operation definition selected for execution.
+ +
+ +#### ExecutionResult + +**Interface.** Represents the response produced by executing a GraphQL operation. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TDataShape of the execution data payload.
TExtensionsShape of the extensions payload.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
errors?Errors raised while parsing, validating, or executing the operation.
data?Data returned by execution, or null when execution could not produce data.
extensions?Additional non-standard metadata included in the execution result.
+ +
+ +#### FormattedExecutionResult + +**Interface.** A JSON-serializable GraphQL execution result. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TDataShape of the formatted data payload.
TExtensionsShape of the formatted extensions payload.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
errors?Errors raised while parsing, validating, or executing the operation.
data?Data returned by execution, or null when execution could not produce data.
extensions?Additional non-standard metadata included in the formatted result.
+ +
+ +#### RootSelectionSetExecutor + +**Type alias.** Function used to execute a validated root selection set for a subscription event. + + + +
+ +#### ExecutionArgs + +**Interface.** Arguments accepted by execute and executeSync. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaThe schema used for validation or execution.
documentThe parsed GraphQL document to execute.
rootValue?Initial root value passed to the operation.
contextValue?Application context value passed to every resolver.
variableValues?Runtime variable values keyed by variable name.
operationName?Name of the operation to execute when the document contains multiple operations.
fieldResolver?Resolver used when a field does not define its own resolver.
typeResolver?Resolver used when an abstract type does not define its own resolver.
subscribeFieldResolver?Resolver used for the root subscription field.
hideSuggestions?Whether suggestion text should be omitted from request errors.
abortSignal?AbortSignal used to cancel execution.
enableEarlyExecution?Whether incremental execution may begin eligible work early.
hooks?Execution hooks invoked during this operation.
options?Additional execution options.
+ +
+ +#### AsyncWorkFinishedInfo + +**Interface.** Information passed to hooks after asynchronous execution work has finished. + +
+ +
Members
+ + + + + + + + + + + + + + + + +
NameTypeDescription
validatedExecutionArgsValidated execution arguments for the operation that finished async work.
+ +
+ +#### ExecutionHooks + +**Interface.** Optional hooks invoked during GraphQL execution. + +
+ +
Members
+ + + + + + + + + + + + + + + + +
NameTypeDescription
asyncWorkFinished?Called after all tracked asynchronous execution work has settled.
+ +## Category: Incremental Execution + + + +### Functions + +#### experimentalExecuteIncrementally() + +Implements the "Executing requests" section of the GraphQL specification, +including `@defer` and `@stream` as proposed in +https://github.com/graphql/graphql-spec/pull/742 + +This function returns either a single ExecutionResult, or an +ExperimentalIncrementalExecutionResults object containing an `initialResult` +and a stream of `subsequentResults`. + +If the arguments to this function do not result in a legal execution context, +a GraphQLError will be thrown immediately explaining the invalid input. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
argsExecution arguments for the GraphQL operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A single execution result or incremental execution results.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { experimentalExecuteIncrementally } from 'graphql/execution'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); + +const result = await experimentalExecuteIncrementally({ + schema, + document: parse('{ greeting }'), + rootValue: { greeting: 'Hello' }, +}); + +result; // => { data: { greeting: 'Hello' } } +``` + +
+ +#### experimentalExecuteRootSelectionSet() + +Executes the operation root selection set with incremental delivery enabled. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
validatedExecutionArgsValidated execution arguments.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A single execution result or incremental execution results.
+ +
+ +
Example
+ +```ts +import assert from 'node:assert'; +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { + experimentalExecuteRootSelectionSet, + validateExecutionArgs, +} from 'graphql/execution'; + +const schema = buildSchema('type Query { greeting: String }'); +const validatedArgs = validateExecutionArgs({ + schema, + document: parse('{ greeting }'), + rootValue: { greeting: 'Hello' }, +}); + +assert('schema' in validatedArgs); + +const result = await experimentalExecuteRootSelectionSet(validatedArgs); +result; // => { data: { greeting: 'Hello' } } +``` + +### Types + +#### ExperimentalIncrementalExecutionResults + +**Interface.** Results for an operation that produced incremental payloads. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TInitialDataShape of the initial result data payload.
TDeferredDataShape of deferred fragment data payloads.
TStreamItemShape of streamed list items.
TExtensionsShape of extensions payloads.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
initialResultInitial execution result delivered before subsequent incremental payloads.
subsequentResultsAsync stream of incremental payloads delivered after the initial result.
+ +
+ +#### FormattedExperimentalIncrementalExecutionResults + +**Interface.** JSON-serializable form of incremental execution results. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TInitialShape of the formatted initial result data payload.
TDeferredDataShape of formatted deferred fragment data payloads.
TStreamItemShape of formatted streamed list items.
TExtensionsShape of formatted extensions payloads.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
initialResultFormatted initial execution result.
subsequentResultsAsync stream of formatted incremental payloads.
+ +
+ +#### InitialIncrementalExecutionResult + +**Interface.** Initial execution result for an operation that produced incremental payloads. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TDataShape of the initial data payload.
TExtensionsShape of the extensions payload.
+ + + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
dataData produced by the initial execution payload.
pendingIncremental payloads that are still pending after the initial result.
hasNextIndicates that subsequent incremental payloads will follow.
extensions?Additional non-standard metadata included in the initial result.
+ +
+ +#### FormattedInitialIncrementalExecutionResult + +**Interface.** JSON-serializable form of an initial incremental execution result. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TInitialDataShape of the formatted initial data payload.
TExtensionsShape of the formatted extensions payload.
+ + + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
dataFormatted data produced by the initial execution payload.
pendingFormatted list of incremental payloads still pending after the initial result.
hasNextIndicates whether subsequent incremental payloads will follow.
extensions?Additional non-standard metadata included in the formatted initial result.
+ +
+ +#### SubsequentIncrementalExecutionResult + +**Interface.** Subsequent payload produced by incremental execution. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TDeferredDataShape of deferred fragment data payloads.
TStreamItemShape of streamed list items.
TExtensionsShape of the extensions payload.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
pending?Incremental payloads that became pending with this response.
incremental?Deferred or streamed payloads delivered by this response.
completed?Incremental payloads that completed with this response.
hasNextIndicates whether more incremental payloads will follow.
extensions?Additional non-standard metadata included in this payload.
+ +
+ +#### FormattedSubsequentIncrementalExecutionResult + +**Interface.** JSON-serializable form of a subsequent incremental execution payload. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TDeferredDataShape of formatted deferred fragment data payloads.
TStreamItemShape of formatted streamed list items.
TExtensionsShape of formatted extensions payloads.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
hasNextIndicates whether more incremental payloads will follow.
pending?Formatted incremental payloads that became pending with this response.
incremental?Formatted deferred or streamed payloads delivered by this response.
completed?Formatted incremental payloads that completed with this response.
extensions?Additional non-standard metadata included in this formatted payload.
+ +
+ +#### IncrementalDeferResult + +**Interface.** Incremental payload produced by a deferred fragment. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TDeferredDataShape of deferred fragment data.
TExtensionsShape of extensions payloads.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
idIdentifier matching this payload to a pending deferred fragment.
subPath?Path from the deferred fragment location to this payload.
errors?Errors raised while executing the deferred fragment.
dataData produced by the deferred fragment.
extensions?Additional non-standard metadata included in this payload.
+ +
+ +#### FormattedIncrementalDeferResult + +**Interface.** JSON-serializable form of a deferred fragment payload. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TDeferredDataShape of formatted deferred fragment data.
TExtensionsShape of formatted extensions payloads.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
errors?Formatted errors raised while executing the deferred fragment.
dataFormatted data produced by the deferred fragment.
idIdentifier matching this payload to a pending deferred fragment.
subPath?Path from the deferred fragment location to this payload.
extensions?Additional non-standard metadata included in this formatted payload.
+ +
+ +#### IncrementalStreamResult + +**Interface.** Incremental payload produced by a streamed list field. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TStreamItemShape of streamed list items.
TExtensionsShape of extensions payloads.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
idIdentifier matching this payload to a pending stream.
subPath?Path from the streamed field location to these items.
errors?Errors raised while producing streamed items.
itemsStreamed list items delivered by this payload.
extensions?Additional non-standard metadata included in this payload.
+ +
+ +#### FormattedIncrementalStreamResult + +**Interface.** JSON-serializable form of a streamed list payload. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TStreamItemShape of formatted streamed list items.
TExtensionsShape of formatted extensions payloads.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
errors?Formatted errors raised while producing streamed items.
itemsFormatted streamed list items delivered by this payload.
idIdentifier matching this payload to a pending stream.
subPath?Path from the streamed field location to these items.
extensions?Additional non-standard metadata included in this formatted payload.
+ +
+ +#### IncrementalResult + +**Type alias.** Deferred fragment or streamed list payload produced by incremental execution. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TDeferredDataShape of deferred fragment data.
TStreamItemShape of streamed list items.
TExtensionsShape of extensions payloads.
+ + + +
+ +#### FormattedIncrementalResult + +**Type alias.** JSON-serializable deferred fragment or streamed list payload. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TDeferredDataShape of formatted deferred fragment data.
TStreamItemShape of formatted streamed list items.
TExtensionsShape of formatted extensions payloads.
+ + + +## Category: Legacy Incremental Execution + + + +### Functions + +#### legacyExecuteIncrementally() + +Executes a GraphQL operation with support for `@defer` and `@stream` using +the legacy incremental delivery payload format. + +Prefer [`experimentalExecuteIncrementally`](/api-v17/execution#experimentalexecuteincrementally) for the current incremental +delivery format. In the legacy format, each subsequent incremental payload +identifies its location with `path` and optional `label` fields. The current +format instead tracks pending work by `id` and reports completion through +`completed` entries. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
argsExecution arguments for the GraphQL operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A single execution result or legacy incremental execution results.
+ +
+ +
Example 1
+ +```ts +import assert from 'node:assert'; +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { legacyExecuteIncrementally } from 'graphql/execution'; + +const schema = buildSchema(` + type Query { + hero: Hero + } + + type Hero { + id: ID! + name: String! + } +`); + +const result = await legacyExecuteIncrementally({ + schema, + document: parse('{ hero { id ... @defer(label: "HeroName") { name } } }'), + rootValue: { hero: { id: '1', name: 'Luke' } }, +}); + +assert('initialResult' in result); + +result.initialResult; // => { data: { hero: { id: '1' } }, hasNext: true } + +const deferred = await result.subsequentResults.next(); +deferred.value; // => { incremental: [ { data: { name: 'Luke' }, path: ['hero'], label: 'HeroName' } ], hasNext: false } +``` + +
+ +
Example 2
+ +Compare the legacy payload format with the current incremental delivery +format returned by `experimentalExecuteIncrementally`. +```ts +import assert from 'node:assert'; +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { + experimentalExecuteIncrementally, + legacyExecuteIncrementally, +} from 'graphql/execution'; + +const schema = buildSchema(` + type Query { + hero: Hero + } + + type Hero { + id: ID! + name: String! + } +`); +const document = parse('{ hero { id ... @defer { name } } }'); +const rootValue = { hero: { id: '1', name: 'Luke' } }; + +const experimental = await experimentalExecuteIncrementally({ + schema, + document, + rootValue, +}); +const legacy = await legacyExecuteIncrementally({ + schema, + document, + rootValue, +}); + +assert('initialResult' in experimental); +assert('initialResult' in legacy); + +experimental.initialResult; // => { data: { hero: { id: '1' } }, pending: [ { id: '0', path: ['hero'] } ], hasNext: true } +legacy.initialResult; // => { data: { hero: { id: '1' } }, hasNext: true } + +const experimentalDeferred = await experimental.subsequentResults.next(); +experimentalDeferred.value; // => { incremental: [{ data: { name: 'Luke' }, id: '0' }], completed: [{ id: '0' }], hasNext: false } + +const legacyDeferred = await legacy.subsequentResults.next(); +legacyDeferred.value; // => { incremental: [ { data: { name: 'Luke' }, path: ['hero'] } ], hasNext: false } +``` + +
+ +
Example 3
+ +Compare streamed list payloads in the legacy and current incremental +delivery formats. +```ts +import assert from 'node:assert'; +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { + experimentalExecuteIncrementally, + legacyExecuteIncrementally, +} from 'graphql/execution'; + +const schema = buildSchema('type Query { colors: [String] }'); +const document = parse('{ colors @stream(initialCount: 1) }'); +const rootValue = { colors: ['red', 'green', 'blue'] }; + +const experimental = await experimentalExecuteIncrementally({ + schema, + document, + rootValue, +}); +const legacy = await legacyExecuteIncrementally({ + schema, + document, + rootValue, +}); + +assert('initialResult' in experimental); +assert('initialResult' in legacy); + +experimental.initialResult; // => { data: { colors: ['red'] }, pending: [ { id: '0', path: ['colors'] } ], hasNext: true } +legacy.initialResult; // => { data: { colors: ['red'] }, hasNext: true } + +const experimentalStream = await experimental.subsequentResults.next(); +experimentalStream.value; // => { incremental: [ { items: ['green', 'blue'], id: '0' } ], completed: [{ id: '0' }], hasNext: false } + +const legacyStream = await legacy.subsequentResults.next(); +legacyStream.value; // => { incremental: [ { items: ['green', 'blue'], path: ['colors', 1] } ], hasNext: false } +``` + +
+ +#### legacyExecuteRootSelectionSet() + +Executes a validated operation root selection set with support for `@defer` +and `@stream` using the legacy incremental delivery payload format. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
validatedExecutionArgsValidated execution arguments.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A single execution result or legacy incremental execution results.
+ +
+ +
Example
+ +```ts +import assert from 'node:assert'; +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { + legacyExecuteRootSelectionSet, + validateExecutionArgs, +} from 'graphql/execution'; + +const schema = buildSchema('type Query { greeting: String }'); +const validatedArgs = validateExecutionArgs({ + schema, + document: parse('{ greeting }'), + rootValue: { greeting: 'Hello' }, +}); + +assert('schema' in validatedArgs); + +const result = await legacyExecuteRootSelectionSet(validatedArgs); +result; // => { data: { greeting: 'Hello' } } +``` + +### Types + +#### LegacyExperimentalIncrementalExecutionResults + +**Interface.** Results for an operation that produced legacy incremental payloads. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TInitialDataShape of the initial result data payload.
TDeferredDataShape of deferred fragment data payloads.
TStreamItemShape of streamed list items.
TExtensionsShape of extensions payloads.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
initialResultInitial execution result delivered before subsequent legacy incremental payloads.
subsequentResultsAsync stream of legacy incremental payloads delivered after the initial result.
+ +
+ +#### LegacyInitialIncrementalExecutionResult + +**Interface.** Initial execution result for an operation that produced legacy incremental payloads. + +Unlike [`InitialIncrementalExecutionResult`](/api-v17/execution#initialincrementalexecutionresult), the legacy initial result does +not include a `pending` list. Subsequent payloads identify their location +directly with `path` and optional `label` fields. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TInitialDataShape of the initial data payload.
TExtensionsShape of the extensions payload.
+ + + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
dataData produced by the initial execution payload.
hasNextIndicates that subsequent legacy incremental payloads will follow.
extensions?Additional non-standard metadata included in the initial result.
+ +
+ +#### LegacySubsequentIncrementalExecutionResult + +**Interface.** Subsequent payload produced by legacy incremental execution. + +Legacy subsequent payloads may contain deferred fragment data, streamed list +items, or only `hasNext: false` to complete the response stream. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TDeferredDataShape of deferred fragment data payloads.
TStreamItemShape of streamed list items.
TExtensionsShape of the extensions payload.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
incremental?Deferred or streamed payloads delivered by this response.
hasNextIndicates whether more legacy incremental payloads will follow.
extensions?Additional non-standard metadata included in this payload.
+ +
+ +#### LegacyIncrementalResult + +**Type alias.** Deferred fragment or streamed list payload produced by legacy incremental execution. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TDeferredDataShape of deferred fragment data.
TStreamItemShape of streamed list items.
TExtensionsShape of extensions payloads.
+ + + +
+ +#### LegacyIncrementalDeferResult + +**Interface.** Legacy incremental payload produced by a deferred fragment. + +The payload location is identified directly by `path` and optional `label` +instead of by an `id` from a pending entry. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TDeferredDataShape of deferred fragment data.
TExtensionsShape of extensions payloads.
+ + + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
pathResponse path to the deferred fragment payload.
label?Label from the {"@defer"} directive.
+ +
+ +#### LegacyIncrementalStreamResult + +**Interface.** Legacy incremental payload produced by a streamed list field. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TStreamItemShape of streamed list items.
TExtensionsShape of extensions payloads.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
errors?Errors raised while producing streamed items.
itemsStreamed list items delivered by this payload.
pathResponse path to the first streamed list item in this payload.
label?Label from the {"@stream"} directive.
extensions?Additional non-standard metadata included in this payload.
+ +
+ +#### FormattedLegacyExperimentalIncrementalExecutionResults + +**Interface.** JSON-serializable form of legacy incremental execution results. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TInitialDataShape of the formatted initial result data payload.
TDeferredDataShape of formatted deferred fragment data payloads.
TStreamItemShape of formatted streamed list items.
TExtensionsShape of formatted extensions payloads.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
initialResultFormatted initial execution result.
subsequentResultsAsync stream of formatted legacy incremental payloads.
+ +
+ +#### FormattedLegacyInitialIncrementalExecutionResult + +**Interface.** JSON-serializable form of a legacy initial incremental execution result. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TInitialDataShape of the formatted initial data payload.
TExtensionsShape of the formatted extensions payload.
+ + + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
dataFormatted data produced by the initial execution payload.
hasNextIndicates that subsequent legacy incremental payloads will follow.
extensions?Additional non-standard metadata included in the formatted initial result.
+ +
+ +#### FormattedLegacySubsequentIncrementalExecutionResult + +**Interface.** JSON-serializable form of a legacy subsequent incremental execution payload. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TDeferredDataShape of formatted deferred fragment data payloads.
TStreamItemShape of formatted streamed list items.
TExtensionsShape of formatted extensions payloads.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
incremental?Formatted deferred or streamed payloads delivered by this response.
hasNextIndicates whether more legacy incremental payloads will follow.
extensions?Additional non-standard metadata included in this formatted payload.
+ +
+ +#### FormattedLegacyIncrementalResult + +**Type alias.** JSON-serializable deferred fragment or streamed list payload produced by +legacy incremental execution. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TDeferredDataShape of formatted deferred fragment data.
TStreamItemShape of formatted streamed list items.
TExtensionsShape of formatted extensions payloads.
+ + + +
+ +#### FormattedLegacyIncrementalDeferResult + +**Interface.** JSON-serializable form of a legacy deferred fragment payload. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TDeferredDataShape of formatted deferred fragment data.
TExtensionsShape of formatted extensions payloads.
+ + + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
pathResponse path to the formatted deferred fragment payload.
label?Label from the {"@defer"} directive.
+ +
+ +#### FormattedLegacyIncrementalStreamResult + +**Interface.** JSON-serializable form of a legacy streamed list payload. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TStreamItemShape of formatted streamed list items.
TExtensionsShape of formatted extensions payloads.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
errors?Formatted errors raised while producing streamed items.
itemsFormatted streamed list items delivered by this payload.
pathResponse path to the first streamed list item in this formatted payload.
label?Label from the {"@stream"} directive.
extensions?Additional non-standard metadata included in this formatted payload.
+ +## Category: Values + +
+

+ Functions:
+ getVariableValues() + + getArgumentValues() + + getDirectiveValues() +

+

+ Types:
+ VariableValues +

+
+ +### Functions + +#### getVariableValues() + +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. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
varDefNodesThe variable definition AST nodes to coerce.
inputsThe runtime variable values keyed by variable name.
options?Optional configuration for this operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Coerced variable values with source metadata, or request errors.
+ +
+ +
Example 1
+ +```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 2
+ +```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/ +``` + +
+ +#### getArgumentValues() + +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. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
defField or directive definition that declares the arguments.
nodeField or directive AST node supplying argument literals.
variableValues?Operation variable values returned by getVariableValues.
fragmentVariableValues?Fragment variable values for the current fragment scope.
hideSuggestions?Whether suggestion text should be omitted from errors.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A map of coerced argument values.
+ +
+ +
Example 1
+ +```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 2
+ +```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 +``` + +
+ +#### getDirectiveValues() + +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. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
directiveDefDirective definition to read argument definitions from.
nodeAST node that may contain directives.
variableValues?Operation variable values returned by getVariableValues.
fragmentVariableValues?Fragment variable values for the current fragment scope.
hideSuggestions?Whether suggestion text should be omitted from errors.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A map of coerced directive argument values, or undefined when absent.
+ +
+ +
Example 1
+ +```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 2
+ +```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 +``` + +### Types + +#### VariableValues + +**Interface.** 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. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourcesSource metadata for each variable value keyed by variable name.
coercedCoerced runtime variable values keyed by variable name.
+ +## Category: Paths + +
+

+ Functions:
+ responsePathAsArray() +

+
+ +### Functions + +#### responsePathAsArray() + +Given a Path, return an Array of the path keys. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
pathThe linked response path to flatten.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
An array of response path keys from root to leaf.
+ +
+ +
Example
+ +```ts +import { pathToArray } from 'graphql/jsutils/Path'; + +const path = { + prev: { + prev: { + prev: undefined, + key: 'viewer', + typename: 'Query', + }, + key: 'friends', + typename: 'User', + }, + key: 0, + typename: undefined, +}; + +pathToArray(path); // => ['viewer', 'friends', 0] +pathToArray(undefined); // => [] +``` diff --git a/website/pages/api-v17/execution/_meta.ts b/website/pages/api-v17/execution/_meta.ts new file mode 100644 index 0000000000..0eff171fdf --- /dev/null +++ b/website/pages/api-v17/execution/_meta.ts @@ -0,0 +1,24 @@ +const meta = { + execution: { + title: 'Category: Execution', + href: '/api-v17/execution#category-execution', + }, + 'incremental-execution': { + title: 'Category: Incremental Execution', + href: '/api-v17/execution#category-incremental-execution', + }, + 'legacy-incremental-execution': { + title: 'Category: Legacy Incremental Execution', + href: '/api-v17/execution#category-legacy-incremental-execution', + }, + values: { + title: 'Category: Values', + href: '/api-v17/execution#category-values', + }, + paths: { + title: 'Category: Paths', + href: '/api-v17/execution#category-paths', + }, +}; + +export default meta; diff --git a/website/pages/api-v17/graphql.mdx b/website/pages/api-v17/graphql.mdx new file mode 100644 index 0000000000..792467022d --- /dev/null +++ b/website/pages/api-v17/graphql.mdx @@ -0,0 +1,596 @@ +import { ApiSignature, ApiType } from '../../components/ApiCode'; + +The root `graphql` package re-exports the public GraphQL.js API from its +submodules and provides the high-level request pipeline helpers defined in +this module. + +You can import public exports from GraphQL.js modules through the root +`graphql` package or through their module-specific entry point. For example, +these two references resolve to the same [`parse`](/api-v17/language#parse) function: + +```ts +import { parse } from 'graphql'; +import { parse } from 'graphql/language'; +``` + +Use the root package when you want a single import surface, or use submodules +such as `graphql/language`, `graphql/type`, `graphql/execution`, and +`graphql/utilities` when you want module-focused imports. This module also +defines root-only APIs, such as request pipeline helpers and version +metadata, that do not belong to a narrower submodule. + +For documentation purposes, these exports are grouped into the following categories: + +- [Development Mode](/api-v17/graphql#category-development-mode) +- [Request Pipeline](/api-v17/graphql#category-request-pipeline) +- [Harness](/api-v17/graphql#category-harness) +- [Version](/api-v17/graphql#category-version) + +## Category: Development Mode + +
+

+ Functions:
+ enableDevMode() + + isDevModeEnabled() +

+
+ +### Functions + +#### enableDevMode() + +Enables GraphQL.js development mode checks for this module instance. + +Production entry points leave development mode disabled by default. Call this +before constructing schemas or executing requests when additional development +diagnostics should run. + +**Signature:** + + + +
+ +
Example
+ +```ts +import { enableDevMode, isDevModeEnabled } from 'graphql/devMode'; + +isDevModeEnabled(); // => false +enableDevMode(); +isDevModeEnabled(); // => true +``` + +
+ +#### isDevModeEnabled() + +Returns whether GraphQL.js development mode has been enabled for this module +instance. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when development mode is enabled.
+ +
+ +
Example
+ +```ts +import { enableDevMode, isDevModeEnabled } from 'graphql/devMode'; + +enableDevMode(); + +isDevModeEnabled(); // => true +``` + +## Category: Request Pipeline + +
+

+ Functions:
+ graphql() + + graphqlSync() +

+

+ Types:
+ GraphQLArgs +

+
+ +### Functions + +#### graphql() + +Parses, validates, and executes a GraphQL document against a schema. + +This is the primary entry point for fulfilling GraphQL operations. Use this +when you want a single-call request lifecycle that returns a promise in all +cases. + +More sophisticated GraphQL servers, such as those which persist queries, may +wish to separate the validation and execution phases to a static-time tooling +step and a server runtime step. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
argsRequest execution arguments, including schema and source.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A promise that resolves to an execution result or validation errors.
+ +
+ +
Example 1
+ +```ts +// Execute a complete asynchronous request with variables. +import { graphql, buildSchema } from 'graphql'; + +const schema = buildSchema(` + type Query { + greeting(name: String!): String + } +`); + +const result = await graphql({ + schema, + source: 'query SayHello($name: String!) { greeting(name: $name) }', + rootValue: { + greeting: ({ name }) => `Hello, ${name}!`, + }, + variableValues: { name: 'Ada' }, + operationName: 'SayHello', +}); + +result; // => { data: { greeting: 'Hello, Ada!' } } +``` + +
+ +
Example 2
+ +```ts +// This variant supplies context plus custom field and type resolvers. +import { graphql, buildSchema } from 'graphql'; + +const schema = buildSchema(` + interface Named { + name: String! + } + + type User implements Named { + name: String! + } + + type Query { + viewer: Named + } +`); + +const result = await graphql({ + schema, + source: '{ viewer { __typename name } }', + rootValue: { viewer: { kind: 'user', name: 'Ada' } }, + contextValue: { locale: 'en' }, + fieldResolver: (source, _args, context, info) => { + context.locale; // => 'en' + return source[info.fieldName]; + }, + typeResolver: (value) => { + return value.kind === 'user' ? 'User' : undefined; + }, +}); + +result; // => { data: { viewer: { __typename: 'User', name: 'Ada' } } } +``` + +
+ +
Example 3
+ +```ts +// This variant customizes the request pipeline with a harness. +import { buildSchema, defaultHarness, graphql } from 'graphql'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const stages = []; +const abortController = new AbortController(); +const harness = { + parse: (...args) => { + stages.push('parse'); + return defaultHarness.parse(...args); + }, + validate: (...args) => { + stages.push('validate'); + return defaultHarness.validate(...args); + }, + execute: (...args) => { + stages.push('execute'); + return defaultHarness.execute(...args); + }, + subscribe: (...args) => { + stages.push('subscribe'); + return defaultHarness.subscribe(...args); + }, +}; + +const result = await graphql({ + schema, + source: '{ greeting }', + rootValue: { greeting: 'Hello' }, + rules: [], + maxErrors: 25, + hideSuggestions: true, + noLocation: true, + abortSignal: abortController.signal, + harness, +}); + +result; // => { data: { greeting: 'Hello' } } +stages; // => ['parse', 'validate', 'execute'] +``` + +
+ +#### graphqlSync() + +Parses, validates, and executes a GraphQL document synchronously. + +This function guarantees that execution completes synchronously, or throws an +error, assuming that all field resolvers are also synchronous. It throws when +any resolver returns a promise. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
argsRequest execution arguments, including schema and source.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Completed execution output, or request errors if parsing or
+validation fails.
+ +
+ +
Example 1
+ +```ts +// Execute a complete synchronous request with variables. +import { graphqlSync, buildSchema } from 'graphql'; + +const schema = buildSchema(` + type Query { + greeting(name: String!): String + } +`); + +const result = graphqlSync({ + schema, + source: 'query SayHello($name: String!) { greeting(name: $name) }', + rootValue: { + greeting: ({ name }) => `Hello, ${name}!`, + }, + variableValues: { name: 'Ada' }, + operationName: 'SayHello', +}); + +result; // => { data: { greeting: 'Hello, Ada!' } } +``` + +
+ +
Example 2
+ +```ts +// This variant uses a synchronous custom field resolver and context. +import { graphqlSync, buildSchema } from 'graphql'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); + +const result = graphqlSync({ + schema, + source: '{ greeting }', + fieldResolver: (_source, _args, contextValue) => { + return contextValue.defaultGreeting; + }, + contextValue: { defaultGreeting: 'Hello' }, +}); + +result; // => { data: { greeting: 'Hello' } } +``` + +### Types + +#### GraphQLArgs + +**Interface.** Describes the input object accepted by `graphql` and [`graphqlSync`](/api-v17/graphql#graphqlsync). + +These arguments describe the full parse, validate, and execute lifecycle for +a GraphQL request. They include parser options, validation options, execution +options, and an optional harness for replacing pipeline stages. + +`graphql` and [`graphqlSync`](/api-v17/graphql#graphqlsync) do not support incremental delivery (`@defer` and +`@stream`); use [`experimentalExecuteIncrementally`](/api-v17/execution#experimentalexecuteincrementally) after parsing and +validating when incremental delivery is required. + + + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
harness?Custom parse, validate, execute, and subscribe functions for this request
+pipeline.
sourceA GraphQL language-formatted string or source object representing the
+requested operation.
rules?Validation rules to use instead of the specified rules.
+ +## Category: Harness + +
+

+ Constants:
+ defaultHarness +

+

+ Types:
+ GraphQLParseFn + + GraphQLValidateFn + + GraphQLExecuteFn + + GraphQLSubscribeFn + + GraphQLHarness +

+
+ +### Constants + +#### defaultHarness + +Default harness backed by GraphQL.js parse, validate, execute, and subscribe +implementations. + +
+ +
Type
+ + + +### Types + +#### GraphQLParseFn + +**Type alias.** Function used by a GraphQL harness to parse GraphQL source text. + + + +
+ +#### GraphQLValidateFn + +**Type alias.** Function used by a GraphQL harness to validate a parsed document. + + + +
+ +#### GraphQLExecuteFn + +**Type alias.** Function used by a GraphQL harness to execute a valid operation. + + + +
+ +#### GraphQLSubscribeFn + +**Type alias.** Function used by a GraphQL harness to create a subscription response stream. + + + +
+ +#### GraphQLHarness + +**Interface.** Overrides for the parse, validate, execute, and subscribe stages used by the +high-level `graphql` and [`graphqlSync`](/api-v17/graphql#graphqlsync) request pipeline. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
parseParses GraphQL source text into a document AST.
validateValidates a document AST against a schema.
executeExecutes a valid operation.
subscribeCreates a response stream for a subscription operation.
+ +## Category: Version + +
+

+ Constants:
+ version + + versionInfo +

+
+ +### Constants + +#### version + +A string containing the version of the GraphQL.js library + +
+ +
Type
+ + + +
+ +#### versionInfo + +An object containing the components of the GraphQL.js version string + +
+ +
Type
+ + diff --git a/website/pages/api-v17/graphql/_meta.ts b/website/pages/api-v17/graphql/_meta.ts new file mode 100644 index 0000000000..01bfd14665 --- /dev/null +++ b/website/pages/api-v17/graphql/_meta.ts @@ -0,0 +1,20 @@ +const meta = { + 'development-mode': { + title: 'Category: Development Mode', + href: '/api-v17/graphql#category-development-mode', + }, + 'request-pipeline': { + title: 'Category: Request Pipeline', + href: '/api-v17/graphql#category-request-pipeline', + }, + harness: { + title: 'Category: Harness', + href: '/api-v17/graphql#category-harness', + }, + version: { + title: 'Category: Version', + href: '/api-v17/graphql#category-version', + }, +}; + +export default meta; diff --git a/website/pages/api-v17/language.mdx b/website/pages/api-v17/language.mdx new file mode 100644 index 0000000000..8095c6c15b --- /dev/null +++ b/website/pages/api-v17/language.mdx @@ -0,0 +1,5742 @@ +import { ApiSignature, ApiType } from '../../components/ApiCode'; + +Parse, print, and visit GraphQL language source files and AST nodes. + +These exports are also available from the root `graphql` package. + +For documentation purposes, these exports are grouped into the following categories: + +- [AST](/api-v17/language#category-ast) +- [Kinds](/api-v17/language#category-kinds) +- [Lexing](/api-v17/language#category-lexing) +- [Source](/api-v17/language#category-source) +- [Parsing](/api-v17/language#category-parsing) +- [AST Predicates](/api-v17/language#category-ast-predicates) +- [Printing](/api-v17/language#category-printing) +- [Visiting](/api-v17/language#category-visiting) + +## Category: AST + +
+

+ Classes:
+ Location + + Token +

+

+ Types:
+ ASTNode + + ASTKindToNode + + NameNode + + DocumentNode + + DefinitionNode + + ExecutableDefinitionNode + + OperationDefinitionNode + + SubscriptionOperationDefinitionNode + + VariableDefinitionNode + + VariableNode + + SelectionSetNode + + SelectionNode + + FieldNode + + ArgumentNode + + ConstArgumentNode + + FragmentArgumentNode + + FragmentSpreadNode + + InlineFragmentNode + + FragmentDefinitionNode + + ValueNode + + ConstValueNode + + IntValueNode + + FloatValueNode + + StringValueNode + + BooleanValueNode + + NullValueNode + + EnumValueNode + + ListValueNode + + ConstListValueNode + + ObjectValueNode + + ConstObjectValueNode + + ObjectFieldNode + + ConstObjectFieldNode + + DirectiveNode + + ConstDirectiveNode + + TypeNode + + NamedTypeNode + + ListTypeNode + + NonNullTypeNode + + TypeSystemDefinitionNode + + SchemaDefinitionNode + + OperationTypeDefinitionNode + + TypeDefinitionNode + + ScalarTypeDefinitionNode + + ObjectTypeDefinitionNode + + FieldDefinitionNode + + InputValueDefinitionNode + + InterfaceTypeDefinitionNode + + UnionTypeDefinitionNode + + EnumTypeDefinitionNode + + EnumValueDefinitionNode + + InputObjectTypeDefinitionNode + + DirectiveDefinitionNode + + TypeSystemExtensionNode + + SchemaExtensionNode + + TypeExtensionNode + + ScalarTypeExtensionNode + + ObjectTypeExtensionNode + + InterfaceTypeExtensionNode + + UnionTypeExtensionNode + + EnumTypeExtensionNode + + InputObjectTypeExtensionNode + + DirectiveExtensionNode + + SchemaCoordinateNode + + TypeCoordinateNode + + MemberCoordinateNode + + ArgumentCoordinateNode + + DirectiveCoordinateNode + + DirectiveArgumentCoordinateNode +

+
+ +### Classes + +#### Location + +Contains a range of UTF-8 character offsets and token references that +identify the region of the source from which the AST derived. + +
+ +##### Constructor + +Creates a Location instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
startTokenThe start token.
endTokenThe end token.
sourceSource document used to derive error locations.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
startThe character offset at which this Node begins.
endThe character offset at which this Node ends.
startTokenThe Token at which this Node begins.
endTokenThe Token at which this Node ends.
sourceThe Source document the AST represents.
+ +
+ +##### toJSON() + +Returns a JSON representation of this location. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; + +const document = parse('{ hello }'); +const location = document.loc?.toJSON(); + +location; // => { start: 0, end: 9 } +``` + +
+ +#### Token + +Represents a range of characters represented by a lexical token +within a Source. + +
+ +##### Constructor + +Creates a Token instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindToken kind produced by lexical analysis.
startCharacter offset where this token begins.
endCharacter offset where this token ends.
lineOne-indexed line number where this token begins.
columnOne-indexed column number where this token begins.
value?Interpreted value for non-punctuation tokens.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe kind of Token.
startThe character offset at which this Node begins.
endThe character offset at which this Node ends.
lineThe 1-indexed line number on which this Token appears.
columnThe 1-indexed column number at which this Token begins.
valueFor non-punctuation tokens, represents the interpreted value of the token.
+Note: is undefined for punctuation tokens, but typed as string for
+convenience in the parser.
prevTokens exist as nodes in a double-linked-list amongst all tokens
+including ignored tokens. <SOF> is always the first node and <EOF>
+the last.
nextNext token in the token stream, including ignored tokens.
+ +
+ +##### toJSON() + +Returns a JSON representation of this token. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { Lexer, Source } from 'graphql/language'; + +const lexer = new Lexer(new Source('{ hello }')); +const token = lexer.advance().toJSON(); + +token; // => { kind: '{', value: undefined, line: 1, column: 1 } +``` + +### Types + +#### ASTNode + +**Type alias.** The list of all possible AST node types. + + + +
+ +#### ASTKindToNode + +**Type alias.** Utility type listing all nodes indexed by their kind. + + + +
+ +#### NameNode + +**Interface.** An identifier in a GraphQL document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
valueParsed value represented by this node.
+ +
+ +#### DocumentNode + +**Interface.** The root AST node for a parsed GraphQL document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
definitionsTop-level executable and type-system definitions in this document.
tokenCount?The number of lexical tokens parsed for this document, if token counting was enabled.
+ +
+ +#### DefinitionNode + +**Type alias.** Any top-level definition that may appear in a GraphQL document. + + + +
+ +#### ExecutableDefinitionNode + +**Type alias.** Any executable definition that may appear in an operation document. + + + +
+ +#### OperationDefinitionNode + +**Interface.** A query, mutation, or subscription operation definition. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
operationThe operation selected for execution.
name?Name node identifying this AST node.
variableDefinitions?Variable definitions declared by this operation or fragment.
directives?Directives available in this schema or applied to this AST node.
selectionSetSelections made by this operation, field, or fragment.
+ +
+ +#### SubscriptionOperationDefinitionNode + +**Interface.** A narrowed OperationDefinitionNode for subscription operations. +Subscription operations go through a distinct execution pipeline +(source event stream + per-event execution), so narrowing the operation +type allows functions in that pipeline to accept only valid input. + + + +
+ +
Members
+ + + + + + + + + + + + + + + + +
NameTypeDescription
operationSubscription operation kind for this definition.
+ +
+ +#### VariableDefinitionNode + +**Interface.** A variable declaration in an operation or experimental fragment definition. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
variableThe variable being defined or referenced.
typeThe GraphQL type reference or runtime type for this element.
defaultValue?Default value used when no explicit value is supplied.
directives?Directives available in this schema or applied to this AST node.
+ +
+ +#### VariableNode + +**Interface.** A variable reference, such as `$id`. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
+ +
+ +#### SelectionSetNode + +**Interface.** A set of fields and fragments selected from an object, interface, or union. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
selectionsFields and fragments contained in this selection set.
+ +
+ +#### SelectionNode + +**Type alias.** Any selection that may appear inside a selection set. + + + +
+ +#### FieldNode + +**Interface.** A field selected in an executable GraphQL document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
alias?The response-key alias for this field, if one was supplied.
nameName node identifying this AST node.
arguments?Arguments supplied to this field, directive, or coordinate.
directives?Directives available in this schema or applied to this AST node.
selectionSet?Selections made by this operation, field, or fragment.
+ +
+ +#### ArgumentNode + +**Interface.** An argument supplied to a field or directive. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
valueParsed value represented by this node.
+ +
+ +#### ConstArgumentNode + +**Interface.** An argument node whose value is guaranteed to be constant. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
valueParsed value represented by this node.
+ +
+ +#### FragmentArgumentNode + +**Interface.** Variable definition declared by a fragment argument. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindAST node kind for a fragment argument.
loc?Source location for this fragment argument.
nameVariable name declared by this fragment argument.
valueDefault value literal for this fragment argument, if provided.
+ +
+ +#### FragmentSpreadNode + +**Interface.** A named fragment spread, such as `...userFields`. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
arguments?Argument values supplied to the referenced fragment.
directives?Directives available in this schema or applied to this AST node.
+ +
+ +#### InlineFragmentNode + +**Interface.** An inline fragment spread with an optional type condition. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
typeCondition?The type condition that limits where this fragment applies.
directives?Directives available in this schema or applied to this AST node.
selectionSetSelections made by this operation, field, or fragment.
+ +
+ +#### FragmentDefinitionNode + +**Interface.** A reusable fragment definition declared in an executable document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
variableDefinitions?Experimental variable definitions declared by this fragment definition.
typeConditionThe type condition that limits where this fragment applies.
directives?Directives available in this schema or applied to this AST node.
selectionSetSelections made by this operation, field, or fragment.
+ +
+ +#### ValueNode + +**Type alias.** Any value literal that may appear in an executable GraphQL document. + + + +
+ +#### ConstValueNode + +**Type alias.** Any value literal that is guaranteed not to contain a variable reference. + + + +
+ +#### IntValueNode + +**Interface.** An integer value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
valueParsed value represented by this node.
+ +
+ +#### FloatValueNode + +**Interface.** A floating-point value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
valueParsed value represented by this node.
+ +
+ +#### StringValueNode + +**Interface.** A string value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
valueParsed value represented by this node.
block?Whether this string was parsed from block string syntax.
+ +
+ +#### BooleanValueNode + +**Interface.** A boolean value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
valueParsed value represented by this node.
+ +
+ +#### NullValueNode + +**Interface.** A null value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
+ +
+ +#### EnumValueNode + +**Interface.** An enum value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
valueParsed value represented by this node.
+ +
+ +#### ListValueNode + +**Interface.** A list value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
valuesValues contained in this enum, list, or input-object definition.
+ +
+ +#### ConstListValueNode + +**Interface.** A list value literal whose elements are all constant values. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
valuesValues contained in this enum, list, or input-object definition.
+ +
+ +#### ObjectValueNode + +**Interface.** An input object value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
fieldsFields declared by this object, interface, input object, or literal.
+ +
+ +#### ConstObjectValueNode + +**Interface.** An input object value literal whose fields are all constant values. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
fieldsFields declared by this object, interface, input object, or literal.
+ +
+ +#### ObjectFieldNode + +**Interface.** A field inside an input object value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
valueParsed value represented by this node.
+ +
+ +#### ConstObjectFieldNode + +**Interface.** A field inside a constant input object value literal. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
valueParsed value represented by this node.
+ +
+ +#### DirectiveNode + +**Interface.** A directive applied to an executable or type-system location. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
arguments?Arguments supplied to this field, directive, or coordinate.
+ +
+ +#### ConstDirectiveNode + +**Interface.** A directive whose arguments are all constant values. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
arguments?Arguments supplied to this field, directive, or coordinate.
+ +
+ +#### TypeNode + +**Type alias.** Any GraphQL type reference AST node. + + + +
+ +#### NamedTypeNode + +**Interface.** A named type reference. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
+ +
+ +#### ListTypeNode + +**Interface.** A list type reference. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
typeThe GraphQL type reference or runtime type for this element.
+ +
+ +#### NonNullTypeNode + +**Interface.** A non-null type reference. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
typeThe GraphQL type reference or runtime type for this element.
+ +
+ +#### TypeSystemDefinitionNode + +**Type alias.** Any type-system definition that may appear in a schema document. + + + +
+ +#### SchemaDefinitionNode + +**Interface.** A schema definition in a type-system document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
directives?Directives available in this schema or applied to this AST node.
operationTypesRoot operation types declared by this schema definition or extension.
+ +
+ +#### OperationTypeDefinitionNode + +**Interface.** A root operation type declaration inside a schema definition or extension. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
operationThe operation selected for execution.
typeThe GraphQL type reference or runtime type for this element.
+ +
+ +#### TypeDefinitionNode + +**Type alias.** Any named type definition that may appear in a schema document. + + + +
+ +#### ScalarTypeDefinitionNode + +**Interface.** A scalar type definition in a type-system document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
+ +
+ +#### ObjectTypeDefinitionNode + +**Interface.** An object type definition in a type-system document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
interfaces?Interfaces implemented by this object or interface type.
directives?Directives available in this schema or applied to this AST node.
fields?Fields declared by this object, interface, input object, or literal.
+ +
+ +#### FieldDefinitionNode + +**Interface.** A field definition declared by an object or interface type. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
arguments?Arguments supplied to this field, directive, or coordinate.
typeThe GraphQL type reference or runtime type for this element.
directives?Directives available in this schema or applied to this AST node.
+ +
+ +#### InputValueDefinitionNode + +**Interface.** An argument or input-field definition. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
typeThe GraphQL type reference or runtime type for this element.
defaultValue?Default value used when no explicit value is supplied.
directives?Directives available in this schema or applied to this AST node.
+ +
+ +#### InterfaceTypeDefinitionNode + +**Interface.** An interface type definition in a type-system document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
interfaces?Interfaces implemented by this object or interface type.
directives?Directives available in this schema or applied to this AST node.
fields?Fields declared by this object, interface, input object, or literal.
+ +
+ +#### UnionTypeDefinitionNode + +**Interface.** A union type definition in a type-system document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
types?Object types that belong to this union type.
+ +
+ +#### EnumTypeDefinitionNode + +**Interface.** An enum type definition in a type-system document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
values?Values contained in this enum, list, or input-object definition.
+ +
+ +#### EnumValueDefinitionNode + +**Interface.** An enum value definition. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
+ +
+ +#### InputObjectTypeDefinitionNode + +**Interface.** An input object type definition in a type-system document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
fields?Fields declared by this object, interface, input object, or literal.
+ +
+ +#### DirectiveDefinitionNode + +**Interface.** A directive definition in a type-system document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
description?The optional GraphQL description associated with this definition.
nameName node identifying this AST node.
arguments?Arguments supplied to this field, directive, or coordinate.
directives?Directives available in this schema or applied to this AST node.
repeatableWhether this directive may appear more than once at the same location.
locationsLocations where this directive may be applied.
+ +
+ +#### TypeSystemExtensionNode + +**Type alias.** Any type-system extension that may appear in a schema extension document. + + + +
+ +#### SchemaExtensionNode + +**Interface.** A schema extension in a type-system document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
directives?Directives available in this schema or applied to this AST node.
operationTypes?Root operation types declared by this schema definition or extension.
+ +
+ +#### TypeExtensionNode + +**Type alias.** Any named type extension that may appear in a schema extension document. + + + +
+ +#### ScalarTypeExtensionNode + +**Interface.** A scalar type extension. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
+ +
+ +#### ObjectTypeExtensionNode + +**Interface.** An object type extension. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
interfaces?Interfaces implemented by this object or interface type.
directives?Directives available in this schema or applied to this AST node.
fields?Fields declared by this object, interface, input object, or literal.
+ +
+ +#### InterfaceTypeExtensionNode + +**Interface.** An interface type extension. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
interfaces?Interfaces implemented by this object or interface type.
directives?Directives available in this schema or applied to this AST node.
fields?Fields declared by this object, interface, input object, or literal.
+ +
+ +#### UnionTypeExtensionNode + +**Interface.** A union type extension. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
types?Object types that belong to this union type.
+ +
+ +#### EnumTypeExtensionNode + +**Interface.** An enum type extension. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
values?Values contained in this enum, list, or input-object definition.
+ +
+ +#### InputObjectTypeExtensionNode + +**Interface.** An input object type extension. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
fields?Fields declared by this object, interface, input object, or literal.
+ +
+ +#### DirectiveExtensionNode + +**Interface.** A directive extension. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
directives?Directives available in this schema or applied to this AST node.
+ +
+ +#### SchemaCoordinateNode + +**Type alias.** Any AST node representing a GraphQL schema coordinate. + + + +
+ +#### TypeCoordinateNode + +**Interface.** A schema coordinate that refers to a named type. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
+ +
+ +#### MemberCoordinateNode + +**Interface.** A schema coordinate that refers to a member of a named type. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
memberNameThe member name referenced by this schema coordinate.
+ +
+ +#### ArgumentCoordinateNode + +**Interface.** A schema coordinate that refers to a field or directive argument. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
fieldNameThe field name referenced by this schema coordinate.
argumentNameThe argument name referenced by this schema coordinate.
+ +
+ +#### DirectiveCoordinateNode + +**Interface.** A schema coordinate that refers to a directive. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
+ +
+ +#### DirectiveArgumentCoordinateNode + +**Interface.** A schema coordinate that refers to a directive argument. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe discriminator identifying the concrete AST or introspection kind.
loc?The source location for this AST node, if location tracking was enabled.
nameName node identifying this AST node.
argumentNameThe argument name referenced by this schema coordinate.
+ +## Category: Kinds + +
+

+ Enumerations:
+ OperationTypeNode + + DirectiveLocation + + Kind +

+
+ +### Enumerations + +#### OperationTypeNode + +**Enumeration.** The operation types supported by GraphQL executable definitions. + +> This is not a TypeScript `enum`. GraphQL.js exports `OperationTypeNode` as both a runtime const object of literal values and a TypeScript type alias for those values. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + +
NameValue
{"QUERY"}{"\"query\""}
{"MUTATION"}{"\"mutation\""}
{"SUBSCRIPTION"}{"\"subscription\""}
+ +
+ +#### DirectiveLocation + +**Enumeration.** The set of allowed directive location values. + +> This is not a TypeScript `enum`. GraphQL.js exports `DirectiveLocation` as both a runtime const object of literal values and a TypeScript type alias for those values. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameValueDescription
{"QUERY"}{"\"QUERY\""}Directive location for query operations.
{"MUTATION"}{"\"MUTATION\""}Directive location for mutation operations.
{"SUBSCRIPTION"}{"\"SUBSCRIPTION\""}Directive location for subscription operations.
{"FIELD"}{"\"FIELD\""}Directive location for field selections.
{"FRAGMENT_DEFINITION"}{"\"FRAGMENT_DEFINITION\""}Directive location for fragment definitions.
{"FRAGMENT_SPREAD"}{"\"FRAGMENT_SPREAD\""}Directive location for fragment spreads.
{"INLINE_FRAGMENT"}{"\"INLINE_FRAGMENT\""}Directive location for inline fragments.
{"VARIABLE_DEFINITION"}{"\"VARIABLE_DEFINITION\""}Directive location for variable definitions.
{"FRAGMENT_VARIABLE_DEFINITION"}{"\"FRAGMENT_VARIABLE_DEFINITION\""}Directive location for fragment variable definitions.
{"SCHEMA"}{"\"SCHEMA\""}Directive location for schema definitions and extensions.
{"SCALAR"}{"\"SCALAR\""}Directive location for scalar type definitions and extensions.
{"OBJECT"}{"\"OBJECT\""}Directive location for object type definitions and extensions.
{"FIELD_DEFINITION"}{"\"FIELD_DEFINITION\""}Directive location for field definitions.
{"ARGUMENT_DEFINITION"}{"\"ARGUMENT_DEFINITION\""}Directive location for argument definitions.
{"INTERFACE"}{"\"INTERFACE\""}Directive location for interface type definitions and extensions.
{"UNION"}{"\"UNION\""}Directive location for union type definitions and extensions.
{"ENUM"}{"\"ENUM\""}Directive location for enum type definitions and extensions.
{"ENUM_VALUE"}{"\"ENUM_VALUE\""}Directive location for enum value definitions.
{"INPUT_OBJECT"}{"\"INPUT_OBJECT\""}Directive location for input object type definitions and extensions.
{"INPUT_FIELD_DEFINITION"}{"\"INPUT_FIELD_DEFINITION\""}Directive location for input object field definitions.
{"DIRECTIVE_DEFINITION"}{"\"DIRECTIVE_DEFINITION\""}Directive location for directive definitions and extensions.
+ +
+ +#### Kind + +**Enumeration.** + +> This is not a TypeScript `enum`. GraphQL.js exports `Kind` as both a runtime namespace object of literal values and a TypeScript type alias for those values. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameValueDescription
{"NAME"}{"\"Name\""}AST kind for name nodes.
{"DOCUMENT"}{"\"Document\""}AST kind for document nodes.
{"OPERATION_DEFINITION"}{"\"OperationDefinition\""}AST kind for operation definition nodes.
{"VARIABLE_DEFINITION"}{"\"VariableDefinition\""}AST kind for variable definition nodes.
{"SELECTION_SET"}{"\"SelectionSet\""}AST kind for selection set nodes.
{"FIELD"}{"\"Field\""}AST kind for field selection nodes.
{"ARGUMENT"}{"\"Argument\""}AST kind for argument nodes.
{"FRAGMENT_ARGUMENT"}{"\"FragmentArgument\""}AST kind for fragment argument nodes.
{"FRAGMENT_SPREAD"}{"\"FragmentSpread\""}AST kind for fragment spread nodes.
{"INLINE_FRAGMENT"}{"\"InlineFragment\""}AST kind for inline fragment nodes.
{"FRAGMENT_DEFINITION"}{"\"FragmentDefinition\""}AST kind for fragment definition nodes.
{"VARIABLE"}{"\"Variable\""}AST kind for variable reference nodes.
{"INT"}{"\"IntValue\""}AST kind for integer value nodes.
{"FLOAT"}{"\"FloatValue\""}AST kind for floating-point value nodes.
{"STRING"}{"\"StringValue\""}AST kind for string value nodes.
{"BOOLEAN"}{"\"BooleanValue\""}AST kind for boolean value nodes.
{"NULL"}{"\"NullValue\""}AST kind for null value nodes.
{"ENUM"}{"\"EnumValue\""}AST kind for enum value nodes.
{"LIST"}{"\"ListValue\""}AST kind for list value nodes.
{"OBJECT"}{"\"ObjectValue\""}AST kind for object value nodes.
{"OBJECT_FIELD"}{"\"ObjectField\""}AST kind for object field nodes.
{"DIRECTIVE"}{"\"Directive\""}AST kind for directive nodes.
{"NAMED_TYPE"}{"\"NamedType\""}AST kind for named type reference nodes.
{"LIST_TYPE"}{"\"ListType\""}AST kind for list type reference nodes.
{"NON_NULL_TYPE"}{"\"NonNullType\""}AST kind for non-null type reference nodes.
{"SCHEMA_DEFINITION"}{"\"SchemaDefinition\""}AST kind for schema definition nodes.
{"OPERATION_TYPE_DEFINITION"}{"\"OperationTypeDefinition\""}AST kind for operation type definition nodes.
{"SCALAR_TYPE_DEFINITION"}{"\"ScalarTypeDefinition\""}AST kind for scalar type definition nodes.
{"OBJECT_TYPE_DEFINITION"}{"\"ObjectTypeDefinition\""}AST kind for object type definition nodes.
{"FIELD_DEFINITION"}{"\"FieldDefinition\""}AST kind for field definition nodes.
{"INPUT_VALUE_DEFINITION"}{"\"InputValueDefinition\""}AST kind for input value definition nodes.
{"INTERFACE_TYPE_DEFINITION"}{"\"InterfaceTypeDefinition\""}AST kind for interface type definition nodes.
{"UNION_TYPE_DEFINITION"}{"\"UnionTypeDefinition\""}AST kind for union type definition nodes.
{"ENUM_TYPE_DEFINITION"}{"\"EnumTypeDefinition\""}AST kind for enum type definition nodes.
{"ENUM_VALUE_DEFINITION"}{"\"EnumValueDefinition\""}AST kind for enum value definition nodes.
{"INPUT_OBJECT_TYPE_DEFINITION"}{"\"InputObjectTypeDefinition\""}AST kind for input object type definition nodes.
{"DIRECTIVE_DEFINITION"}{"\"DirectiveDefinition\""}AST kind for directive definition nodes.
{"SCHEMA_EXTENSION"}{"\"SchemaExtension\""}AST kind for schema extension nodes.
{"DIRECTIVE_EXTENSION"}{"\"DirectiveExtension\""}AST kind for directive extension nodes.
{"SCALAR_TYPE_EXTENSION"}{"\"ScalarTypeExtension\""}AST kind for scalar type extension nodes.
{"OBJECT_TYPE_EXTENSION"}{"\"ObjectTypeExtension\""}AST kind for object type extension nodes.
{"INTERFACE_TYPE_EXTENSION"}{"\"InterfaceTypeExtension\""}AST kind for interface type extension nodes.
{"UNION_TYPE_EXTENSION"}{"\"UnionTypeExtension\""}AST kind for union type extension nodes.
{"ENUM_TYPE_EXTENSION"}{"\"EnumTypeExtension\""}AST kind for enum type extension nodes.
{"INPUT_OBJECT_TYPE_EXTENSION"}{"\"InputObjectTypeExtension\""}AST kind for input object type extension nodes.
{"TYPE_COORDINATE"}{"\"TypeCoordinate\""}AST kind for type coordinate nodes.
{"MEMBER_COORDINATE"}{"\"MemberCoordinate\""}AST kind for member coordinate nodes.
{"ARGUMENT_COORDINATE"}{"\"ArgumentCoordinate\""}AST kind for argument coordinate nodes.
{"DIRECTIVE_COORDINATE"}{"\"DirectiveCoordinate\""}AST kind for directive coordinate nodes.
{"DIRECTIVE_ARGUMENT_COORDINATE"}{"\"DirectiveArgumentCoordinate\""}AST kind for directive argument coordinate nodes.
+ +## Category: Lexing + +
+

+ Classes:
+ Lexer +

+

+ Enumerations:
+ TokenKind +

+
+ +### Classes + +#### Lexer + +Given a Source object, creates a Lexer for that source. +A Lexer is a stateful stream generator in that every time +it is advanced, it returns the next token in the Source. Assuming the +source lexes, the final Token emitted by the lexer will be of kind +EOF, after which the lexer will repeatedly return the same EOF token +whenever called. + +
+ +##### Constructor + +Creates a Lexer instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
sourceSource document used to derive error locations.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourceSource document used to derive error locations.
lastTokenMost recent non-ignored token returned by the lexer.
tokenCurrent non-ignored token at the lexer cursor.
lineThe (1-indexed) line containing the current token.
lineStartCharacter offset where the current line starts.
+ +
+ +##### advance() + +Advances the token stream to the next non-ignored token. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The next non-ignored token.
+ +
+ +
Example
+ +```ts +import { Lexer, Source } from 'graphql/language'; + +const lexer = new Lexer(new Source('{ hello }')); +const token = lexer.advance(); + +token.kind; // => '{' +lexer.token; // => token +``` + +
+ +##### lookahead() + +Looks ahead and returns the next non-ignored token, but does not change +the state of Lexer. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The next non-ignored token without advancing the lexer.
+ +
+ +
Example
+ +```ts +import { Lexer, Source } from 'graphql/language'; + +const lexer = new Lexer(new Source('{ hello }')); +const token = lexer.lookahead(); + +token.kind; // => '{' +lexer.token.kind; // => '' +``` + +### Enumerations + +#### TokenKind + +**Enumeration.** An exported enum describing the different kinds of tokens that the +lexer emits. + +> This is not a TypeScript `enum`. GraphQL.js exports `TokenKind` as both a runtime const object of literal values and a TypeScript type alias for those values. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameValue
{"SOF"}{"\"\""}
{"EOF"}{"\"\""}
{"BANG"}{"\"!\""}
{"DOLLAR"}{"\"$\""}
{"AMP"}{"\"&\""}
{"PAREN_L"}{"\"(\""}
{"PAREN_R"}{"\")\""}
{"DOT"}{"\".\""}
{"SPREAD"}{"\"...\""}
{"COLON"}{"\":\""}
{"EQUALS"}{"\"=\""}
{"AT"}{"\"@\""}
{"BRACKET_L"}{"\"[\""}
{"BRACKET_R"}{"\"]\""}
{"BRACE_L"}{"\"{\""}
{"PIPE"}{"\"\u007c\""}
{"BRACE_R"}{"\"}\""}
{"NAME"}{"\"Name\""}
{"INT"}{"\"Int\""}
{"FLOAT"}{"\"Float\""}
{"STRING"}{"\"String\""}
{"BLOCK_STRING"}{"\"BlockString\""}
{"COMMENT"}{"\"Comment\""}
+ +## Category: Source + +
+

+ Classes:
+ Source +

+

+ Functions:
+ getLocation() + + printLocation() + + printSourceLocation() +

+

+ Types:
+ SourceLocation +

+
+ +### Classes + +#### Source + +A representation of source input to GraphQL. The `name` and `locationOffset` parameters are +optional, but they are useful for clients who store GraphQL documents in source files. +For example, if the GraphQL input starts at line 40 in a file named `Foo.graphql`, it might +be useful for `name` to be `"Foo.graphql"` and location to be `{ line: 40, column: 1 }`. +The `line` and `column` properties in `locationOffset` are 1-indexed. + +
+ +##### Constructor + +Creates a Source instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
bodyThe GraphQL source text.
nameName used in diagnostics for this source.
locationOffsetOne-indexed line and column where this source begins.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
bodyThe GraphQL source text.
nameName used in diagnostics for this source, such as a file path or request name.
locationOffsetOne-indexed line and column where this source begins.
+ +### Functions + +#### getLocation() + +Takes a Source and a UTF-8 character offset, and returns the corresponding +line and column as a SourceLocation. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourceThe source document that contains the position.
positionThe UTF-8 character offset in the source body.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The 1-indexed line and column for the given source position.
+ +
+ +
Example
+ +```ts +import { Source, getLocation } from 'graphql/language'; + +const source = new Source('type Query { hello: String }'); +const location = getLocation(source, 13); + +location; // => { line: 1, column: 14 } +``` + +
+ +#### printLocation() + +Render a helpful description of the location in the GraphQL Source document. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
locationThe AST location to print.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A formatted source excerpt with line and column information.
+ +
+ +
Example
+ +```ts +import { parse, printLocation } from 'graphql/language'; + +const document = parse('type Query { hello: String }'); +const location = document.definitions[0].loc; + +if (location) { + const printed = printLocation(location); + + printed; // => 'GraphQL request:1:1\n1 | type Query { hello: String }\n | ^' +} +``` + +
+ +#### printSourceLocation() + +Render a helpful description of the location in the GraphQL Source document. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourceThe source document that contains the location.
sourceLocationThe 1-indexed line and column to print.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A formatted source excerpt with line and column information.
+ +
+ +
Example
+ +```ts +import { Source, printSourceLocation } from 'graphql/language'; + +const source = new Source('type Query { hello: String }'); +const printed = printSourceLocation(source, { line: 1, column: 14 }); + +printed; // => 'GraphQL request:1:14\n1 | type Query { hello: String }\n | ^' +``` + +### Types + +#### SourceLocation + +**Interface.** Represents a location in a Source. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
lineOne-indexed line number in the source document.
columnOne-indexed column number in the source document.
+ +## Category: Parsing + +
+

+ Functions:
+ parse() + + parseValue() + + parseConstValue() + + parseType() + + parseSchemaCoordinate() +

+

+ Types:
+ ParseOptions +

+
+ +### Functions + +#### parse() + +Given a GraphQL source, parses it into a Document. +Throws GraphQLError if a syntax error is encountered. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourceA GraphQL source string or source object.
options?Optional parser configuration.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The parsed GraphQL document AST.
+ +
+ +
Example 1
+ +```ts +// Parse a GraphQL document with the default parser options. +import { parse } from 'graphql/language'; + +const document = parse('{ hero { name } }'); + +document.kind; // => 'Document' +``` + +
+ +
Example 2
+ +```ts +// This variant enables parser options and provides an explicit lexer. +import { Lexer, Source, parse } from 'graphql/language'; + +const document = parse(` + { + t { ...A(var: true) } + } + fragment A($var: Boolean = false) on T { + name + } +`, { + experimentalFragmentArguments: true, + maxTokens: 80, + noLocation: true, +}); +const directiveDocument = parse('directive @foo @bar on FIELD', { + experimentalDirectivesOnDirectiveDefinitions: true, +}); +const source = new Source('{ hero }'); +const lexerDocument = parse(source, { lexer: new Lexer(source) }); + +document.definitions[0].kind; // => 'OperationDefinition' +document.definitions[1].kind; // => 'FragmentDefinition' +document.loc; // => undefined +directiveDocument.definitions[0].kind; // => 'DirectiveDefinition' +lexerDocument.definitions[0].kind; // => 'OperationDefinition' +``` + +
+ +#### parseValue() + +Given a string containing a GraphQL value (ex. `[42]`), parse the AST for +that value. +Throws GraphQLError if a syntax error is encountered. + +This is useful within tools that operate upon GraphQL Values directly and +in isolation of complete GraphQL documents. + +Consider providing the results to the utility function: valueFromAST(). + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourceA GraphQL source string or source object containing a value.
options?Optional parser configuration.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The parsed GraphQL value AST.
+ +
+ +
Example
+ +```ts +import { parseValue } from 'graphql/language'; + +const value = parseValue('[42]'); + +value.kind; // => 'ListValue' +``` + +
+ +#### parseConstValue() + +Similar to parseValue(), but raises a parse error if it encounters a +variable. The return type will be a constant value. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourceA GraphQL source string or source object containing a constant value.
options?Optional parser configuration.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The parsed GraphQL constant value AST.
+ +
+ +
Example
+ +```ts +import { parseConstValue } from 'graphql/language'; + +const value = parseConstValue('{ enabled: true }'); + +value.kind; // => 'ObjectValue' +parseConstValue('$variable'); // throws an error +``` + +
+ +#### parseType() + +Given a string containing a GraphQL Type (ex. `[Int!]`), parse the AST for +that type. +Throws GraphQLError if a syntax error is encountered. + +This is useful within tools that operate upon GraphQL Types directly and +in isolation of complete GraphQL documents. + +Consider providing the results to the utility function: typeFromAST(). + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourceA GraphQL source string or source object containing a type reference.
options?Optional parser configuration.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The parsed GraphQL type AST.
+ +
+ +
Example
+ +```ts +import { parseType } from 'graphql/language'; + +const type = parseType('[String!]'); + +type.kind; // => 'ListType' +``` + +
+ +#### parseSchemaCoordinate() + +Given a string containing a GraphQL Schema Coordinate (ex. `Type.field`), +parse the AST for that schema coordinate. +Throws GraphQLError if a syntax error is encountered. + +Consider providing the results to the utility function: +resolveASTSchemaCoordinate(). Or calling resolveSchemaCoordinate() directly +with an unparsed source. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
sourceA GraphQL source string or source object containing a schema coordinate.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The parsed GraphQL schema coordinate AST.
+ +
+ +
Example
+ +```ts +import { parseSchemaCoordinate } from 'graphql/language'; + +const coordinate = parseSchemaCoordinate('Query.hero'); + +coordinate.kind; // => 'MemberCoordinate' +``` + +### Types + +#### ParseOptions + +**Interface.** Configuration options to control parser behavior + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
noLocation?By default, the parser creates AST nodes that know the location
+in the source that they correspond to. This configuration flag
+disables that behavior for performance or testing.
maxTokens?Parser CPU and memory usage is linear to the number of tokens in a document
+however in extreme cases it becomes quadratic due to memory exhaustion.
+Parsing happens before validation so even invalid queries can burn lots of
+CPU time and memory.
+To prevent this you can set a maximum number of tokens allowed within a document.
experimentalFragmentArguments?EXPERIMENTAL:
+If enabled, the parser will understand and parse fragment variable definitions
+and arguments on fragment spreads. Fragment variable definitions will be represented
+in the {"variableDefinitions"} field of the FragmentDefinitionNode.
+Fragment spread arguments will be represented in the {"arguments"} field of FragmentSpreadNode.
experimentalDirectivesOnDirectiveDefinitions?EXPERIMENTAL:
+If enabled, the parser will parse directives on directive definitions.
+This syntax is not part of the GraphQL specification and may change.
+ +
+ +
experimentalFragmentArguments Example
+ +```graphql +{ + t { ...A(var: true) } +} +fragment A($var: Boolean = false) on T { + ...B(x: $var) +} +``` + +
+ +
experimentalDirectivesOnDirectiveDefinitions Example
+ +```graphql +directive @foo @bar on FIELD +``` + +## Category: AST Predicates + + + +### Functions + +#### isDefinitionNode() + +Returns true when the AST node is a definition node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a definition node.
+ +
+ +
Example
+ +```ts +import { parse, isDefinitionNode } from 'graphql/language'; + +const document = parse('{ hello }'); + +isDefinitionNode(document.definitions[0]); // => true +isDefinitionNode(document); // => false +``` + +
+ +#### isExecutableDefinitionNode() + +Returns true when the AST node is an executable definition node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is an executable definition node.
+ +
+ +
Example
+ +```ts +import { parse, isExecutableDefinitionNode } from 'graphql/language'; + +const query = parse('{ hello }'); +const schema = parse('type Query { hello: String }'); + +isExecutableDefinitionNode(query.definitions[0]); // => true +isExecutableDefinitionNode(schema.definitions[0]); // => false +``` + +
+ +#### isSubscriptionOperationDefinitionNode() + +A type predicate for SubscriptionOperationDefinitionNode. +Useful anywhere that must distinguish subscription operations from +queries and mutations, such as the subscription execution pipeline +which routes events through a different code path. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeOperation definition node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the operation definition is a subscription.
+ +
+ +
Example
+ +```ts +import { parse, isSubscriptionOperationDefinitionNode } from 'graphql/language'; + +const subscription = parse('subscription { greeting }').definitions[0]; +const query = parse('{ greeting }').definitions[0]; + +isSubscriptionOperationDefinitionNode(subscription); // => true +isSubscriptionOperationDefinitionNode(query); // => false +``` + +
+ +#### isSelectionNode() + +Returns true when the AST node is a selection node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a selection node.
+ +
+ +
Example
+ +```ts +import { Kind, isSelectionNode } from 'graphql/language'; + +const field = { kind: Kind.FIELD, name: { kind: Kind.NAME, value: 'hello' } }; +const document = { kind: Kind.DOCUMENT, definitions: [] }; + +isSelectionNode(field); // => true +isSelectionNode(document); // => false +``` + +
+ +#### isValueNode() + +Returns true when the AST node is a value node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a value node.
+ +
+ +
Example
+ +```ts +import { parseType, parseValue, isValueNode } from 'graphql/language'; + +const value = parseValue('[42]'); +const type = parseType('[String!]'); + +isValueNode(value); // => true +isValueNode(type); // => false +``` + +
+ +#### isConstValueNode() + +Returns true when the AST node is a constant value node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a constant value node.
+ +
+ +
Example
+ +```ts +import { parseConstValue, parseValue, isConstValueNode } from 'graphql/language'; + +const value = parseConstValue('[42]'); +const variable = parseValue('$id'); + +isConstValueNode(value); // => true +isConstValueNode(variable); // => false +``` + +
+ +#### isTypeNode() + +Returns true when the AST node is a type node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a type node.
+ +
+ +
Example
+ +```ts +import { parseType, parseValue, isTypeNode } from 'graphql/language'; + +const type = parseType('[String!]'); +const value = parseValue('[42]'); + +isTypeNode(type); // => true +isTypeNode(value); // => false +``` + +
+ +#### isTypeSystemDefinitionNode() + +Returns true when the AST node is a type system definition node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a type system definition node.
+ +
+ +
Example
+ +```ts +import { parse, isTypeSystemDefinitionNode } from 'graphql/language'; + +const schema = parse('type Query { hello: String }'); +const query = parse('{ hello }'); + +isTypeSystemDefinitionNode(schema.definitions[0]); // => true +isTypeSystemDefinitionNode(query.definitions[0]); // => false +``` + +
+ +#### isTypeDefinitionNode() + +Returns true when the AST node is a type definition node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a type definition node.
+ +
+ +
Example
+ +```ts +import { parse, isTypeDefinitionNode } from 'graphql/language'; + +const typeDefinition = parse('type Query { hello: String }'); +const directiveDefinition = parse('directive @cache on FIELD'); + +isTypeDefinitionNode(typeDefinition.definitions[0]); // => true +isTypeDefinitionNode(directiveDefinition.definitions[0]); // => false +``` + +
+ +#### isTypeSystemExtensionNode() + +Returns true when the AST node is a type system extension node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a type system extension node.
+ +
+ +
Example
+ +```ts +import { parse, isTypeSystemExtensionNode } from 'graphql/language'; + +const extension = parse('extend type Query { hello: String }'); +const definition = parse('type Query { hello: String }'); + +isTypeSystemExtensionNode(extension.definitions[0]); // => true +isTypeSystemExtensionNode(definition.definitions[0]); // => false +``` + +
+ +#### isTypeExtensionNode() + +Returns true when the AST node is a type extension node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a type extension node.
+ +
+ +
Example
+ +```ts +import { parse, isTypeExtensionNode } from 'graphql/language'; + +const extension = parse('extend type Query { hello: String }'); +const schemaExtension = parse('extend schema { query: Query }'); + +isTypeExtensionNode(extension.definitions[0]); // => true +isTypeExtensionNode(schemaExtension.definitions[0]); // => false +``` + +
+ +#### isSchemaCoordinateNode() + +Returns true when the AST node is a schema coordinate node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to test.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the AST node is a schema coordinate node.
+ +
+ +
Example
+ +```ts +import { + parse, + parseSchemaCoordinate, + isSchemaCoordinateNode, +} from 'graphql/language'; + +const coordinate = parseSchemaCoordinate('Query.hero'); +const document = parse('{ hero }'); + +isSchemaCoordinateNode(coordinate); // => true +isSchemaCoordinateNode(document); // => false +``` + +## Category: Printing + +
+

+ Functions:
+ print() +

+
+ +### Functions + +#### print() + +Converts an AST into a string, using one set of reasonable +formatting rules. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
astThe GraphQL AST node to print.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A stable string representation of the AST.
+ +
+ +
Example
+ +```ts +import { parse, print } from 'graphql'; + +const ast = parse('{ hero { name } }'); +const text = print(ast); + +text; // => '{\n hero {\n name\n }\n}' +``` + +## Category: Visiting + +
+

+ Functions:
+ visitInParallel() + + getEnterLeaveForKind() +

+

+ Constants:
+ BREAK +

+

+ Types:
+ ASTVisitor + + ASTVisitFn + + ASTVisitorKeyMap +

+
+ +### Functions + +#### visitInParallel() + +Creates a new visitor instance which delegates to many visitors to run in +parallel. Each visitor will be visited for each node before moving on. + +If a prior visitor edits a node, no following visitors will see that node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
visitorsThe visitors to merge into one parallel visitor.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that delegates traversal to each provided visitor.
+ +
+ +
Example
+ +```ts +import { parse, visit, visitInParallel } from 'graphql/language'; + +const document = parse('{ hero { name } }'); +const events = []; + +visit( + document, + visitInParallel([ + { Field: (node) => { events.push(`field:${node.name.value}`); } }, + { Name: (node) => { events.push(`name:${node.value}`); } }, + ]), +); + +events; // => ['field:hero', 'name:hero', 'field:name', 'name:name'] +``` + +
+ +#### getEnterLeaveForKind() + +Given a visitor instance and a node kind, return EnterLeaveVisitor for that kind. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
visitorThe visitor object to inspect.
kindThe AST node kind to resolve handlers for.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The enter and leave handlers that apply for the given node kind.
+ +
+ +
Example
+ +```ts +import { Kind, getEnterLeaveForKind } from 'graphql/language'; + +const handlers = getEnterLeaveForKind({ Field: () => {} }, Kind.FIELD); + +typeof handlers.enter; // => 'function' +handlers.leave; // => undefined +``` + +### Constants + +#### BREAK + +A value that can be returned from a visitor function to stop traversal. + +
+ +
Type
+ + + +### Types + +#### ASTVisitor + +**Type alias.** A visitor defines the callbacks called during AST traversal. + + + +
+ +#### ASTVisitFn + +**Type alias.** A visitor is composed of visit functions called for each node during traversal. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TVisitedNodeAST node type handled by this visitor function.
+ + + +
+ +#### ASTVisitorKeyMap + +**Type alias.** A visitor key map describes the traversable child properties for each node kind. + + diff --git a/website/pages/api-v17/language/_meta.ts b/website/pages/api-v17/language/_meta.ts new file mode 100644 index 0000000000..a1454144eb --- /dev/null +++ b/website/pages/api-v17/language/_meta.ts @@ -0,0 +1,36 @@ +const meta = { + ast: { + title: 'Category: AST', + href: '/api-v17/language#category-ast', + }, + kinds: { + title: 'Category: Kinds', + href: '/api-v17/language#category-kinds', + }, + lexing: { + title: 'Category: Lexing', + href: '/api-v17/language#category-lexing', + }, + source: { + title: 'Category: Source', + href: '/api-v17/language#category-source', + }, + parsing: { + title: 'Category: Parsing', + href: '/api-v17/language#category-parsing', + }, + 'ast-predicates': { + title: 'Category: AST Predicates', + href: '/api-v17/language#category-ast-predicates', + }, + printing: { + title: 'Category: Printing', + href: '/api-v17/language#category-printing', + }, + visiting: { + title: 'Category: Visiting', + href: '/api-v17/language#category-visiting', + }, +}; + +export default meta; diff --git a/website/pages/api-v17/type.mdx b/website/pages/api-v17/type.mdx new file mode 100644 index 0000000000..d36821a452 --- /dev/null +++ b/website/pages/api-v17/type.mdx @@ -0,0 +1,11846 @@ +import { ApiSignature, ApiType } from '../../components/ApiCode'; + +Create and inspect GraphQL type definitions and schemas. + +These exports are also available from the root `graphql` package. + +For documentation purposes, these exports are grouped into the following categories: + +- [Paths](/api-v17/type#category-paths) +- [Names](/api-v17/type#category-names) +- [Types](/api-v17/type#category-types) +- [Directives](/api-v17/type#category-directives) +- [Introspection](/api-v17/type#category-introspection) +- [Scalars](/api-v17/type#category-scalars) +- [Schema](/api-v17/type#category-schema) +- [Validation](/api-v17/type#category-validation) + +## Category: Paths + +
+

+ Types:
+ ResponsePath +

+
+ +### Types + +#### ResponsePath + +**Interface.** Represents a linked response path from a field back to the root response. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
prevThe previous segment in the linked response path, or undefined at the root.
keyThe field name or list index for this response path segment.
typenameThe runtime object type name associated with this path segment, if known.
+ +## Category: Names + +
+

+ Functions:
+ assertName() + + assertEnumValueName() +

+
+ +### Functions + +#### assertName() + +Upholds the spec rules about naming. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name to validate.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The validated GraphQL name.
+ +
+ +
Example
+ +```ts +import { assertName } from 'graphql/type'; + +assertName('User'); // => 'User' +assertName('123User'); // throws an error +``` + +
+ +#### assertEnumValueName() + +Upholds the spec rules about naming enum values. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name to validate.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The validated GraphQL name.
+ +
+ +
Example
+ +```ts +import { assertEnumValueName } from 'graphql/type'; + +assertEnumValueName('ACTIVE'); // => 'ACTIVE' +assertEnumValueName('true'); // throws an error +``` + +## Category: Types + +
+

+ Classes:
+ GraphQLList + + GraphQLNonNull + + GraphQLScalarType + + GraphQLObjectType + + GraphQLInterfaceType + + GraphQLUnionType + + GraphQLEnumType + + GraphQLInputObjectType +

+

+ Functions:
+ isType() + + assertType() + + isScalarType() + + assertScalarType() + + isObjectType() + + assertObjectType() + + isField() + + assertField() + + isArgument() + + assertArgument() + + isInterfaceType() + + assertInterfaceType() + + isUnionType() + + assertUnionType() + + isEnumType() + + assertEnumType() + + isEnumValue() + + assertEnumValue() + + isInputObjectType() + + assertInputObjectType() + + isInputField() + + assertInputField() + + assertListType() + + assertNonNullType() + + isInputType() + + assertInputType() + + isOutputType() + + assertOutputType() + + isLeafType() + + assertLeafType() + + isCompositeType() + + assertCompositeType() + + isAbstractType() + + assertAbstractType() + + isWrappingType() + + assertWrappingType() + + isNullableType() + + assertNullableType() + + isNamedType() + + assertNamedType() + + resolveReadonlyArrayThunk() + + resolveObjMapThunk() + + isRequiredArgument() + + isRequiredInputField() +

+

+ Types:
+ GraphQLType + + GraphQLNullableInputType + + GraphQLInputType + + GraphQLNullableOutputType + + GraphQLOutputType + + GraphQLLeafType + + GraphQLCompositeType + + GraphQLAbstractType + + GraphQLWrappingType + + GraphQLNullableType + + GraphQLNamedType + + GraphQLNamedInputType + + GraphQLNamedOutputType + + ThunkReadonlyArray + + ThunkObjMap + + GraphQLScalarTypeExtensions + + GraphQLScalarSerializer + + GraphQLScalarOutputValueCoercer + + GraphQLScalarValueParser + + GraphQLScalarInputValueCoercer + + GraphQLScalarLiteralParser + + GraphQLScalarInputLiteralCoercer + + GraphQLScalarTypeConfig + + GraphQLObjectTypeExtensions + + GraphQLObjectTypeConfig + + GraphQLTypeResolver + + GraphQLIsTypeOfFn + + GraphQLFieldResolver + + GraphQLResolveInfoHelpers + + GraphQLResolveInfo + + GraphQLFieldExtensions + + GraphQLFieldConfig + + GraphQLFieldConfigArgumentMap + + GraphQLArgumentExtensions + + GraphQLArgumentConfig + + GraphQLFieldConfigMap + + GraphQLField + + GraphQLArgument + + GraphQLFieldMap + + GraphQLDefaultInput + + GraphQLInterfaceTypeExtensions + + GraphQLInterfaceTypeConfig + + GraphQLUnionTypeExtensions + + GraphQLUnionTypeConfig + + GraphQLEnumTypeExtensions + + GraphQLEnumTypeConfig + + GraphQLEnumValueConfigMap + + GraphQLEnumValueExtensions + + GraphQLEnumValueConfig + + GraphQLEnumValue + + GraphQLInputObjectTypeExtensions + + GraphQLInputObjectTypeConfig + + GraphQLInputFieldExtensions + + GraphQLInputFieldConfig + + GraphQLInputFieldConfigMap + + GraphQLInputField + + GraphQLInputFieldMap +

+
+ +### Classes + +#### GraphQLList + +List Type Wrapper + +A list is a wrapping type which points to another type. +Lists are often created within the context of defining the fields of +an object type. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TThe GraphQL type wrapped by this list type.
+ +
+ +
Example
+ +```ts +const PersonType = new GraphQLObjectType({ + name: 'Person', + fields: () => ({ + parents: { type: new GraphQLList(PersonType) }, + children: { type: new GraphQLList(PersonType) }, + }) +}) +``` + +
+ +##### Constructor + +Creates a GraphQLList instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
ofTypeThe type to wrap.
+ +
+ +##### Members + + + + + + + + + + + + + + + + +
NameTypeDescription
ofTypeThe type wrapped by this list or non-null type.
+ +
+ +##### toString() + +Returns this wrapping type as a GraphQL type-reference string. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The GraphQL type-reference string.
+ +
+ +
Example
+ +```ts +import { GraphQLList, GraphQLNonNull, GraphQLString } from 'graphql/type'; + +const stringList = new GraphQLList(GraphQLString); +const requiredStringList = new GraphQLList(new GraphQLNonNull(GraphQLString)); + +stringList.toString(); // => '[String]' +requiredStringList.toString(); // => '[String!]' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { GraphQLList, GraphQLString } from 'graphql/type'; + +const stringList = new GraphQLList(GraphQLString); + +stringList.toJSON(); // => '[String]' +JSON.stringify({ type: stringList }); // => '{"type":"[String]"}' +``` + +
+ +#### GraphQLNonNull + +Non-Null Type Wrapper + +A non-null is a wrapping type which points to another type. +Non-null types enforce that their values are never null and can ensure +an error is raised if this ever occurs during a request. It is useful for +fields which you can make a strong guarantee on non-nullability, for example +usually the id field of a database row will never be null. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TThe nullable GraphQL type wrapped by this non-null type.
+ +
+ +
Example
+ +```ts +const RowType = new GraphQLObjectType({ + name: 'Row', + fields: () => ({ + id: { type: new GraphQLNonNull(GraphQLString) }, + }) +}) +``` + +Note: the enforcement of non-nullability occurs within the executor. + +
+ +##### Constructor + +Creates a GraphQLNonNull instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
ofTypeThe type to wrap.
+ +
+ +##### Members + + + + + + + + + + + + + + + + +
NameTypeDescription
ofTypeThe type wrapped by this list or non-null type.
+ +
+ +##### toString() + +Returns this wrapping type as a GraphQL type-reference string. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The GraphQL type-reference string.
+ +
+ +
Example
+ +```ts +import { GraphQLList, GraphQLNonNull, GraphQLString } from 'graphql/type'; + +const requiredString = new GraphQLNonNull(GraphQLString); +const requiredStringList = new GraphQLNonNull( + new GraphQLList(GraphQLString), +); + +requiredString.toString(); // => 'String!' +requiredStringList.toString(); // => '[String]!' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { GraphQLNonNull, GraphQLString } from 'graphql/type'; + +const requiredString = new GraphQLNonNull(GraphQLString); + +requiredString.toJSON(); // => 'String!' +JSON.stringify({ type: requiredString }); // => '{"type":"String!"}' +``` + +
+ +#### GraphQLScalarType + +Scalar Type Definition + +Scalar types define the leaf values of a GraphQL response and the input +values accepted by arguments and input object fields. A scalar type has a +name and coercion functions that validate and convert runtime values and +GraphQL literals. + +If a type's coerceOutputValue function returns `null` or does not return a +value (i.e. it returns `undefined`) then an error will be raised and a +`null` value will be returned in the response. Prefer validating inputs +before execution so clients receive input diagnostics before result coercion +fails. +Custom scalar behavior is defined via the following functions: + + - coerceOutputValue(value): Implements "Result Coercion". Given an internal value, + produces an external value valid for this type. Returns undefined or + throws an error to indicate invalid values. + + - coerceInputValue(value): Implements "Input Coercion" for values. Given an + external value (for example, variable values), produces an internal value + valid for this type. Returns undefined or throws an error to indicate + invalid values. + + - coerceInputLiteral(ast): Implements "Input Coercion" for constant literals. + Given a GraphQL literal (AST) (for example, an argument value), produces + an internal value valid for this type. Returns undefined or throws an + error to indicate invalid values. + + - valueToLiteral(value): Converts an external value to a GraphQL + literal (AST). Returns undefined or throws an error to indicate + invalid values. + + Deprecated, to be removed in v18: + + - serialize(value): Implements "Result Coercion". Renamed to + `coerceOutputValue()`. + + - parseValue(value): Implements "Input Coercion" for values. Renamed to + `coerceInputValue()`. + + - parseLiteral(ast): Implements "Input Coercion" for literals including + non-specified replacement of variables embedded within complex scalars. + Replaced by the combination of the `replaceVariables()` utility and the + `coerceInputLiteral()` method. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TInternalInternal runtime representation for this scalar.
TExternalExternal representation accepted from or returned to callers.
+ +
+ +
Example
+ +```ts +import { GraphQLScalarType, Kind } from 'graphql'; + +const ensureOdd = (value) => { + if (!Number.isFinite(value)) { + throw new Error( + `Scalar "Odd" cannot represent "${value}" since it is not a finite number.`, + ); + } + + if (value % 2 === 0) { + throw new Error(`Scalar "Odd" cannot represent "${value}" since it is even.`); + } + + return value; +}; + +const OddType = new GraphQLScalarType({ + name: 'Odd', + coerceOutputValue: (value) => { + return ensureOdd(value); + }, + coerceInputValue: (value) => { + return ensureOdd(value); + }, + valueToLiteral: (value) => { + return { kind: Kind.INT, value: String(ensureOdd(value)) }; + } +}); +``` + +
+ +##### Constructor + +Creates a GraphQLScalarType instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
configConfiguration describing this object.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
specifiedByURLURL identifying the behavior specified for this custom scalar.
serializeDeprecated legacy serializer used to convert internal values for response
+output. Use {"coerceOutputValue()"} instead.
parseValueDeprecated legacy parser used to convert externally provided input values.
+Use {"coerceInputValue()"} instead.
parseLiteralDeprecated legacy parser used to convert externally provided input
+literals. Use {"replaceVariables()"} and {"coerceInputLiteral()"} instead.
coerceOutputValueCoercer used to convert internal scalar values for response output.
coerceInputValueCoercer used to convert externally provided scalar input values.
coerceInputLiteralCoercer used to convert GraphQL scalar input literals.
valueToLiteralConverter used to produce GraphQL literals from runtime input values.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
extensionASTNodesAST extension nodes applied to this schema element.
+ +
+ +##### toConfig() + +Returns a normalized configuration object for this object. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this object.
+ +
+ +
Example
+ +```ts +import { GraphQLScalarType } from 'graphql/type'; + +const Url = new GraphQLScalarType({ + name: 'Url', + description: 'An absolute URL string.', + specifiedByURL: 'https://url.spec.whatwg.org/', +}); + +const config = Url.toConfig(); +const UrlCopy = new GraphQLScalarType(config); + +config.name; // => 'Url' +config.specifiedByURL; // => 'https://url.spec.whatwg.org/' +UrlCopy.name; // => Url.name +``` + +
+ +##### toString() + +Returns the schema coordinate identifying this scalar type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema coordinate for this scalar type.
+ +
+ +
Example
+ +```ts +import { GraphQLScalarType } from 'graphql/type'; + +const DateTime = new GraphQLScalarType({ name: 'DateTime' }); + +DateTime.toString(); // => 'DateTime' +String(DateTime); // => 'DateTime' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { GraphQLScalarType } from 'graphql/type'; + +const DateTime = new GraphQLScalarType({ name: 'DateTime' }); + +DateTime.toJSON(); // => 'DateTime' +JSON.stringify({ type: DateTime }); // => '{"type":"DateTime"}' +``` + +
+ +#### GraphQLObjectType + +Object Type Definition + +Almost all of the GraphQL types you define will be object types. Object types +have a name, but most importantly describe their fields. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
TAbstractRuntime value type used for abstract type resolution.
+ +
+ +
Example 1
+ +```ts +const AddressType = new GraphQLObjectType({ + name: 'Address', + fields: { + street: { type: GraphQLString }, + number: { type: GraphQLInt }, + formatted: { + type: GraphQLString, + resolve: (obj) => { + return obj.number + ' ' + obj.street + } + } + } +}); +``` + +
+ +
Example 2
+ +When two types need to refer to each other, or a type needs to refer to +itself in a field, you can use a function expression (aka a closure or a +thunk) to supply the fields lazily. + +```ts +const PersonType = new GraphQLObjectType({ + name: 'Person', + fields: () => ({ + name: { type: GraphQLString }, + bestFriend: { type: PersonType }, + }) +}); +``` + +
+ +##### Constructor + +Creates a GraphQLObjectType instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
configConfiguration describing this object.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
isTypeOfPredicate used to determine whether a runtime value belongs to this object type.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
extensionASTNodesAST extension nodes applied to this schema element.
+ +
+ +##### getFields() + +Returns the fields defined by this type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The fields keyed by field name.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertObjectType } from 'graphql/type'; + +const schema = buildSchema(` + type User { + id: ID! + name: String + } + + type Query { + viewer: User + } +`); + +const User = assertObjectType(schema.getType('User')); +const fields = User.getFields(); + +Object.keys(fields); // => ['id', 'name'] +String(fields.id.type); // => 'ID!' +``` + +
+ +##### getInterfaces() + +Returns the interfaces implemented by this type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The implemented interfaces.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertObjectType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Query { + viewer: User + } +`); + +const User = assertObjectType(schema.getType('User')); + +User.getInterfaces().map((type) => type.name); // => ['Node'] +``` + +
+ +##### toConfig() + +Returns a normalized configuration object for this object. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this object.
+ +
+ +
Example
+ +```ts +import { GraphQLObjectType, GraphQLString } from 'graphql/type'; + +const User = new GraphQLObjectType({ + name: 'User', + fields: { + name: { type: GraphQLString }, + }, +}); + +const config = User.toConfig(); +const UserCopy = new GraphQLObjectType(config); + +config.fields.name.type; // => GraphQLString +UserCopy.getFields().name.type; // => GraphQLString +``` + +
+ +##### toString() + +Returns the schema coordinate identifying this object type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema coordinate for this object type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertObjectType } from 'graphql/type'; + +const schema = buildSchema(` + type User { + name: String + } + + type Query { + viewer: User + } +`); + +const User = assertObjectType(schema.getType('User')); + +User.toString(); // => 'User' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { GraphQLObjectType, GraphQLString } from 'graphql/type'; + +const User = new GraphQLObjectType({ + name: 'User', + fields: { name: { type: GraphQLString } }, +}); + +User.toJSON(); // => 'User' +JSON.stringify({ type: User }); // => '{"type":"User"}' +``` + +
+ +#### GraphQLInterfaceType + +Interface Type Definition + +When a field can return one of a heterogeneous set of types, a Interface type +is used to describe what types are possible, what fields are in common across +all types, as well as a function to determine which type is actually used +when the field is resolved. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
+ +
+ +
Example
+ +```ts +const EntityType = new GraphQLInterfaceType({ + name: 'Entity', + fields: { + name: { type: GraphQLString } + } +}); +``` + +
+ +##### Constructor + +Creates a GraphQLInterfaceType instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
configConfiguration describing this object.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
resolveTypeFunction that resolves the concrete object type for this abstract type.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
extensionASTNodesAST extension nodes applied to this schema element.
+ +
+ +##### getFields() + +Returns the fields defined by this type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The fields keyed by field name.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInterfaceType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Query { + node: Node + } +`); + +const Node = assertInterfaceType(schema.getType('Node')); +const fields = Node.getFields(); + +Object.keys(fields); // => ['id'] +String(fields.id.type); // => 'ID!' +``` + +
+ +##### getInterfaces() + +Returns the interfaces implemented by this type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The implemented interfaces.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInterfaceType } from 'graphql/type'; + +const schema = buildSchema(` + interface Resource { + url: String! + } + + interface Image implements Resource { + url: String! + width: Int + } + + type Photo implements Resource & Image { + url: String! + width: Int + } + + type Query { + image: Image + } +`); + +const Image = assertInterfaceType(schema.getType('Image')); + +Image.getInterfaces().map((type) => type.name); // => ['Resource'] +``` + +
+ +##### toConfig() + +Returns a normalized configuration object for this object. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this object.
+ +
+ +
Example
+ +```ts +import { GraphQLID, GraphQLInterfaceType, GraphQLNonNull } from 'graphql/type'; + +const Node = new GraphQLInterfaceType({ + name: 'Node', + fields: { + id: { type: new GraphQLNonNull(GraphQLID) }, + }, +}); + +const config = Node.toConfig(); +const NodeCopy = new GraphQLInterfaceType(config); + +String(config.fields.id.type); // => 'ID!' +String(NodeCopy.getFields().id.type); // => 'ID!' +``` + +
+ +##### toString() + +Returns the schema coordinate identifying this interface type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema coordinate for this interface type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInterfaceType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Query { + node: Node + } +`); + +const Node = assertInterfaceType(schema.getType('Node')); + +Node.toString(); // => 'Node' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { GraphQLInterfaceType, GraphQLString } from 'graphql/type'; + +const Named = new GraphQLInterfaceType({ + name: 'Named', + fields: { name: { type: GraphQLString } }, +}); + +Named.toJSON(); // => 'Named' +JSON.stringify({ type: Named }); // => '{"type":"Named"}' +``` + +
+ +#### GraphQLUnionType + +Union Type Definition + +When a field can return one of a heterogeneous set of types, a Union type +is used to describe what types are possible as well as providing a function +to determine which type is actually used when the field is resolved. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
+ +
+ +
Example
+ +```ts +const PetType = new GraphQLUnionType({ + name: 'Pet', + types: [DogType, CatType], + resolveType: (value) => { + if (value instanceof Dog) { + return DogType; + } + if (value instanceof Cat) { + return CatType; + } + } +}); +``` + +
+ +##### Constructor + +Creates a GraphQLUnionType instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
configConfiguration describing this object.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
resolveTypeFunction that resolves the concrete object type for this abstract type.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
extensionASTNodesAST extension nodes applied to this schema element.
+ +
+ +##### getTypes() + +Returns the object types included in this union. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The union member object types.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertUnionType } from 'graphql/type'; + +const schema = buildSchema(` + type Photo { + url: String! + } + + type Video { + url: String! + } + + union Media = Photo | Video + + type Query { + media: [Media] + } +`); + +const Media = assertUnionType(schema.getType('Media')); + +Media.getTypes().map((type) => type.name); // => ['Photo', 'Video'] +``` + +
+ +##### toConfig() + +Returns a normalized configuration object for this object. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this object.
+ +
+ +
Example
+ +```ts +import { GraphQLObjectType, GraphQLString, GraphQLUnionType } from 'graphql/type'; + +const Photo = new GraphQLObjectType({ + name: 'Photo', + fields: { url: { type: GraphQLString } }, +}); +const Video = new GraphQLObjectType({ + name: 'Video', + fields: { url: { type: GraphQLString } }, +}); +const Media = new GraphQLUnionType({ + name: 'Media', + types: [Photo, Video], +}); + +const config = Media.toConfig(); +const MediaCopy = new GraphQLUnionType(config); + +MediaCopy.getTypes().map((type) => type.name); // => ['Photo', 'Video'] +``` + +
+ +##### toString() + +Returns the schema coordinate identifying this union type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema coordinate for this union type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertUnionType } from 'graphql/type'; + +const schema = buildSchema(` + type Photo { + url: String! + } + + union SearchResult = Photo + + type Query { + search: [SearchResult] + } +`); + +const SearchResult = assertUnionType(schema.getType('SearchResult')); + +SearchResult.toString(); // => 'SearchResult' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { GraphQLObjectType, GraphQLString, GraphQLUnionType } from 'graphql/type'; + +const Photo = new GraphQLObjectType({ + name: 'Photo', + fields: { url: { type: GraphQLString } }, +}); +const SearchResult = new GraphQLUnionType({ + name: 'SearchResult', + types: [Photo], +}); + +SearchResult.toJSON(); // => 'SearchResult' +JSON.stringify({ type: SearchResult }); // => '{"type":"SearchResult"}' +``` + +
+ +#### GraphQLEnumType + +Enum Type Definition + +Enum types define leaf values whose serialized form is one of a fixed set +of GraphQL enum names. Internally, enum values can map to any runtime value, +often integers. + +
+ +
Example
+ +```ts +import { GraphQLEnumType } from 'graphql/type'; + +const RGBType = new GraphQLEnumType({ + name: 'RGB', + values: { + RED: { value: 0 }, + GREEN: { value: 1 }, + BLUE: { value: 2 }, + }, +}); + +RGBType.getValue('GREEN')?.value; // => 1 +``` + +Note: If a value is not provided in a definition, the name of the enum value +will be used as its internal value. + +
+ +##### Constructor + +Creates a GraphQLEnumType instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
configConfiguration describing this object.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
extensionASTNodesAST extension nodes applied to this schema element.
+ +
+ +##### getValues() + +Returns the values defined by this enum type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Enum value definitions in schema order.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertEnumType } from 'graphql/type'; + +const schema = buildSchema(` + enum Episode { + NEW_HOPE + EMPIRE + JEDI + } + + type Query { + episode: Episode + } +`); + +const Episode = assertEnumType(schema.getType('Episode')); + +Episode.getValues().map((value) => value.name); // => ['NEW_HOPE', 'EMPIRE', 'JEDI'] +``` + +
+ +##### getValue() + +Returns the enum value definition for a value name. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name to look up.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The matching enum value definition, if it exists.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertEnumType } from 'graphql/type'; + +const schema = buildSchema(` + enum Episode { + NEW_HOPE + EMPIRE + } + + type Query { + episode: Episode + } +`); + +const Episode = assertEnumType(schema.getType('Episode')); + +Episode.getValue('EMPIRE')?.name; // => 'EMPIRE' +Episode.getValue('JEDI'); // => undefined +``` + +
+ +##### serialize() Deprecated + +Serializes a runtime enum value as a GraphQL enum name. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
outputValueRuntime enum value to serialize.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The GraphQL enum name for the runtime value.
+This deprecated method delegates to {"coerceOutputValue()"}; call
+{"coerceOutputValue()"} directly instead.
+ +
+ +
Example
+ +```ts +import { GraphQLEnumType } from 'graphql/type'; + +const RGB = new GraphQLEnumType({ + name: 'RGB', + values: { + RED: { value: 0 }, + GREEN: { value: 1 }, + BLUE: { value: 2 }, + }, +}); + +RGB.serialize(1); // => 'GREEN' +RGB.serialize(3); // throws an error +``` + +
+ +##### coerceOutputValue() + +Coerces a runtime enum value to a GraphQL enum name. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
outputValueRuntime enum value to coerce.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The GraphQL enum name for the runtime value.
+ +
+ +
Example
+ +```ts +import { GraphQLEnumType } from 'graphql/type'; + +const RGB = new GraphQLEnumType({ + name: 'RGB', + values: { + RED: { value: 0 }, + GREEN: { value: 1 }, + BLUE: { value: 2 }, + }, +}); + +RGB.coerceOutputValue(1); // => 'GREEN' +RGB.coerceOutputValue(3); // throws an error +``` + +
+ +##### parseValue() Deprecated + +Deprecated legacy enum parser for externally provided input values. Use +`coerceInputValue()` instead. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
inputValueExternal enum name to parse.
hideSuggestions?Whether suggestion text should be omitted from errors.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The internal runtime value for the enum name.
+ +
+ +
Example
+ +```ts +import { GraphQLEnumType } from 'graphql/type'; + +const RGB = new GraphQLEnumType({ + name: 'RGB', + values: { + RED: { value: 0 }, + GREEN: { value: 1 }, + BLUE: { value: 2 }, + }, +}); + +RGB.parseValue('BLUE'); // => 2 +RGB.parseValue('PURPLE', true); // throws an error +``` + +
+ +##### coerceInputValue() + +Coerces an external enum name to its internal runtime value. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
inputValueExternal enum name to coerce.
hideSuggestions?Whether suggestion text should be omitted from errors.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The internal runtime value for the enum name.
+ +
+ +
Example
+ +```ts +import { GraphQLEnumType } from 'graphql/type'; + +const RGB = new GraphQLEnumType({ + name: 'RGB', + values: { + RED: { value: 0 }, + GREEN: { value: 1 }, + BLUE: { value: 2 }, + }, +}); + +RGB.coerceInputValue('BLUE'); // => 2 +RGB.coerceInputValue('PURPLE'); // throws an error +RGB.coerceInputValue(2); // throws an error +``` + +
+ +##### parseLiteral() Deprecated + +Deprecated legacy enum parser for externally provided input literals. Use +`coerceInputLiteral()` instead. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
valueNodeEnum value AST node to parse.
_variablesDeprecated variable values parameter that is no longer used.
hideSuggestions?Whether suggestion text should be omitted from errors.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The internal runtime value for the enum literal.
+ +
+ +
Example
+ +```ts +import { parseValue } from 'graphql/language'; +import { GraphQLEnumType } from 'graphql/type'; + +const RGB = new GraphQLEnumType({ + name: 'RGB', + values: { + RED: { value: 0 }, + GREEN: { value: 1 }, + BLUE: { value: 2 }, + }, +}); + +RGB.parseLiteral(parseValue('RED')); // => 0 +RGB.parseLiteral(parseValue('"RED"')); // throws an error +``` + +
+ +##### coerceInputLiteral() + +Coerces an enum value AST node to its internal runtime value. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
valueNodeEnum value AST node to coerce.
hideSuggestions?Whether suggestion text should be omitted from errors.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The internal runtime value for the enum literal.
+ +
+ +
Example
+ +```ts +import { parseConstValue } from 'graphql/language'; +import { GraphQLEnumType } from 'graphql/type'; + +const RGB = new GraphQLEnumType({ + name: 'RGB', + values: { + RED: { value: 0 }, + GREEN: { value: 1 }, + BLUE: { value: 2 }, + }, +}); + +RGB.coerceInputLiteral(parseConstValue('RED')); // => 0 +RGB.coerceInputLiteral(parseConstValue('"RED"'), true); // throws an error +``` + +
+ +##### valueToLiteral() + +Converts a runtime enum value to a GraphQL enum value AST node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
valueRuntime enum value to convert.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Enum value AST node, or undefined if the value is invalid.
+ +
+ +
Example
+ +```ts +import { print } from 'graphql/language'; +import { GraphQLEnumType } from 'graphql/type'; + +const RGB = new GraphQLEnumType({ + name: 'RGB', + values: { + RED: { value: 0 }, + GREEN: { value: 1 }, + BLUE: { value: 2 }, + }, +}); + +print(RGB.valueToLiteral(2)); // => 'BLUE' +RGB.valueToLiteral(3); // => undefined +``` + +
+ +##### toConfig() + +Returns a normalized configuration object for this object. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this object.
+ +
+ +
Example
+ +```ts +import { GraphQLEnumType } from 'graphql/type'; + +const RGB = new GraphQLEnumType({ + name: 'RGB', + values: { + RED: { value: 0 }, + GREEN: { value: 1 }, + BLUE: { value: 2 }, + }, +}); + +const config = RGB.toConfig(); +const RGBCopy = new GraphQLEnumType(config); + +config.values.GREEN.value; // => 1 +RGBCopy.coerceOutputValue(2); // => 'BLUE' +``` + +
+ +##### toString() + +Returns the schema coordinate identifying this enum type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema coordinate for this enum type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertEnumType } from 'graphql/type'; + +const schema = buildSchema(` + enum Episode { + NEW_HOPE + } + + type Query { + episode: Episode + } +`); + +const Episode = assertEnumType(schema.getType('Episode')); + +Episode.toString(); // => 'Episode' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { GraphQLEnumType } from 'graphql/type'; + +const Episode = new GraphQLEnumType({ + name: 'Episode', + values: { + NEW_HOPE: {}, + }, +}); + +Episode.toJSON(); // => 'Episode' +JSON.stringify({ type: Episode }); // => '{"type":"Episode"}' +``` + +
+ +#### GraphQLInputObjectType + +Input Object Type Definition + +An input object defines a structured collection of fields which may be +supplied to a field argument. + +Using `NonNull` will ensure that a value must be provided by the query + +
+ +
Example
+ +```ts +const GeoPoint = new GraphQLInputObjectType({ + name: 'GeoPoint', + fields: { + lat: { type: new GraphQLNonNull(GraphQLFloat) }, + lon: { type: new GraphQLNonNull(GraphQLFloat) }, + alt: { type: GraphQLFloat, default: { value: 0 } }, + } +}); +``` + +
+ +##### Constructor + +Creates a GraphQLInputObjectType instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
configConfiguration describing this object.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
extensionASTNodesAST extension nodes applied to this schema element.
isOneOfWhether this input object uses the experimental OneOf input object semantics.
+ +
+ +##### getFields() + +Returns the fields defined by this type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The fields keyed by field name.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInputObjectType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + commentary: String = "" + } + + type Query { + reviews(filter: ReviewInput): [String] + } +`); + +const ReviewInput = assertInputObjectType(schema.getType('ReviewInput')); +const fields = ReviewInput.getFields(); + +Object.keys(fields); // => ['stars', 'commentary'] +fields.commentary.default; // => { literal: { kind: 'StringValue', value: '' } } +``` + +
+ +##### toConfig() + +Returns a normalized configuration object for this object. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this object.
+ +
+ +
Example
+ +```ts +import { + GraphQLInputObjectType, + GraphQLInt, + GraphQLNonNull, +} from 'graphql/type'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: { + stars: { type: new GraphQLNonNull(GraphQLInt) }, + }, +}); + +const config = ReviewInput.toConfig(); +const ReviewInputCopy = new GraphQLInputObjectType(config); + +String(config.fields.stars.type); // => 'Int!' +String(ReviewInputCopy.getFields().stars.type); // => 'Int!' +``` + +
+ +##### toString() + +Returns the schema coordinate identifying this input object type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema coordinate for this input object type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInputObjectType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + } + + type Query { + reviews(filter: ReviewInput): [String] + } +`); + +const ReviewInput = assertInputObjectType(schema.getType('ReviewInput')); + +ReviewInput.toString(); // => 'ReviewInput' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { GraphQLInputObjectType, GraphQLString } from 'graphql/type'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: { + commentary: { type: GraphQLString }, + }, +}); + +ReviewInput.toJSON(); // => 'ReviewInput' +JSON.stringify({ type: ReviewInput }); // => '{"type":"ReviewInput"}' +``` + +### Functions + +#### isType() + +Returns true when the value is any GraphQL type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is any GraphQL type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { GraphQLList, GraphQLString, isType } from 'graphql/type'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +isType(GraphQLString); // => true +isType(new GraphQLList(GraphQLString)); // => true +isType(schema.getType('Query')); // => true +isType('String'); // => false +``` + +
+ +#### assertType() + +Returns the value as a GraphQL type, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQL type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertType } from 'graphql/type'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const queryType = assertType(schema.getType('Query')); + +queryType.toString(); // => 'Query' +assertType('Query'); // throws an error +``` + +
+ +#### isScalarType() + +There are predicates for each kind of GraphQL type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLScalarType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isScalarType } from 'graphql/type'; + +const schema = buildSchema(` + scalar DateTime + + type Query { + createdAt: DateTime + } +`); + +isScalarType(schema.getType('DateTime')); // => true +isScalarType(schema.getType('Query')); // => false +``` + +
+ +#### assertScalarType() + +Returns the value as a GraphQLScalarType, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLScalarType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertScalarType } from 'graphql/type'; + +const schema = buildSchema(` + scalar DateTime + + type Query { + createdAt: DateTime + } +`); + +const dateTimeType = assertScalarType(schema.getType('DateTime')); + +dateTimeType.name; // => 'DateTime' +assertScalarType(schema.getType('Query')); // throws an error +``` + +
+ +#### isObjectType() + +Returns true when the value is a GraphQLObjectType. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLObjectType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isObjectType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + } + + type User { + name: String + } + + type Query { + user: User + } +`); + +isObjectType(schema.getType('User')); // => true +isObjectType(schema.getType('ReviewInput')); // => false +``` + +
+ +#### assertObjectType() + +Returns the value as a GraphQLObjectType, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLObjectType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertObjectType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + } + + type User { + name: String + } + + type Query { + user: User + } +`); + +const userType = assertObjectType(schema.getType('User')); + +Object.keys(userType.getFields()); // => ['name'] +assertObjectType(schema.getType('ReviewInput')); // throws an error +``` + +
+ +#### isField() + +Returns true when the value is a resolved GraphQL field definition. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
fieldValue to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLField.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isField } from 'graphql/type'; + +const schema = buildSchema('type Query { greeting: String }'); +const field = schema.getQueryType().getFields().greeting; + +isField(field); // => true +isField(schema.getQueryType()); // => false +``` + +
+ +#### assertField() + +Returns the value as a GraphQLField, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
fieldValue to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLField.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertField } from 'graphql/type'; + +const schema = buildSchema('type Query { greeting: String }'); +const field = assertField(schema.getQueryType().getFields().greeting); + +field.name; // => 'greeting' +assertField(schema.getQueryType()); // throws an error +``` + +
+ +#### isArgument() + +Returns true when the value is a resolved GraphQL argument definition. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
argValue to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLArgument.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isArgument } from 'graphql/type'; + +const schema = buildSchema('type Query { greeting(name: String): String }'); +const arg = schema.getQueryType().getFields().greeting.args[0]; + +isArgument(arg); // => true +isArgument(schema.getQueryType()); // => false +``` + +
+ +#### assertArgument() + +Returns the value as a GraphQLArgument, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
argValue to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLArgument.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertArgument } from 'graphql/type'; + +const schema = buildSchema('type Query { greeting(name: String): String }'); +const arg = assertArgument(schema.getQueryType().getFields().greeting.args[0]); + +arg.name; // => 'name' +assertArgument(schema.getQueryType()); // throws an error +``` + +
+ +#### isInterfaceType() + +Returns true when the value is a GraphQLInterfaceType. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLInterfaceType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isInterfaceType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Query { + node: Node + } +`); + +isInterfaceType(schema.getType('Node')); // => true +isInterfaceType(schema.getType('User')); // => false +``` + +
+ +#### assertInterfaceType() + +Returns the value as a GraphQLInterfaceType, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLInterfaceType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInterfaceType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Query { + node: Node + } +`); + +const nodeType = assertInterfaceType(schema.getType('Node')); + +nodeType.name; // => 'Node' +assertInterfaceType(schema.getType('User')); // throws an error +``` + +
+ +#### isUnionType() + +Returns true when the value is a GraphQLUnionType. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLUnionType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isUnionType } from 'graphql/type'; + +const schema = buildSchema(` + type Photo { + url: String! + } + + type Video { + url: String! + } + + union Media = Photo | Video + + type Query { + media: [Media] + } +`); + +isUnionType(schema.getType('Media')); // => true +isUnionType(schema.getType('Photo')); // => false +``` + +
+ +#### assertUnionType() + +Returns the value as a GraphQLUnionType, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLUnionType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertUnionType } from 'graphql/type'; + +const schema = buildSchema(` + type Photo { + url: String! + } + + type Video { + url: String! + } + + union Media = Photo | Video + + type Query { + media: [Media] + } +`); + +const mediaType = assertUnionType(schema.getType('Media')); + +mediaType.getTypes().map((type) => type.name); // => ['Photo', 'Video'] +assertUnionType(schema.getType('Photo')); // throws an error +``` + +
+ +#### isEnumType() + +Returns true when the value is a GraphQLEnumType. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLEnumType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isEnumType } from 'graphql/type'; + +const schema = buildSchema(` + enum Episode { + NEW_HOPE + EMPIRE + } + + type Query { + favoriteEpisode: Episode + } +`); + +isEnumType(schema.getType('Episode')); // => true +isEnumType(schema.getType('Query')); // => false +``` + +
+ +#### assertEnumType() + +Returns the value as a GraphQLEnumType, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLEnumType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertEnumType } from 'graphql/type'; + +const schema = buildSchema(` + enum Episode { + NEW_HOPE + EMPIRE + } + + type Query { + favoriteEpisode: Episode + } +`); + +const episodeType = assertEnumType(schema.getType('Episode')); + +episodeType.getValues().map((value) => value.name); // => ['NEW_HOPE', 'EMPIRE'] +assertEnumType(schema.getType('Query')); // throws an error +``` + +
+ +#### isEnumValue() + +Returns true when the value is a resolved GraphQL enum value definition. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
valueValue to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLEnumValue.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertEnumType, isEnumValue } from 'graphql/type'; + +const schema = buildSchema('enum Episode { NEW_HOPE } type Query { episode: Episode }'); +const enumValue = assertEnumType(schema.getType('Episode')).getValues()[0]; + +isEnumValue(enumValue); // => true +isEnumValue(schema.getType('Episode')); // => false +``` + +
+ +#### assertEnumValue() + +Returns the value as a GraphQLEnumValue, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
valueValue to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLEnumValue.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertEnumType, assertEnumValue } from 'graphql/type'; + +const schema = buildSchema('enum Episode { NEW_HOPE } type Query { episode: Episode }'); +const enumValue = assertEnumValue( + assertEnumType(schema.getType('Episode')).getValues()[0], +); + +enumValue.name; // => 'NEW_HOPE' +assertEnumValue(schema.getType('Episode')); // throws an error +``` + +
+ +#### isInputObjectType() + +Returns true when the value is a GraphQLInputObjectType. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLInputObjectType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isInputObjectType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + } + + type Review { + stars: Int! + } + + type Query { + review(input: ReviewInput): Review + } +`); + +isInputObjectType(schema.getType('ReviewInput')); // => true +isInputObjectType(schema.getType('Review')); // => false +``` + +
+ +#### assertInputObjectType() + +Returns the value as a GraphQLInputObjectType, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLInputObjectType.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInputObjectType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + } + + type Review { + stars: Int! + } + + type Query { + review(input: ReviewInput): Review + } +`); + +const inputType = assertInputObjectType(schema.getType('ReviewInput')); + +Object.keys(inputType.getFields()); // => ['stars'] +assertInputObjectType(schema.getType('Review')); // throws an error +``` + +
+ +#### isInputField() + +Returns true when the value is a resolved GraphQL input field definition. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
fieldValue to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLInputField.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInputObjectType, isInputField } from 'graphql/type'; + +const schema = buildSchema('input ReviewInput { stars: Int } type Query { ok: Boolean }'); +const inputField = assertInputObjectType(schema.getType('ReviewInput')).getFields().stars; + +isInputField(inputField); // => true +isInputField(schema.getQueryType()); // => false +``` + +
+ +#### assertInputField() + +Returns the value as a GraphQLInputField, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
fieldValue to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLInputField.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInputField, assertInputObjectType } from 'graphql/type'; + +const schema = buildSchema('input ReviewInput { stars: Int } type Query { ok: Boolean }'); +const inputField = assertInputField( + assertInputObjectType(schema.getType('ReviewInput')).getFields().stars, +); + +inputField.name; // => 'stars' +assertInputField(schema.getQueryType()); // throws an error +``` + +
+ +#### assertListType() + +Returns the value as a GraphQLList, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLList.
+ +
+ +
Example
+ +```ts +import { GraphQLList, GraphQLString, assertListType } from 'graphql/type'; + +const listType = assertListType(new GraphQLList(GraphQLString)); + +listType.ofType; // => GraphQLString +assertListType(GraphQLString); // throws an error +``` + +
+ +#### assertNonNullType() + +Returns the value as a GraphQLNonNull, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLNonNull.
+ +
+ +
Example
+ +```ts +import { GraphQLNonNull, GraphQLString, assertNonNullType } from 'graphql/type'; + +const nonNullType = assertNonNullType(new GraphQLNonNull(GraphQLString)); + +nonNullType.ofType; // => GraphQLString +assertNonNullType(GraphQLString); // throws an error +``` + +
+ +#### isInputType() + +Returns true when the value can be used as a GraphQL input type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value can be used as a GraphQL input type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isInputType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + } + + type Review { + stars: Int! + } + + type Query { + review(input: ReviewInput): Review + } +`); + +isInputType(schema.getType('ReviewInput')); // => true +isInputType(schema.getType('Review')); // => false +``` + +
+ +#### assertInputType() + +Returns the value as a GraphQL input type, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQL input type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInputType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + } + + type Review { + stars: Int! + } + + type Query { + review(input: ReviewInput): Review + } +`); + +const inputType = assertInputType(schema.getType('ReviewInput')); + +inputType.toString(); // => 'ReviewInput' +assertInputType(schema.getType('Review')); // throws an error +``` + +
+ +#### isOutputType() + +Returns true when the value can be used as a GraphQL output type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value can be used as a GraphQL output type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isOutputType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + } + + type Review { + stars: Int! + } + + type Query { + review(input: ReviewInput): Review + } +`); + +isOutputType(schema.getType('Review')); // => true +isOutputType(schema.getType('ReviewInput')); // => false +``` + +
+ +#### assertOutputType() + +Returns the value as a GraphQL output type, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQL output type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertOutputType } from 'graphql/type'; + +const schema = buildSchema(` + input ReviewInput { + stars: Int! + } + + type Review { + stars: Int! + } + + type Query { + review(input: ReviewInput): Review + } +`); + +const outputType = assertOutputType(schema.getType('Review')); + +outputType.toString(); // => 'Review' +assertOutputType(schema.getType('ReviewInput')); // throws an error +``` + +
+ +#### isLeafType() + +Returns true when the value is a GraphQL scalar or enum type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQL scalar or enum type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isLeafType } from 'graphql/type'; + +const schema = buildSchema(` + enum Episode { + NEW_HOPE + } + + type Review { + stars: Int! + } + + type Query { + episode: Episode + review: Review + } +`); + +isLeafType(schema.getType('Episode')); // => true +isLeafType(schema.getType('String')); // => true +isLeafType(schema.getType('Review')); // => false +``` + +
+ +#### assertLeafType() + +Returns the value as a GraphQL leaf type, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQL leaf type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertLeafType } from 'graphql/type'; + +const schema = buildSchema(` + enum Episode { + NEW_HOPE + } + + type Review { + stars: Int! + } + + type Query { + episode: Episode + review: Review + } +`); + +const episodeType = assertLeafType(schema.getType('Episode')); + +episodeType.toString(); // => 'Episode' +assertLeafType(schema.getType('Review')); // throws an error +``` + +
+ +#### isCompositeType() + +Returns true when the value is a GraphQL object, interface, or union type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQL object, interface, or union type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isCompositeType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + union SearchResult = User + + type Query { + node: Node + search: [SearchResult] + } +`); + +isCompositeType(schema.getType('User')); // => true +isCompositeType(schema.getType('Node')); // => true +isCompositeType(schema.getType('SearchResult')); // => true +isCompositeType(schema.getType('String')); // => false +``` + +
+ +#### assertCompositeType() + +Returns the value as a GraphQL composite type, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQL composite type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertCompositeType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Query { + node: Node + } +`); + +const userType = assertCompositeType(schema.getType('User')); + +userType.toString(); // => 'User' +assertCompositeType(schema.getType('String')); // throws an error +``` + +
+ +#### isAbstractType() + +Returns true when the value is a GraphQL interface or union type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQL interface or union type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { isAbstractType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + union SearchResult = User + + type Query { + node: Node + search: [SearchResult] + } +`); + +isAbstractType(schema.getType('Node')); // => true +isAbstractType(schema.getType('SearchResult')); // => true +isAbstractType(schema.getType('User')); // => false +``` + +
+ +#### assertAbstractType() + +Returns the value as a GraphQL abstract type, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQL abstract type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertAbstractType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Query { + node: Node + } +`); + +const nodeType = assertAbstractType(schema.getType('Node')); + +nodeType.toString(); // => 'Node' +assertAbstractType(schema.getType('User')); // throws an error +``` + +
+ +#### isWrappingType() + +Returns true when the value is a GraphQL list or non-null wrapper type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQL list or non-null wrapper type.
+ +
+ +
Example
+ +```ts +import { + GraphQLList, + GraphQLNonNull, + GraphQLString, + isWrappingType, +} from 'graphql/type'; + +isWrappingType(new GraphQLList(GraphQLString)); // => true +isWrappingType(new GraphQLNonNull(GraphQLString)); // => true +isWrappingType(GraphQLString); // => false +``` + +
+ +#### assertWrappingType() + +Returns the value as a GraphQL wrapping type, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQL wrapping type.
+ +
+ +
Example
+ +```ts +import { GraphQLList, GraphQLString, assertWrappingType } from 'graphql/type'; + +const wrappingType = assertWrappingType(new GraphQLList(GraphQLString)); + +wrappingType.toString(); // => '[String]' +assertWrappingType(GraphQLString); // throws an error +``` + +
+ +#### isNullableType() + +Returns true when the value is a GraphQL type that can accept null. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQL type that can accept null.
+ +
+ +
Example
+ +```ts +import { GraphQLNonNull, GraphQLString, isNullableType } from 'graphql/type'; + +isNullableType(GraphQLString); // => true +isNullableType(new GraphQLNonNull(GraphQLString)); // => false +isNullableType(null); // => false +``` + +
+ +#### assertNullableType() + +Returns the value as a nullable GraphQL type, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a nullable GraphQL type.
+ +
+ +
Example
+ +```ts +import { + GraphQLNonNull, + GraphQLString, + assertNullableType, +} from 'graphql/type'; + +const nullableType = assertNullableType(GraphQLString); + +nullableType; // => GraphQLString +assertNullableType(new GraphQLNonNull(GraphQLString)); // throws an error +``` + +
+ +#### isNamedType() + +Returns true when the value is a GraphQL named type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQL named type.
+ +
+ +
Example
+ +```ts +import { GraphQLList, GraphQLString, isNamedType } from 'graphql/type'; + +isNamedType(GraphQLString); // => true +isNamedType(new GraphQLList(GraphQLString)); // => false +isNamedType(null); // => false +``` + +
+ +#### assertNamedType() + +Returns the value as a GraphQL named type, or throws if it is not one. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQL named type.
+ +
+ +
Example
+ +```ts +import { GraphQLList, GraphQLString, assertNamedType } from 'graphql/type'; + +const namedType = assertNamedType(GraphQLString); + +namedType.name; // => 'String' +assertNamedType(new GraphQLList(GraphQLString)); // throws an error +``` + +
+ +#### resolveReadonlyArrayThunk() + +Resolves a thunked readonly array. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TThe element type resolved from the thunk or array.
+ +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
thunkThe thunk or value to resolve.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The resolved readonly array.
+ +
+ +
Example
+ +```ts +import { GraphQLString, resolveReadonlyArrayThunk } from 'graphql/type'; + +const lazyFields = resolveReadonlyArrayThunk(() => [GraphQLString]); +const fields = resolveReadonlyArrayThunk([GraphQLString]); + +lazyFields; // => [GraphQLString] +fields; // => [GraphQLString] +``` + +
+ +#### resolveObjMapThunk() + +Resolves a thunked object map. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TThe object-map value type resolved from the thunk or map.
+ +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
thunkThe thunk or value to resolve.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The resolved object map.
+ +
+ +
Example
+ +```ts +import { GraphQLString, resolveObjMapThunk } from 'graphql/type'; + +const lazyFields = resolveObjMapThunk(() => ({ name: GraphQLString })); +const fields = resolveObjMapThunk({ name: GraphQLString }); + +lazyFields.name; // => GraphQLString +fields.name; // => GraphQLString +``` + +
+ +#### isRequiredArgument() + +Returns true when the argument is non-null and has no default value. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
argThe argument definition to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the argument is non-null and has no default value.
+ +
+ +
Example
+ +```ts +import { + GraphQLArgument, + GraphQLField, + GraphQLInt, + GraphQLNonNull, + GraphQLObjectType, + GraphQLString, + isRequiredArgument, +} from 'graphql/type'; + +const Query = new GraphQLObjectType({ name: 'Query', fields: {} }); +const field = new GraphQLField(Query, 'reviews', { type: GraphQLString }); +const requiredArgument = new GraphQLArgument(field, 'id', { + type: new GraphQLNonNull(GraphQLInt), +}); +const optionalArgument = new GraphQLArgument(field, 'name', { + type: GraphQLString, +}); +const argumentWithDefault = new GraphQLArgument(field, 'limit', { + type: new GraphQLNonNull(GraphQLInt), + default: { value: 10 }, +}); + +isRequiredArgument(requiredArgument); // => true +isRequiredArgument(optionalArgument); // => false +isRequiredArgument(argumentWithDefault); // => false +``` + +
+ +#### isRequiredInputField() + +Returns true when the input field is non-null and has no default value. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
fieldThe input field definition to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the input field is non-null and has no default value.
+ +
+ +
Example
+ +```ts +import { + GraphQLInputField, + GraphQLInputObjectType, + GraphQLInt, + GraphQLNonNull, + GraphQLString, + isRequiredInputField, +} from 'graphql/type'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: {}, +}); +const requiredField = new GraphQLInputField(ReviewInput, 'id', { + type: new GraphQLNonNull(GraphQLInt), +}); +const optionalField = new GraphQLInputField(ReviewInput, 'name', { + type: GraphQLString, +}); +const fieldWithDefault = new GraphQLInputField(ReviewInput, 'limit', { + type: new GraphQLNonNull(GraphQLInt), + default: { value: 10 }, +}); + +isRequiredInputField(requiredField); // => true +isRequiredInputField(optionalField); // => false +isRequiredInputField(fieldWithDefault); // => false +``` + +### Types + +#### GraphQLType + +**Type alias.** These are all of the possible kinds of types. + + + +
+ +#### GraphQLNullableInputType + +**Type alias.** These types may be used as input types for arguments and directives. + + + +
+ +#### GraphQLInputType + +**Type alias.** These types may be used as input types for arguments and directives. + + + +
+ +#### GraphQLNullableOutputType + +**Type alias.** These types may be used as output types as the result of fields. + + + +
+ +#### GraphQLOutputType + +**Type alias.** These types may be used as output types as the result of fields. + + + +
+ +#### GraphQLLeafType + +**Type alias.** These types may describe types which may be leaf values. + + + +
+ +#### GraphQLCompositeType + +**Type alias.** These types may describe the parent context of a selection set. + + + +
+ +#### GraphQLAbstractType + +**Type alias.** These types may describe the parent context of a selection set. + + + +
+ +#### GraphQLWrappingType + +**Type alias.** These types wrap and modify other types + + + +
+ +#### GraphQLNullableType + +**Type alias.** These types can all accept null as a value. + + + +
+ +#### GraphQLNamedType + +**Type alias.** These named types do not include modifiers like List or NonNull. + + + +
+ +#### GraphQLNamedInputType + +**Type alias.** A named GraphQL type that can be used as an input type. + + + +
+ +#### GraphQLNamedOutputType + +**Type alias.** A named GraphQL type that can be used as an output type. + + + +
+ +#### ThunkReadonlyArray + +**Type alias.** Used while defining GraphQL types to allow for circular references in +otherwise immutable type definitions. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TThe element type returned by the thunk or array.
+ + + +
+ +#### ThunkObjMap + +**Type alias.** A thunk that resolves to an object map. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TValue type stored in the object map.
+ + + +
+ +#### GraphQLScalarTypeExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLScalarSerializer Deprecated + +**Type alias.** Deprecated function type that serializes a runtime value as a scalar output +value. Use [`GraphQLScalarOutputValueCoercer`](/api-v17/type#graphqlscalaroutputvaluecoercer) instead. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TExternalExternal representation accepted from or returned to callers.
+ + + +
+ +#### GraphQLScalarOutputValueCoercer + +**Type alias.** Function used to coerce internal scalar values for response output. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TExternalExternal representation accepted from or returned to callers.
+ + + +
+ +#### GraphQLScalarValueParser Deprecated + +**Type alias.** Deprecated function type that parses a runtime input value as a scalar input +value. Use [`GraphQLScalarInputValueCoercer`](/api-v17/type#graphqlscalarinputvaluecoercer) instead. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TInternalInternal runtime representation for this scalar.
+ + + +
+ +#### GraphQLScalarInputValueCoercer + +**Type alias.** Function used to coerce externally provided scalar input values. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TInternalInternal runtime representation for this scalar.
+ + + +
+ +#### GraphQLScalarLiteralParser Deprecated + +**Type alias.** Deprecated function type that parses a GraphQL value literal as a scalar +input value. Use [`GraphQLScalarInputLiteralCoercer`](/api-v17/type#graphqlscalarinputliteralcoercer) instead. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TInternalInternal runtime representation for this scalar.
+ + + +
+ +#### GraphQLScalarInputLiteralCoercer + +**Type alias.** Function used to coerce GraphQL scalar input literals. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TInternalInternal runtime representation for this scalar.
+ + + +
+ +#### GraphQLScalarTypeConfig + +**Interface.** Configuration used to construct a GraphQLScalarType. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TInternalInternal runtime representation for this scalar.
TExternalExternal representation accepted from or returned to callers.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
specifiedByURL?URL identifying the behavior specified for this custom scalar.
serialize?Deprecated legacy serializer used to convert internal values for response
+output. Use {"coerceOutputValue()"} instead.
parseValue?Deprecated legacy parser used to convert externally provided input values.
+Use {"coerceInputValue()"} instead.
parseLiteral?Deprecated legacy parser used to convert externally provided input
+literals. Use {"replaceVariables()"} and {"coerceInputLiteral()"} instead.
coerceOutputValue?Coerces an internal value to include in a response.
coerceInputValue?Coerces an externally provided value to use as an input.
coerceInputLiteral?Coerces an externally provided const literal value to use as an input.
valueToLiteral?Translates an externally provided value to a literal (AST).
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
extensionASTNodes?AST extension nodes applied to this schema element.
+ +
+ +#### GraphQLObjectTypeExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. +We've provided these template arguments because this is an open type and +you may find them useful. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
_TSourceReserved source type parameter for extension typing.
_TContextReserved context type parameter for extension typing.
+ +
+ +#### GraphQLObjectTypeConfig + +**Interface.** Configuration used to construct a GraphQLObjectType. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
TAbstractRuntime value type used for abstract type resolution.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
interfaces?Interfaces implemented by this object or interface type.
fieldsFields declared by this object, interface, input object, or literal.
isTypeOf?Predicate used to determine whether a runtime value belongs to this object type.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
extensionASTNodes?AST extension nodes applied to this schema element.
+ +
+ +#### GraphQLTypeResolver + +**Type alias.** Resolves the concrete object type for an abstract GraphQL type. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
+ + + +
+ +#### GraphQLIsTypeOfFn + +**Type alias.** Checks whether a runtime value belongs to a GraphQL object type. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TAbstractRuntime value type used for abstract type resolution.
TContextContext object type passed to resolvers.
+ + + +
+ +#### GraphQLFieldResolver + +**Type alias.** Resolves the runtime value for a GraphQL field. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
TArgsArgument object type passed to resolvers.
TResultResult value type.
+ + + +
+ +#### GraphQLResolveInfoHelpers + +**Interface.** Utilities available from resolver info for tracking asynchronous work. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
promiseAllPromise.all wrapper that allows rejected branches to be tracked
+as execution async work.
+Intended use: return or await this promise from resolver work.
+Un-awaited async side effects are an anti-pattern:
+ const { promiseAll } = info.getAsyncHelpers();
+ promiseAll([someAsyncWork(), someOtherAsyncWork()]).catch(() => undefined);
+In that anti-pattern, tracking starts only after rejection (on a
+later microtask), so this work is not guaranteed to delay
+{"hooks.asyncWorkFinished"}.
+Use {"track(...)"} for un-awaited async side effects:
+ const { track } = info.getAsyncHelpers();
+ track([
+ someAsyncWork().catch(() => undefined),
+ someOtherAsyncWork().catch(() => undefined)
+ ]);
trackTracks asynchronous work that should delay execution completion hooks.
+ +
+ +#### GraphQLResolveInfo + +**Interface.** Information about the currently executing GraphQL field. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
fieldNameThe field name referenced by this schema coordinate.
fieldNodesAST field nodes that contributed to the current field execution.
returnTypeGraphQL output type declared for the current field.
parentTypeObject type that owns the current field.
pathResponse path where this error occurred during execution.
schemaThe schema used for validation or execution.
fragmentsFragment definitions in the operation document keyed by fragment name.
rootValueInitial root value passed to the operation.
operationThe operation selected for execution.
variableValuesCoerced variable values and source metadata for this operation. Resolver
+code that needs runtime variable values should read {"variableValues.coerced"}.
getAbortSignalReturns the AbortSignal supplied for this execution, if any.
getAsyncHelpersReturns helper functions for tracking asynchronous resolver work.
+ +
+ +#### GraphQLFieldExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. +We've provided these template arguments because this is an open type and +you may find them useful. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
_TSourceReserved source type parameter for extension typing.
_TContextReserved context type parameter for extension typing.
_TArgsReserved argument type parameter for extension typing.
+ +
+ +#### GraphQLFieldConfig + +**Interface.** Configuration used to define a GraphQL field. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
TArgsArgument object type passed to resolvers.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
description?Human-readable description for this schema element, if provided.
typeThe GraphQL type reference or runtime type for this element.
args?Arguments accepted by this field or directive.
resolve?Resolver function used to produce this field value.
subscribe?Resolver function used to create a subscription event stream for this field.
deprecationReason?Reason this element is deprecated, if one was provided.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
+ +
+ +#### GraphQLFieldConfigArgumentMap + +**Type alias.** A map of argument names to argument configuration objects. + + + +
+ +#### GraphQLArgumentExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLArgumentConfig + +**Interface.** Configuration used to define a GraphQL argument. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
description?Human-readable description for this schema element, if provided.
typeThe GraphQL type reference or runtime type for this element.
defaultValue?Deprecated legacy default value for this argument. Use {"default"} instead.
default?Default value represented as either a runtime value or a GraphQL literal.
deprecationReason?Reason this element is deprecated, if one was provided.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
+ +
+ +#### GraphQLFieldConfigMap + +**Type alias.** A map of field names to field configuration objects. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
+ + + +
+ +#### GraphQLField + +**Interface.** A resolved GraphQL field definition. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
TArgsArgument object type passed to resolvers.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
parentTypeObject or interface type that owns this field, if known.
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
typeThe GraphQL type reference or runtime type for this element.
argsArguments accepted by this field or directive.
resolve?Resolver function used to produce this field value.
subscribe?Resolver function used to create a subscription event stream for this field.
deprecationReasonReason this element is deprecated, if one was provided.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
+ +
+ +##### toConfig() + +Returns a normalized configuration object for this field. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this field.
+ +
+ +
Example
+ +```ts +import { GraphQLField, GraphQLObjectType, GraphQLString } from 'graphql/type'; + +const Query = new GraphQLObjectType({ name: 'Query', fields: {} }); +const field = new GraphQLField(Query, 'greeting', { + type: GraphQLString, + extensions: { cacheSeconds: 60 }, +}); + +field.toConfig().type; // => GraphQLString +field.toConfig().extensions; // => { cacheSeconds: 60 } +``` + +
+ +##### toString() + +Returns this field as a schema coordinate string. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The field coordinate.
+ +
+ +
Example
+ +```ts +import { GraphQLField, GraphQLObjectType, GraphQLString } from 'graphql/type'; + +const Query = new GraphQLObjectType({ name: 'Query', fields: {} }); +const field = new GraphQLField(Query, 'greeting', { type: GraphQLString }); + +field.toString(); // => 'Query.greeting' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The field coordinate.
+ +
+ +
Example
+ +```ts +import { GraphQLField, GraphQLObjectType, GraphQLString } from 'graphql/type'; + +const Query = new GraphQLObjectType({ name: 'Query', fields: {} }); +const field = new GraphQLField(Query, 'greeting', { type: GraphQLString }); + +JSON.stringify(field); // => '"Query.greeting"' +``` + +
+ +#### GraphQLArgument + +**Interface.** A resolved GraphQL argument definition. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
parentField or directive that owns this argument.
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
typeThe GraphQL type reference or runtime type for this element.
defaultValueDeprecated legacy default value used when no explicit value is supplied.
+Use {"default"} instead.
defaultDefault value represented as either a runtime value or a GraphQL literal.
deprecationReasonReason this element is deprecated, if one was provided.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
+ +
+ +##### toConfig() + +Returns a normalized configuration object for this argument. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this argument.
+ +
+ +
Example
+ +```ts +import { + GraphQLArgument, + GraphQLField, + GraphQLObjectType, + GraphQLString, +} from 'graphql/type'; + +const Query = new GraphQLObjectType({ name: 'Query', fields: {} }); +const field = new GraphQLField(Query, 'greeting', { type: GraphQLString }); +const arg = new GraphQLArgument(field, 'name', { + type: GraphQLString, + default: { value: 'world' }, +}); + +arg.toConfig().default.value; // => 'world' +``` + +
+ +##### toString() + +Returns this argument as a schema coordinate string. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The argument coordinate.
+ +
+ +
Example
+ +```ts +import { + GraphQLArgument, + GraphQLField, + GraphQLObjectType, + GraphQLString, +} from 'graphql/type'; + +const Query = new GraphQLObjectType({ name: 'Query', fields: {} }); +const field = new GraphQLField(Query, 'greeting', { type: GraphQLString }); +const arg = new GraphQLArgument(field, 'name', { type: GraphQLString }); + +arg.toString(); // => 'Query.greeting(name:)' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The argument coordinate.
+ +
+ +
Example
+ +```ts +import { + GraphQLArgument, + GraphQLField, + GraphQLObjectType, + GraphQLString, +} from 'graphql/type'; + +const Query = new GraphQLObjectType({ name: 'Query', fields: {} }); +const field = new GraphQLField(Query, 'greeting', { type: GraphQLString }); +const arg = new GraphQLArgument(field, 'name', { type: GraphQLString }); + +JSON.stringify(arg); // => '"Query.greeting(name:)"' +``` + +
+ +#### GraphQLFieldMap + +**Type alias.** A map of field names to resolved field definitions. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
+ + + +
+ +#### GraphQLDefaultInput + +**Type alias.** Default input represented as either a runtime value or a GraphQL literal. + + + +
+ +#### GraphQLInterfaceTypeExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLInterfaceTypeConfig + +**Interface.** Configuration used to construct a GraphQLInterfaceType. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
interfaces?Interfaces implemented by this object or interface type.
fieldsFields declared by this object, interface, input object, or literal.
resolveType?Optionally provide a custom type resolver function. If one is not provided,
+the default implementation will call {"isTypeOf"} on each implementing
+Object type.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
extensionASTNodes?AST extension nodes applied to this schema element.
+ +
+ +#### GraphQLUnionTypeExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLUnionTypeConfig + +**Interface.** Configuration used to construct a GraphQLUnionType. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TSourceSource object type passed to resolvers.
TContextContext object type passed to resolvers.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
typesObject types that belong to this union type.
resolveType?Optionally provide a custom type resolver function. If one is not provided,
+the default implementation will call {"isTypeOf"} on each implementing
+Object type.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
extensionASTNodes?AST extension nodes applied to this schema element.
+ +
+ +#### GraphQLEnumTypeExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLEnumTypeConfig + +**Interface.** Configuration used to construct a GraphQLEnumType. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
valuesValues contained in this enum, list, or input-object definition.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
extensionASTNodes?AST extension nodes applied to this schema element.
+ +
+ +#### GraphQLEnumValueConfigMap + +**Type alias.** A map of enum value names to enum value configuration objects. + + + +
+ +#### GraphQLEnumValueExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLEnumValueConfig + +**Interface.** Configuration used to define a GraphQL enum value. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
description?Human-readable description for this schema element, if provided.
value?Parsed value represented by this node.
deprecationReason?Reason this element is deprecated, if one was provided.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
+ +
+ +#### GraphQLEnumValue + +**Interface.** A resolved GraphQL enum value definition. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
parentEnumEnum type that owns this enum value.
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
valueParsed value represented by this node.
deprecationReasonReason this element is deprecated, if one was provided.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
+ +
+ +##### toConfig() + +Returns a normalized configuration object for this enum value. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this enum value.
+ +
+ +
Example
+ +```ts +import { GraphQLEnumType, GraphQLEnumValue } from 'graphql/type'; + +const Episode = new GraphQLEnumType({ + name: 'Episode', + values: { NEW_HOPE: { value: 4 } }, +}); +const enumValue = new GraphQLEnumValue(Episode, 'EMPIRE', { + value: 5, + extensions: { trilogy: 'original' }, +}); + +enumValue.toConfig(); // => { description: undefined, value: 5, deprecationReason: undefined, extensions: { trilogy: 'original' }, astNode: undefined } +``` + +
+ +##### toString() + +Returns this enum value as a schema coordinate string. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Enum value coordinate.
+ +
+ +
Example
+ +```ts +import { GraphQLEnumType, GraphQLEnumValue } from 'graphql/type'; + +const Episode = new GraphQLEnumType({ + name: 'Episode', + values: { NEW_HOPE: { value: 4 } }, +}); +const enumValue = new GraphQLEnumValue(Episode, 'EMPIRE', { value: 5 }); + +enumValue.toString(); // => 'Episode.EMPIRE' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Enum value coordinate.
+ +
+ +
Example
+ +```ts +import { GraphQLEnumType, GraphQLEnumValue } from 'graphql/type'; + +const Episode = new GraphQLEnumType({ + name: 'Episode', + values: { NEW_HOPE: { value: 4 } }, +}); +const enumValue = new GraphQLEnumValue(Episode, 'EMPIRE', { value: 5 }); + +JSON.stringify(enumValue); // => '"Episode.EMPIRE"' +``` + +
+ +#### GraphQLInputObjectTypeExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLInputObjectTypeConfig + +**Interface.** Configuration used to construct a GraphQLInputObjectType. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
fieldsFields declared by this object, interface, input object, or literal.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
extensionASTNodes?AST extension nodes applied to this schema element.
isOneOf?Whether this input object uses the experimental OneOf input object semantics.
+ +
+ +#### GraphQLInputFieldExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLInputFieldConfig + +**Interface.** Configuration used to define a GraphQL input field. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
description?Human-readable description for this schema element, if provided.
typeThe GraphQL type reference or runtime type for this element.
defaultValue?Deprecated legacy default value for this input field. Use {"default"}
+instead.
default?Default value represented as either a runtime value or a GraphQL literal.
deprecationReason?Reason this element is deprecated, if one was provided.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
+ +
+ +#### GraphQLInputFieldConfigMap + +**Type alias.** A map of input field names to input field configuration objects. + + + +
+ +#### GraphQLInputField + +**Interface.** A resolved GraphQL input field definition. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
parentTypeInput object type that owns this input field.
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
typeThe GraphQL type reference or runtime type for this element.
defaultValueDeprecated legacy default value used when no explicit value is supplied.
+Use {"default"} instead.
defaultDefault value represented as either a runtime value or a GraphQL literal.
deprecationReasonReason this element is deprecated, if one was provided.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
+ +
+ +##### toConfig() + +Returns a normalized configuration object for this input field. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this input field.
+ +
+ +
Example
+ +```ts +import { GraphQLInputField, GraphQLInputObjectType, GraphQLString } from 'graphql/type'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: {}, +}); +const field = new GraphQLInputField(ReviewInput, 'commentary', { + type: GraphQLString, + extensions: { form: 'review' }, +}); + +field.toConfig().extensions; // => { form: 'review' } +``` + +
+ +##### toString() + +Returns this input field as a schema coordinate string. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The input field coordinate.
+ +
+ +
Example
+ +```ts +import { GraphQLInputField, GraphQLInputObjectType, GraphQLString } from 'graphql/type'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: {}, +}); +const field = new GraphQLInputField(ReviewInput, 'commentary', { + type: GraphQLString, +}); + +field.toString(); // => 'ReviewInput.commentary' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The input field coordinate.
+ +
+ +
Example
+ +```ts +import { GraphQLInputField, GraphQLInputObjectType, GraphQLString } from 'graphql/type'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: {}, +}); +const field = new GraphQLInputField(ReviewInput, 'commentary', { + type: GraphQLString, +}); + +JSON.stringify(field); // => '"ReviewInput.commentary"' +``` + +
+ +#### GraphQLInputFieldMap + +**Type alias.** A map of input field names to resolved input field definitions. + + + +## Category: Directives + + + +### Classes + +#### GraphQLDirective + +Directives are used by the GraphQL runtime as a way of modifying execution +behavior. Type system creators will usually not create these directly. + +
+ +##### Constructor + +Creates a GraphQLDirective instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
configConfiguration describing this object.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
descriptionHuman-readable description for this schema element, if provided.
locationsLocations where this directive may be applied.
argsArguments accepted by this field or directive.
isRepeatableWhether this directive may appear more than once at the same location.
deprecationReasonReason this element is deprecated, if one was provided.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
extensionASTNodesAST extension nodes applied to this schema element.
+ +
+ +##### toConfig() + +Returns a normalized configuration object for this object. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this object.
+ +
+ +
Example
+ +```ts +import { DirectiveLocation } from 'graphql/language'; +import { GraphQLDirective, GraphQLString } from 'graphql/type'; + +const tag = new GraphQLDirective({ + name: 'tag', + locations: [DirectiveLocation.FIELD_DEFINITION], + args: { + name: { type: GraphQLString }, + }, +}); + +const config = tag.toConfig(); +const tagCopy = new GraphQLDirective(config); + +config.args.name.type; // => GraphQLString +tagCopy.args[0].name; // => 'name' +``` + +
+ +##### toString() + +Returns the schema coordinate identifying this directive. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The directive schema coordinate.
+ +
+ +
Example
+ +```ts +import { DirectiveLocation } from 'graphql/language'; +import { GraphQLDirective } from 'graphql/type'; + +const tag = new GraphQLDirective({ + name: 'tag', + locations: [DirectiveLocation.FIELD_DEFINITION], +}); + +tag.toString(); // => '@tag' +``` + +
+ +##### toJSON() + +Returns the JSON representation used when this object is serialized. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The JSON-serializable representation.
+ +
+ +
Example
+ +```ts +import { DirectiveLocation } from 'graphql/language'; +import { GraphQLDirective } from 'graphql/type'; + +const tag = new GraphQLDirective({ + name: 'tag', + locations: [DirectiveLocation.FIELD_DEFINITION], +}); + +tag.toJSON(); // => '@tag' +JSON.stringify({ directive: tag }); // => '{"directive":"@tag"}' +``` + +### Functions + +#### isDirective() + +Test if the given value is a GraphQL directive. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
directiveValue to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLDirective.
+ +
+ +
Example
+ +```ts +import { DirectiveLocation } from 'graphql/language'; +import { GraphQLDirective, GraphQLString, isDirective } from 'graphql/type'; + +const upper = new GraphQLDirective({ + name: 'upper', + locations: [DirectiveLocation.FIELD_DEFINITION], +}); + +isDirective(upper); // => true +isDirective(GraphQLString); // => false +``` + +
+ +#### assertDirective() + +Returns the value as a GraphQLDirective, or throws if it is not a directive. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
directiveValue to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLDirective.
+ +
+ +
Example
+ +```ts +import { DirectiveLocation } from 'graphql/language'; +import { assertDirective, GraphQLDirective, GraphQLString } from 'graphql/type'; + +const upper = new GraphQLDirective({ + name: 'upper', + locations: [DirectiveLocation.FIELD_DEFINITION], +}); + +assertDirective(upper); // => upper +assertDirective(GraphQLString); // throws an error +``` + +
+ +#### isSpecifiedDirective() + +Returns true when the directive is one of the directives specified by GraphQL. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
directiveDirective to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the directive is specified by GraphQL.
+ +
+ +
Example
+ +```ts +import { + GraphQLDirective, + GraphQLIncludeDirective, + isSpecifiedDirective, +} from 'graphql/type'; +import { DirectiveLocation } from 'graphql/language'; + +const customDirective = new GraphQLDirective({ + name: 'auth', + locations: [DirectiveLocation.FIELD_DEFINITION], +}); + +isSpecifiedDirective(GraphQLIncludeDirective); // => true +isSpecifiedDirective(customDirective); // => false +``` + +### Constants + +#### GraphQLIncludeDirective + +Used to conditionally include fields or fragments. + +
+ +
Type
+ + + +
+ +#### GraphQLSkipDirective + +Used to conditionally skip (exclude) fields or fragments. + +
+ +
Type
+ + + +
+ +#### GraphQLDeferDirective + +Experimental directive used to conditionally defer fragments. + +This directive is exported for schemas that explicitly opt in to incremental +delivery. It is not included in [`specifiedDirectives`](/api-v17/type#specifieddirectives). + +
+ +
Type
+ + + +
+ +#### GraphQLStreamDirective + +Experimental directive used to conditionally stream list fields. + +This directive is exported for schemas that explicitly opt in to incremental +delivery. It is not included in [`specifiedDirectives`](/api-v17/type#specifieddirectives). + +
+ +
Type
+ + + +
+ +#### DEFAULT_DEPRECATION_REASON + +Constant string used for default reason for a deprecation. + +
+ +
Type
+ + + +
+ +#### GraphQLDeprecatedDirective + +Used to declare element of a GraphQL schema as deprecated. + +The `reason` argument is non-null and defaults to +[`DEFAULT_DEPRECATION_REASON`](/api-v17/type#default_deprecation_reason). + +
+ +
Type
+ + + +
+ +#### GraphQLSpecifiedByDirective + +Used to provide a URL for specifying the behavior of custom scalar definitions. + +
+ +
Type
+ + + +
+ +#### GraphQLOneOfDirective + +Used to indicate an Input Object is a OneOf Input Object. + +
+ +
Type
+ + + +
+ +#### specifiedDirectives + +Full list of stable directives specified by GraphQL.js. + +Experimental `@defer` and `@stream` are exported separately and are not +included in this list. + +
+ +
Type
+ + + +### Types + +#### GraphQLDirectiveExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLDirectiveConfig + +**Interface.** Configuration used to construct a GraphQLDirective. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
locationsLocations where this directive may be applied.
args?Arguments accepted by this field or directive.
isRepeatable?Whether this directive may appear more than once at the same location.
deprecationReason?Reason this element is deprecated, if one was provided.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
extensionASTNodes?AST extension nodes applied to this schema element.
+ +## Category: Introspection + +
+

+ Functions:
+ isIntrospectionType() +

+

+ Constants:
+ __Schema + + __Directive + + __DirectiveLocation + + __Type + + __Field + + __InputValue + + __EnumValue + + __TypeKind + + SchemaMetaFieldDef + + TypeMetaFieldDef + + TypeNameMetaFieldDef + + introspectionTypes +

+

+ Enumerations:
+ TypeKind +

+
+ +### Functions + +#### isIntrospectionType() + +Returns true when the type is one of the built-in introspection types. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the type is one of the built-in introspection types.
+ +
+ +
Example
+ +```ts +import { GraphQLString, isIntrospectionType, __Type } from 'graphql/type'; + +isIntrospectionType(__Type); // => true +isIntrospectionType(GraphQLString); // => false +``` + +### Constants + +#### __Schema + +The introspection type describing a GraphQL schema. + +
+ +
Type
+ + + +
+ +#### __Directive + +The introspection type describing a GraphQL directive. + +
+ +
Type
+ + + +
+ +#### __DirectiveLocation + +The introspection enum describing directive locations. + +
+ +
Type
+ + + +
+ +#### __Type + +The introspection type describing GraphQL types. + +
+ +
Type
+ + + +
+ +#### __Field + +The introspection type describing object and interface fields. + +
+ +
Type
+ + + +
+ +#### __InputValue + +The introspection type describing arguments and input fields. + +
+ +
Type
+ + + +
+ +#### __EnumValue + +The introspection type describing enum values. + +
+ +
Type
+ + + +
+ +#### __TypeKind + +The introspection enum describing GraphQL type kinds. + +
+ +
Type
+ + + +
+ +#### SchemaMetaFieldDef + +Note that these are GraphQLField and not GraphQLFieldConfig, +so the format for args is different. + +
+ +
Type
+ + + +
+ +#### TypeMetaFieldDef + +The `__type` meta field definition used by introspection. + +
+ +
Type
+ + + +
+ +#### TypeNameMetaFieldDef + +The `__typename` meta field definition used by execution and introspection. + +
+ +
Type
+ + + +
+ +#### introspectionTypes + +All introspection types defined by the GraphQL specification. + +
+ +
Type
+ + + +### Enumerations + +#### TypeKind + +**Enumeration.** The introspection enum describing the different kinds of GraphQL types. + +> This is not a TypeScript `enum`. GraphQL.js exports `TypeKind` as both a runtime const object of literal values and a TypeScript type alias for those values. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameValue
{"SCALAR"}{"\"SCALAR\""}
{"OBJECT"}{"\"OBJECT\""}
{"INTERFACE"}{"\"INTERFACE\""}
{"UNION"}{"\"UNION\""}
{"ENUM"}{"\"ENUM\""}
{"INPUT_OBJECT"}{"\"INPUT_OBJECT\""}
{"LIST"}{"\"LIST\""}
{"NON_NULL"}{"\"NON_NULL\""}
+ +## Category: Scalars + +
+

+ Functions:
+ isSpecifiedScalarType() +

+

+ Constants:
+ GRAPHQL_MAX_INT + + GRAPHQL_MIN_INT + + GraphQLInt + + GraphQLFloat + + GraphQLString + + GraphQLBoolean + + GraphQLID + + specifiedScalarTypes +

+
+ +### Functions + +#### isSpecifiedScalarType() + +Returns true when the scalar type is one of the scalars specified by GraphQL. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the scalar type is one of the scalars specified by GraphQL.
+ +
+ +
Example
+ +```ts +import { + GraphQLScalarType, + GraphQLString, + isSpecifiedScalarType, +} from 'graphql/type'; + +const DateTime = new GraphQLScalarType({ + name: 'DateTime', +}); + +isSpecifiedScalarType(GraphQLString); // => true +isSpecifiedScalarType(DateTime); // => false +``` + +### Constants + +#### GRAPHQL_MAX_INT + +Maximum possible Int value as per GraphQL Spec (32-bit signed integer). +n.b. This differs from JavaScript's numbers that are IEEE 754 doubles safe up-to 2^53 - 1 + +
+ +
Type
+ + + +
+ +#### GRAPHQL_MIN_INT + +Minimum possible Int value as per GraphQL Spec (32-bit signed integer). +n.b. This differs from JavaScript's numbers that are IEEE 754 doubles safe starting at -(2^53 - 1) + +
+ +
Type
+ + + +
+ +#### GraphQLInt + +The built-in `Int` scalar type. + +
+ +
Type
+ + + +
+ +#### GraphQLFloat + +The built-in `Float` scalar type. + +
+ +
Type
+ + + +
+ +#### GraphQLString + +The built-in `String` scalar type. + +
+ +
Type
+ + + +
+ +#### GraphQLBoolean + +The built-in `Boolean` scalar type. + +
+ +
Type
+ + + +
+ +#### GraphQLID + +The built-in `ID` scalar type. + +
+ +
Type
+ + + +
+ +#### specifiedScalarTypes + +All built-in scalar types defined by the GraphQL specification. + +
+ +
Type
+ + + +## Category: Schema + +
+

+ Classes:
+ GraphQLSchema +

+

+ Functions:
+ isSchema() + + assertSchema() +

+

+ Types:
+ GraphQLSchemaExtensions + + GraphQLSchemaConfig +

+
+ +### Classes + +#### GraphQLSchema + +Schema Definition + +A Schema is created by supplying the root types of each type of operation, +query and mutation (optional). A schema definition is then supplied to the +validator and executor. + +
+ +
Example 1
+ +```ts +const MyAppQueryRootType = new GraphQLObjectType({ + name: 'Query', + fields: { + greeting: { type: GraphQLString }, + }, +}); + +const MyAppMutationRootType = new GraphQLObjectType({ + name: 'Mutation', + fields: { + setGreeting: { type: GraphQLString }, + }, +}); + +const MyAppSchema = new GraphQLSchema({ + query: MyAppQueryRootType, + mutation: MyAppMutationRootType, +}); +``` + +
+ +
Example 2
+ +When the schema is constructed, by default only the types that are reachable +by traversing the root types are included, other types must be explicitly +referenced. + +```ts +const characterInterface = new GraphQLInterfaceType({ + name: 'Character', + fields: { + name: { type: GraphQLString }, + }, +}); + +const humanType = new GraphQLObjectType({ + name: 'Human', + interfaces: [characterInterface], + fields: { + name: { type: GraphQLString }, + }, +}); + +const droidType = new GraphQLObjectType({ + name: 'Droid', + interfaces: [characterInterface], + fields: { + name: { type: GraphQLString }, + }, +}); + +const schema = new GraphQLSchema({ + query: new GraphQLObjectType({ + name: 'Query', + fields: { + hero: { type: characterInterface }, + }, + }), + // Since this schema references only the `Character` interface it's + // necessary to explicitly list the types that implement it if + // you want them to be included in the final schema. + types: [humanType, droidType], +}); +``` + +
+ +
Example 3
+ +If an array of `directives` are provided to GraphQLSchema, that will be the +exact list of directives represented and allowed. If `directives` is not +provided then a default set of the specified directives (e.g. `@include` and +`@skip`) will be used. If you wish to provide *additional* directives to +these specified directives, you must explicitly declare them. + +```ts +const MyAppSchema = new GraphQLSchema({ + query: MyAppQueryRootType, + directives: specifiedDirectives.concat([myCustomDirective]), +}); +``` + +
+ +##### Constructor + +Creates a GraphQLSchema instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
configConfiguration describing this object.
+ +
+ +##### Members + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
descriptionHuman-readable description for this schema element, if provided.
extensionsExtension fields to include in the formatted result.
astNodeAST node from which this schema element was built, if available.
extensionASTNodesAST extension nodes applied to this schema element.
assumeValidWhether this schema instance skips validation checks.
+ +
+ +##### getQueryType() + +Returns the root object type for query operations. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The query root type, if this schema defines one.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); + +schema.getQueryType()?.name; // => 'Query' +``` + +
+ +##### getMutationType() + +Returns the root object type for mutation operations. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The mutation root type, if this schema defines one.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } + + type Mutation { + setGreeting(value: String!): String + } +`); + +schema.getMutationType()?.name; // => 'Mutation' +``` + +
+ +##### getSubscriptionType() + +Returns the root object type for subscription operations. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The subscription root type, if this schema defines one.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } + + type Subscription { + greetings: String + } +`); + +schema.getSubscriptionType()?.name; // => 'Subscription' +``` + +
+ +##### getRootType() + +Returns the root object type for the requested operation kind. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
operationOperation kind to resolve.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The root object type for the operation kind, if this schema defines one.
+ +
+ +
Example
+ +```ts +import { OperationTypeNode } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } + + type Mutation { + setGreeting(value: String!): String + } +`); + +schema.getRootType(OperationTypeNode.QUERY)?.name; // => 'Query' +schema.getRootType(OperationTypeNode.MUTATION)?.name; // => 'Mutation' +schema.getRootType(OperationTypeNode.SUBSCRIPTION); // => undefined +``` + +
+ +##### getTypeMap() + +Returns all named types known to this schema. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A map of schema types keyed by type name.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type User { + name: String + } + + type Query { + viewer: User + } +`); + +const typeMap = schema.getTypeMap(); + +typeMap.User.name; // => 'User' +typeMap.Query.name; // => 'Query' +typeMap.String.name; // => 'String' +``` + +
+ +##### getType() + +Returns the named type with the provided name. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name to look up.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The named schema type, if one exists.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type User { + name: String + } + + type Query { + viewer: User + } +`); + +schema.getType('User')?.toString(); // => 'User' +schema.getType('Missing'); // => undefined +``` + +
+ +##### getPossibleTypes() + +Returns object types that may be returned for an abstract type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
abstractTypeInterface or union type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Object types that may satisfy the abstract type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInterfaceType, assertUnionType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Organization implements Node { + id: ID! + } + + union SearchResult = User | Organization + + type Query { + node: Node + search: [SearchResult] + } +`); + +const Node = assertInterfaceType(schema.getType('Node')); +const SearchResult = assertUnionType(schema.getType('SearchResult')); + +schema.getPossibleTypes(Node).map((type) => type.name); // => ['User', 'Organization'] +schema.getPossibleTypes(SearchResult).map((type) => type.name); // => ['User', 'Organization'] +``` + +
+ +##### getImplementations() + +Returns objects and interfaces that implement an interface type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
interfaceTypeInterface type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Object and interface implementations of the interface.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInterfaceType } from 'graphql/type'; + +const schema = buildSchema(` + interface Resource { + url: String! + } + + interface Image implements Resource { + url: String! + width: Int + } + + type Photo implements Resource & Image { + url: String! + width: Int + } + + type Query { + resource: Resource + } +`); + +const Resource = assertInterfaceType(schema.getType('Resource')); +const implementations = schema.getImplementations(Resource); + +implementations.interfaces.map((type) => type.name); // => ['Image'] +implementations.objects.map((type) => type.name); // => ['Photo'] +``` + +
+ +##### isSubType() + +Returns whether one type is a possible runtime subtype of an abstract type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
abstractTypeInterface or union type to inspect.
maybeSubTypeObject or interface type to test as a possible subtype.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the subtype may satisfy the abstract type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertInterfaceType, assertObjectType } from 'graphql/type'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Review { + body: String + } + + type Query { + node: Node + review: Review + } +`); + +const Node = assertInterfaceType(schema.getType('Node')); +const User = assertObjectType(schema.getType('User')); +const Review = assertObjectType(schema.getType('Review')); + +schema.isSubType(Node, User); // => true +schema.isSubType(Node, Review); // => false +``` + +
+ +##### getDirectives() + +Returns directives available in this schema. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Directives available in this schema.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + directive @upper on FIELD_DEFINITION + + type Query { + greeting: String @upper + } +`); + +schema.getDirectives().map((directive) => directive.name); // => ['include', 'skip', 'deprecated', 'specifiedBy', 'oneOf', 'upper'] +``` + +
+ +##### getDirective() + +Returns the current directive definition. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name to look up.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current directive definition, if known.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + directive @upper on FIELD_DEFINITION + + type Query { + greeting: String @upper + } +`); + +schema.getDirective('upper')?.name; // => 'upper' +schema.getDirective('missing'); // => undefined +``` + +
+ +##### getField() + +This method looks up the field on the given type definition. +It has special casing for the three introspection fields, `__schema`, +`__type` and `__typename`. + +`__typename` is special because it can always be queried as a field, even +in situations where no other fields are allowed, like on a Union. + +`__schema` and `__type` could get automatically added to the query type, +but that would require mutating type definitions, which would cause issues. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
parentTypeComposite type to look up the field on.
fieldNameField name to look up.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The field definition, including supported introspection fields.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const queryType = schema.getQueryType(); + +schema.getField(queryType, 'greeting')?.name; // => 'greeting' +schema.getField(queryType, '__typename')?.name; // => '__typename' +schema.getField(queryType, 'missing'); // => undefined +``` + +
+ +##### toConfig() + +Returns a normalized configuration object for this object. + +The returned config preserves the original `assumeValid` flag so the schema +can be recreated with the same validation behavior. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A configuration object that can be used to recreate this object.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { GraphQLSchema } from 'graphql/type'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); + +const config = schema.toConfig(); +const schemaCopy = new GraphQLSchema(config); + +config.query?.name; // => 'Query' +schemaCopy.getQueryType()?.name; // => 'Query' +``` + +### Functions + +#### isSchema() + +Test if the given value is a GraphQL schema. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
schemaValue to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the value is a GraphQLSchema.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { GraphQLString, isSchema } from 'graphql/type'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); + +isSchema(schema); // => true +isSchema(GraphQLString); // => false +``` + +
+ +#### assertSchema() + +Returns the value as a GraphQLSchema, or throws if it is not a schema. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The value typed as a GraphQLSchema.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertSchema, GraphQLString } from 'graphql/type'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); + +assertSchema(schema); // => schema +assertSchema(GraphQLString); // throws an error +``` + +### Types + +#### GraphQLSchemaExtensions + +**Interface.** Custom extensions + +**Remarks:** Use a unique identifier name for your extension, for example the name of +your library or project. Do not use a shortened identifier as this increases +the risk of conflicts. We recommend you add at most one extension field, +an object which can contain all the values you need. + +
+ +#### GraphQLSchemaConfig + +**Interface.** Configuration used to construct a GraphQLSchema. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
description?Human-readable description for this schema element, if provided.
query?Root object type for query operations.
mutation?Root object type for mutation operations.
subscription?Root object type for subscription operations.
types?Object types that belong to this union type.
directives?Directives available in this schema or applied to this AST node.
extensions?Extension fields to include in the formatted result.
astNode?AST node from which this schema element was built, if available.
extensionASTNodes?AST extension nodes applied to this schema element.
+ +## Category: Validation + +
+

+ Functions:
+ validateSchema() + + assertValidSchema() +

+
+ +### Functions + +#### validateSchema() + +Implements the "Type Validation" sub-sections of the specification's +"Type System" section. + +Validation runs synchronously, returning an array of encountered errors, or +an empty array if no errors were encountered and the Schema is valid. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Schema validation errors, or an empty array when the schema is valid.
+ +
+ +
Example
+ +```ts +import { validateSchema } from 'graphql/type'; +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + name: String + } +`); +const errors = validateSchema(schema); + +errors; // => [] +``` + +
+ +#### assertValidSchema() + +Utility function which asserts a schema is valid by throwing an error if +it is invalid. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
+ +
+ +
Example
+ +```ts +import { assertValidSchema } from 'graphql/type'; +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +assertValidSchema(schema); // does not throw +``` diff --git a/website/pages/api-v17/type/_meta.ts b/website/pages/api-v17/type/_meta.ts new file mode 100644 index 0000000000..f1d66585c4 --- /dev/null +++ b/website/pages/api-v17/type/_meta.ts @@ -0,0 +1,36 @@ +const meta = { + paths: { + title: 'Category: Paths', + href: '/api-v17/type#category-paths', + }, + names: { + title: 'Category: Names', + href: '/api-v17/type#category-names', + }, + types: { + title: 'Category: Types', + href: '/api-v17/type#category-types', + }, + directives: { + title: 'Category: Directives', + href: '/api-v17/type#category-directives', + }, + introspection: { + title: 'Category: Introspection', + href: '/api-v17/type#category-introspection', + }, + scalars: { + title: 'Category: Scalars', + href: '/api-v17/type#category-scalars', + }, + schema: { + title: 'Category: Schema', + href: '/api-v17/type#category-schema', + }, + validation: { + title: 'Category: Validation', + href: '/api-v17/type#category-validation', + }, +}; + +export default meta; diff --git a/website/pages/api-v17/utilities.mdx b/website/pages/api-v17/utilities.mdx new file mode 100644 index 0000000000..a8bac403d3 --- /dev/null +++ b/website/pages/api-v17/utilities.mdx @@ -0,0 +1,5435 @@ +import { ApiSignature, ApiType } from '../../components/ApiCode'; + +Utilities for building schemas, working with introspection, transforming ASTs, +and comparing GraphQL types. + +These exports are also available from the root `graphql` package. + +For documentation purposes, these exports are grouped into the following categories: + +- [Type Info](/api-v17/utilities#category-type-info) +- [Values](/api-v17/utilities#category-values) +- [Schema Construction](/api-v17/utilities#category-schema-construction) +- [Introspection](/api-v17/utilities#category-introspection) +- [AST Utilities](/api-v17/utilities#category-ast-utilities) +- [Schema Changes](/api-v17/utilities#category-schema-changes) +- [Operations](/api-v17/utilities#category-operations) +- [Schema Printing](/api-v17/utilities#category-schema-printing) +- [Schema Coordinates](/api-v17/utilities#category-schema-coordinates) +- [Type Comparisons](/api-v17/utilities#category-type-comparisons) +- [Typed Documents](/api-v17/utilities#category-typed-documents) + +## Category: Type Info + +
+

+ Classes:
+ TypeInfo +

+

+ Functions:
+ visitWithTypeInfo() +

+
+ +### Classes + +#### TypeInfo + +TypeInfo is a utility class which, given a GraphQL schema, can keep track +of the current field and type definitions at any point in a GraphQL document +AST during a recursive descent by calling `enter(node)` and `leave(node)`. + +
+ +##### Constructor + +Creates a TypeInfo instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaSchema used for type lookups.
initialType?Optional type to use at the start of traversal.
fragmentSignatures?Fragment signatures available during traversal.
+ +##### getType() + +Returns the current output type at this point in traversal. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current output type, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + viewer: User + } + + type User { + name: String + } +`); +const typeInfo = new TypeInfo(schema); +const fieldTypes = {}; + +visit( + parse('{ viewer { name } }'), + visitWithTypeInfo(typeInfo, { + Field: (node) => { + fieldTypes[node.name.value] = String(typeInfo.getType()); + }, + }), +); + +fieldTypes; // => { viewer: 'User', name: 'String' } +``` + +
+ +##### getParentType() + +Returns the current parent composite type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current parent composite type, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + viewer: User + } + + type User { + name: String + } +`); +const typeInfo = new TypeInfo(schema); +const parentTypes = {}; + +visit( + parse('{ viewer { name } }'), + visitWithTypeInfo(typeInfo, { + Field: (node) => { + parentTypes[node.name.value] = String(typeInfo.getParentType()); + }, + }), +); + +parentTypes; // => { viewer: 'Query', name: 'User' } +``` + +
+ +##### getInputType() + +Returns the current input type at this point in traversal. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current input type, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + reviews(stars: Int!, sort: Sort = NEWEST): [String] + } + + enum Sort { + NEWEST + OLDEST + } +`); +const typeInfo = new TypeInfo(schema); +const inputTypes = {}; + +visit( + parse('{ reviews(stars: 5, sort: OLDEST) }'), + visitWithTypeInfo(typeInfo, { + Argument: (node) => { + inputTypes[node.name.value] = String(typeInfo.getInputType()); + }, + }), +); + +inputTypes; // => { stars: 'Int!', sort: 'Sort' } +``` + +
+ +##### getParentInputType() + +Returns the parent input type for the current input position. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The parent input type, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + input ReviewFilter { + stars: Int! + } + + type Query { + reviews(filter: ReviewFilter): [String] + } +`); +const typeInfo = new TypeInfo(schema); +const parentInputTypes = {}; + +visit( + parse('{ reviews(filter: { stars: 5 }) }'), + visitWithTypeInfo(typeInfo, { + ObjectField: (node) => { + parentInputTypes[node.name.value] = String(typeInfo.getParentInputType()); + }, + }), +); + +parentInputTypes; // => { stars: 'ReviewFilter' } +``` + +
+ +##### getFieldDef() + +Returns the current field definition. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current field definition, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const typeInfo = new TypeInfo(schema); +let fieldName; + +visit( + parse('{ greeting }'), + visitWithTypeInfo(typeInfo, { + Field: () => { + fieldName = typeInfo.getFieldDef()?.name; + }, + }), +); + +fieldName; // => 'greeting' +``` + +
+ +##### getDefaultValue() + +Returns the default input representation for the current input position. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current default input, if one is available.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + reviews(limit: Int = 10): [String] + } +`); +const typeInfo = new TypeInfo(schema); +let defaultLimit; + +visit( + parse('{ reviews(limit: 5) }'), + visitWithTypeInfo(typeInfo, { + Argument: () => { + defaultLimit = typeInfo.getDefaultValue(); + }, + }), +); + +defaultLimit; // => { literal: { kind: 'IntValue', value: '10' } } +``` + +
+ +##### getDirective() + +Returns the current directive definition. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current directive definition, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const typeInfo = new TypeInfo(schema); +let directiveName; + +visit( + parse('{ greeting @include(if: true) }'), + visitWithTypeInfo(typeInfo, { + Directive: () => { + directiveName = typeInfo.getDirective()?.name; + }, + }), +); + +directiveName; // => 'include' +``` + +
+ +##### getArgument() + +Returns the current argument definition. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current argument definition, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + reviews(limit: Int = 10): [String] + } +`); +const typeInfo = new TypeInfo(schema); +let argumentName; + +visit( + parse('{ reviews(limit: 5) }'), + visitWithTypeInfo(typeInfo, { + Argument: () => { + argumentName = typeInfo.getArgument()?.name; + }, + }), +); + +argumentName; // => 'limit' +``` + +
+ +##### getFragmentSignature() + +Returns the current fragment signature. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The fragment signature for the current fragment definition.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse( + ` + { + ...GreetingFields + } + + fragment GreetingFields on Query { + greeting + } + `, + { experimentalFragmentArguments: true }, +); +const typeInfo = new TypeInfo(schema); +let fragmentName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + FragmentSpread: () => { + fragmentName = typeInfo.getFragmentSignature()?.definition.name.value; + }, + }), +); + +fragmentName; // => 'GreetingFields' +``` + +
+ +##### getFragmentSignatureByName() + +Returns the function used to look up fragment signatures by name. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A function that maps fragment names to fragment signatures.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse( + ` + { + ...GreetingFields + } + + fragment GreetingFields on Query { + greeting + } + `, + { experimentalFragmentArguments: true }, +); +const typeInfo = new TypeInfo(schema); +let fragmentName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + Document: () => { + const getFragmentSignature = typeInfo.getFragmentSignatureByName(); + fragmentName = + getFragmentSignature('GreetingFields')?.definition.name.value; + }, + }), +); + +fragmentName; // => 'GreetingFields' +``` + +
+ +##### getFragmentArgument() + +Returns the current fragment argument definition. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The variable definition for the current fragment argument.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting(name: String): String + } +`); +const document = parse( + ` + { + ...GreetingFields(name: "Ada") + } + + fragment GreetingFields($name: String) on Query { + greeting(name: $name) + } + `, + { experimentalFragmentArguments: true }, +); +const typeInfo = new TypeInfo(schema); +let argumentName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + FragmentArgument: () => { + argumentName = typeInfo.getFragmentArgument()?.variable.name.value; + }, + }), +); + +argumentName; // => 'name' +``` + +
+ +##### getEnumValue() + +Returns the current enum value definition. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current enum value definition, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + enum Sort { + NEWEST + OLDEST + } + + type Query { + reviews(sort: Sort = NEWEST): [String] + } +`); +const typeInfo = new TypeInfo(schema); +let enumValueName; + +visit( + parse('{ reviews(sort: OLDEST) }'), + visitWithTypeInfo(typeInfo, { + EnumValue: () => { + enumValueName = typeInfo.getEnumValue()?.name; + }, + }), +); + +enumValueName; // => 'OLDEST' +``` + +
+ +##### enter() + +Updates this TypeInfo instance for an entered AST node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeAST node being entered.
+ +
+ +
Example
+ +```ts +import { Kind, parse } from 'graphql/language'; +import { buildSchema, TypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse('{ greeting }'); +const operation = document.definitions[0]; +const selectionSet = operation.selectionSet; +const field = selectionSet.selections[0]; +const typeInfo = new TypeInfo(schema); + +typeInfo.enter(operation); +typeInfo.enter(selectionSet); +typeInfo.enter(field); + +field.kind; // => Kind.FIELD +typeInfo.getParentType()?.name; // => 'Query' +String(typeInfo.getType()); // => 'String' +``` + +
+ +##### leave() + +Updates this TypeInfo instance for a left AST node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeAST node being entered.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { buildSchema, TypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse('{ greeting }'); +const operation = document.definitions[0]; +const selectionSet = operation.selectionSet; +const field = selectionSet.selections[0]; +const typeInfo = new TypeInfo(schema); + +typeInfo.enter(operation); +typeInfo.enter(selectionSet); +typeInfo.enter(field); +String(typeInfo.getType()); // => 'String' + +typeInfo.leave(field); +typeInfo.getType(); // => undefined +``` + +### Functions + +#### visitWithTypeInfo() + +Creates a new visitor instance which maintains a provided TypeInfo instance +along with visiting visitor. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
typeInfoTypeInfo instance to update during traversal.
visitorVisitor callbacks to wrap with TypeInfo updates.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that keeps TypeInfo in sync while delegating callbacks.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const typeInfo = new TypeInfo(schema); +const fields = []; + +visit( + parse('{ greeting }'), + visitWithTypeInfo(typeInfo, { + Field: (node) => { + fields.push({ + name: node.name.value, + parentType: String(typeInfo.getParentType()), + type: String(typeInfo.getType()), + }); + }, + }), +); + +fields; // => [{ name: 'greeting', parentType: 'Query', type: 'String' }] +``` + +## Category: Values + + + +### Functions + +#### astFromValue() Deprecated + +Produces a GraphQL Value AST given a JavaScript object. +Function will match JavaScript/JSON values to GraphQL AST schema format +by using suggested GraphQLInputType. + +A GraphQL type must be provided, which will be used to interpret different +JavaScript values. + +This deprecated function will be removed in v18. Use `valueToLiteral()` +instead, and take care to operate on external values. + +| JSON Value | GraphQL Value | +| ------------- | -------------------- | +| Object | Input Object | +| Array | List | +| Boolean | Boolean | +| String | String / Enum Value | +| Number | Int / Float | +| BigInt | Int | +| Unknown | Enum Value | +| null | NullValue | + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
valueRuntime value to convert.
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A GraphQL value AST for the provided JavaScript value, or null when no literal can represent it.
+ +
+ +
Example
+ +```ts +import { print } from 'graphql/language'; +import { + GraphQLInputObjectType, + GraphQLInt, + GraphQLList, + GraphQLNonNull, + GraphQLString, +} from 'graphql/type'; +import { astFromValue } from 'graphql/utilities'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: { + stars: { type: new GraphQLNonNull(GraphQLInt) }, + tags: { type: new GraphQLList(GraphQLString) }, + }, +}); + +const valueNode = astFromValue( + { stars: 5, tags: ['featured', 'verified'] }, + ReviewInput, +); + +print(valueNode); // => '{ stars: 5, tags: ["featured", "verified"] }' +astFromValue(undefined, GraphQLString); // => null +astFromValue(null, new GraphQLNonNull(GraphQLString)); // => null +``` + +
+ +#### coerceInputValue() + +Coerces a JavaScript value given a GraphQL Input Type. + +Returns `undefined` when the value could not be validly coerced according to +the provided type. Use [`validateInputValue`](/api-v17/utilities#validateinputvalue) when coercion diagnostics +are needed. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
inputValueJavaScript value to coerce.
typeGraphQL input type to coerce the value against.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Coerced value, or undefined if coercion fails.
+ +
+ +
Example
+ +```ts +// Coerce runtime input values, returning undefined when coercion fails. +import { + GraphQLInputObjectType, + GraphQLInt, + GraphQLList, + GraphQLNonNull, + GraphQLString, +} from 'graphql/type'; +import { coerceInputValue } from 'graphql/utilities'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: { + stars: { type: new GraphQLNonNull(GraphQLInt) }, + tags: { type: new GraphQLList(GraphQLString) }, + }, +}); + +coerceInputValue({ stars: '5', tags: ['featured'] }, ReviewInput); // => { stars: 5, tags: ['featured'] } +coerceInputValue({ stars: 'bad' }, ReviewInput); // => undefined +``` + +
+ +#### coerceInputLiteral() + +Produces a coerced "internal" JavaScript value given a GraphQL Value AST. + +Returns `undefined` when the value could not be validly coerced according to +the provided type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
valueNodeGraphQL value AST node to coerce.
typeGraphQL input type to coerce the literal against.
variableValues?Operation variable values returned by getVariableValues.
fragmentVariableValues?Fragment variable values for the current fragment scope.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Coerced value, or undefined if coercion fails.
+ +
+ +
Example 1
+ +```ts +// Coerce literal input values without variables. +import { parseValue } from 'graphql/language'; +import { + GraphQLInputObjectType, + GraphQLInt, + GraphQLNonNull, + GraphQLString, +} from 'graphql/type'; +import { coerceInputLiteral } from 'graphql/utilities'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: { + stars: { type: new GraphQLNonNull(GraphQLInt) }, + comment: { type: GraphQLString }, + }, +}); + +coerceInputLiteral(parseValue('{ stars: 5, comment: "Loved it" }'), ReviewInput); // => { stars: 5, comment: 'Loved it' } +coerceInputLiteral(parseValue('{ comment: "Missing" }'), ReviewInput); // => undefined +``` + +
+ +
Example 2
+ +```ts +// This variant resolves variable references using VariableValues from getVariableValues(). +import assert from 'node:assert'; +import { parse, parseValue } from 'graphql/language'; +import { GraphQLInt } from 'graphql/type'; +import { getVariableValues } from 'graphql/execution'; +import { buildSchema, coerceInputLiteral } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + review(stars: Int): String + } +`); +const document = parse('query ($stars: Int = 5) { review(stars: $stars) }'); +const operation = document.definitions[0]; +const result = getVariableValues( + schema, + operation.variableDefinitions, + { stars: '4' }, +); + +assert('variableValues' in result); + +coerceInputLiteral(parseValue('$stars'), GraphQLInt, result.variableValues); // => 4 +``` + +
+ +#### replaceVariables() + +Replaces any Variables found within an AST Value literal with literals +supplied from a map of variable values, or removed if no variable replacement +exists, returning a constant value. + +Used primarily to ensure only complete constant values are used during input +coercion of custom scalars which accept complex literals. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
valueNodeValue AST node in which variables should be replaced.
variableValues?Operation variable values returned by getVariableValues.
fragmentVariableValues?Fragment variable values for the current fragment scope.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A constant value AST with variables replaced.
+ +
+ +
Example
+ +```ts +import assert from 'node:assert'; +import { parse, parseValue, print } from 'graphql/language'; +import { getVariableValues } from 'graphql/execution'; +import { buildSchema, replaceVariables } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + review(stars: Int = 5): String + } +`); +const document = parse( + 'query ($stars: Int = 5) { review(stars: $stars) }', +); +const operation = document.definitions[0]; +const result = getVariableValues( + schema, + operation.variableDefinitions, + { stars: 4 }, +); + +assert('variableValues' in result); + +const literal = replaceVariables( + parseValue('{ stars: $stars, comment: $missing }'), + result.variableValues, +); + +print(literal); // => '{ stars: 4 }' +``` + +
+ +#### validateInputValue() + +Validate that the provided input value is allowed for this type, collecting +all errors via a callback function. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
inputValueJavaScript value to validate.
typeGraphQL input type to validate the value against.
onErrorCallback invoked for each validation error and path.
hideSuggestions?Whether suggestion text should be omitted from errors.
+ +
+ +
Example 1
+ +```ts +// Collect validation errors with their input paths. +import { + GraphQLInputObjectType, + GraphQLInt, + GraphQLNonNull, +} from 'graphql/type'; +import { validateInputValue } from 'graphql/utilities'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: { + stars: { type: new GraphQLNonNull(GraphQLInt) }, + }, +}); +const errors = []; + +validateInputValue({ stars: 'bad' }, ReviewInput, (error, path) => { + errors.push({ message: error.message, path }); +}); + +errors; // => [ { message: 'Expected value of type "Int", found: "bad".', path: ['stars'] } ] +``` + +
+ +
Example 2
+ +```ts +// This variant hides suggestion text for unknown input fields. +import { GraphQLInputObjectType, GraphQLString } from 'graphql/type'; +import { validateInputValue } from 'graphql/utilities'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: { + comment: { type: GraphQLString }, + }, +}); +const errors = []; + +validateInputValue( + { rating: 'extra field' }, + ReviewInput, + (error) => { + errors.push(error.message); + }, + true, +); + +errors; // => ['Expected value of type "ReviewInput" not to include unknown field "rating", found: { rating: "extra field" }.'] +``` + +
+ +#### validateInputLiteral() + +Validate that the provided input literal is allowed for this type, collecting +all errors via a callback function. + +If variable values are not provided, the literal is validated statically +(not assuming that those variables are missing runtime values). + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
valueNodeGraphQL value AST node to validate.
typeGraphQL input type to validate the literal against.
onErrorCallback invoked for each validation error and path.
variables?Operation variable values returned by getVariableValues.
fragmentVariableValues?Fragment variable values for the current fragment scope.
hideSuggestions?Whether suggestion text should be omitted from errors.
+ +
+ +
Example 1
+ +```ts +// Validate literal input values and collect literal paths. +import { parseValue } from 'graphql/language'; +import { + GraphQLInputObjectType, + GraphQLInt, + GraphQLNonNull, +} from 'graphql/type'; +import { validateInputLiteral } from 'graphql/utilities'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: { + stars: { type: new GraphQLNonNull(GraphQLInt) }, + }, +}); +const errors = []; + +validateInputLiteral(parseValue('{ stars: "bad" }'), ReviewInput, (error, path) => { + errors.push({ message: error.message, path }); +}); + +errors; // => [ { message: 'Expected value of type "Int", found: "bad".', path: ['stars'] } ] +``` + +
+ +
Example 2
+ +```ts +// This variant resolves variable references using VariableValues from getVariableValues(). +import assert from 'node:assert'; +import { parse, parseValue } from 'graphql/language'; +import { GraphQLInt } from 'graphql/type'; +import { getVariableValues } from 'graphql/execution'; +import { buildSchema, validateInputLiteral } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + review(stars: Int): String + } +`); +const document = parse('query ($stars: Int = 5) { review(stars: $stars) }'); +const operation = document.definitions[0]; +const result = getVariableValues( + schema, + operation.variableDefinitions, + { stars: '4' }, +); + +assert('variableValues' in result); + +const errors = []; +validateInputLiteral( + parseValue('$stars'), + GraphQLInt, + (error) => errors.push(error.message), + result.variableValues, + undefined, + true, +); + +errors; // => [] +``` + +
+ +#### valueFromAST() Deprecated + +Produces a JavaScript value given a GraphQL Value AST. + +A GraphQL type must be provided, which will be used to interpret different +GraphQL Value literals. + +Returns `undefined` when the value could not be validly coerced according to +the provided type. + +This deprecated function will be removed in v18. Use `coerceInputLiteral()` +instead. + +| GraphQL Value | JSON Value | +| -------------------- | ------------- | +| Input Object | Object | +| List | Array | +| Boolean | Boolean | +| String | String | +| Int / Float | Number | +| Enum Value | Unknown | +| NullValue | null | + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
valueNodeGraphQL value AST node to convert.
typeThe GraphQL type to inspect.
variables?Optional runtime variable values keyed by variable name.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The coerced JavaScript value, or undefined if the AST value cannot be coerced to the type.
+ +
+ +
Example 1
+ +```ts +// Coerce literal values without variables. +import { parseValue } from 'graphql/language'; +import { + GraphQLInputObjectType, + GraphQLInt, + GraphQLList, + GraphQLNonNull, + GraphQLString, +} from 'graphql/type'; +import { valueFromAST } from 'graphql/utilities'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: { + stars: { type: new GraphQLNonNull(GraphQLInt) }, + tags: { type: new GraphQLList(GraphQLString) }, + }, +}); + +valueFromAST(parseValue('{ stars: 5, tags: ["featured"] }'), ReviewInput); // => { stars: 5, tags: ['featured'] } +valueFromAST(parseValue('{ stars: "bad" }'), ReviewInput); // => undefined +``` + +
+ +
Example 2
+ +```ts +// This variant resolves variable references from runtime values. +import { parseValue } from 'graphql/language'; +import { GraphQLInt } from 'graphql/type'; +import { valueFromAST } from 'graphql/utilities'; + +valueFromAST(parseValue('$stars'), GraphQLInt, { stars: 5 }); // => 5 +valueFromAST(parseValue('$stars'), GraphQLInt, {}); // => undefined +``` + +
+ +#### valueFromASTUntyped() + +Produces a JavaScript value given a GraphQL Value AST. + +Because no GraphQL type is provided, the returned JavaScript value reflects +the provided GraphQL value AST. + +| GraphQL Value | JavaScript Value | +| -------------------- | ---------------- | +| Input Object | Object | +| List | Array | +| Boolean | Boolean | +| String / Enum | String | +| Int / Float | Number | +| Null | null | + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
valueNodeGraphQL value AST node to convert.
variables?Optional runtime variable values keyed by variable name.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
JavaScript value represented by the GraphQL value AST.
+ +
+ +
Example
+ +```ts +import { parseValue } from 'graphql/language'; +import { valueFromASTUntyped } from 'graphql/utilities'; + +const value = valueFromASTUntyped(parseValue('[1, 2, 3]')); + +value; // => [1, 2, 3] +valueFromASTUntyped(parseValue('$name'), { name: 'Ada' }); // => 'Ada' +``` + +
+ +#### valueToLiteral() + +Produces a GraphQL Value AST given a JavaScript value and a GraphQL type. + +Scalar types are converted by calling the [`valueToLiteral`](/api-v17/utilities#valuetoliteral) method on that +type, otherwise the default scalar [`valueToLiteral`](/api-v17/utilities#valuetoliteral) method is used, defined +below. + +Provided value is a non-coerced "input" value. This function does not +perform any coercion, however it does perform validation. Provided values +which are invalid for the given type will result in an `undefined` return +value. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
valueJavaScript value to convert.
typeGraphQL input type to convert the value against.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A GraphQL value AST, or undefined if the value is invalid.
+ +
+ +
Example
+ +```ts +import { print } from 'graphql/language'; +import { + GraphQLInputObjectType, + GraphQLInt, + GraphQLList, + GraphQLNonNull, + GraphQLString, +} from 'graphql/type'; +import { valueToLiteral } from 'graphql/utilities'; + +const ReviewInput = new GraphQLInputObjectType({ + name: 'ReviewInput', + fields: { + stars: { type: new GraphQLNonNull(GraphQLInt) }, + tags: { type: new GraphQLList(GraphQLString) }, + }, +}); + +const literal = valueToLiteral({ stars: 5, tags: ['featured'] }, ReviewInput); + +print(literal); // => '{ stars: 5, tags: ["featured"] }' +valueToLiteral({ tags: ['missing stars'] }, ReviewInput); // => undefined +``` + +## Category: Schema Construction + +
+

+ Functions:
+ buildASTSchema() + + buildSchema() + + extendSchema() + + lexicographicSortSchema() +

+

+ Types:
+ BuildSchemaOptions +

+
+ +### Functions + +#### buildASTSchema() + +Builds a GraphQLSchema from a parsed schema definition language document. + +If no schema definition is provided, then it will look for types named Query, +Mutation and Subscription. + +The resulting schema has no resolver functions, so execution will use the +default field resolver. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
documentASTThe parsed GraphQL document AST.
options?Optional configuration for this operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema built from the provided SDL document.
+ +
+ +
Example 1
+ +```ts +// Build a schema from a valid parsed SDL document. +import { parse } from 'graphql/language'; +import { buildASTSchema } from 'graphql/utilities'; + +const document = parse('type Query { hello: String }'); +const schema = buildASTSchema(document); + +schema.getQueryType().name; // => 'Query' +``` + +
+ +
Example 2
+ +```ts +// This variant uses validation options when the SDL references unknown types. +import { parse } from 'graphql/language'; +import { buildASTSchema } from 'graphql/utilities'; + +const document = parse('type Query { broken: MissingType }'); + +buildASTSchema(document); // throws an error +buildASTSchema(document, { + assumeValid: true, + assumeValidSDL: true, +}); // does not throw +``` + +
+ +#### buildSchema() + +Builds a GraphQLSchema directly from a schema definition language source. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
sourceThe GraphQL source text or source object.
options?Optional configuration for this operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema built from the provided SDL document.
+ +
+ +
Example 1
+ +```ts +// Build a schema from SDL source using the default options. +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema('type Query { hello: String }'); + +schema.getQueryType().name; // => 'Query' +``` + +
+ +
Example 2
+ +```ts +// This variant enables parser options and omits source locations. +import { buildSchema } from 'graphql/utilities'; + +const schema = buildSchema( + 'directive @tag on FIELD_DEFINITION\n' + + 'directive @compose @tag on FIELD_DEFINITION', + { + experimentalDirectivesOnDirectiveDefinitions: true, + experimentalFragmentArguments: true, + noLocation: true, + }, +); + +const directive = schema.getDirective('compose'); + +directive.name; // => 'compose' +directive.astNode.loc; // => undefined +``` + +
+ +#### extendSchema() + +Produces a new schema given an existing schema and a document which may +contain GraphQL type extensions and definitions. The original schema will +remain unaltered. + +Because a schema represents a graph of references, a schema cannot be +extended without effectively making an entire copy. We do not know until it's +too late if subgraphs remain unchanged. + +This algorithm copies the provided schema, applying extensions while +producing the copy. The original schema remains unaltered. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
documentASTThe parsed GraphQL document AST.
options?Optional configuration for this operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A new schema with the extensions and definitions applied.
+ +
+ +
Example 1
+ +```ts +// Extend a schema with new fields and types. +import { parse } from 'graphql/language'; +import { buildSchema, extendSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const extensionAST = parse(` + extend type Query { + farewell: String + } + + type Review { + body: String + } +`); + +const extendedSchema = extendSchema(schema, extensionAST); + +schema.getType('Review'); // => undefined +extendedSchema.getType('Review')?.name; // => 'Review' +Object.keys(extendedSchema.getQueryType().getFields()); // => ['greeting', 'farewell'] +``` + +
+ +
Example 2
+ +```ts +// This variant bypasses validation for an otherwise invalid extension. +import { parse } from 'graphql/language'; +import { buildSchema, extendSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const invalidExtension = parse(` + extend type Missing { + field: String + } +`); + +extendSchema(schema, invalidExtension); // throws an error +extendSchema(schema, invalidExtension, { + assumeValid: true, + assumeValidSDL: true, + }); // does not throw +``` + +
+ +#### lexicographicSortSchema() + +Sort GraphQLSchema. + +This function returns a sorted copy of the given GraphQLSchema. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A copy of the schema with types, fields, arguments, and values sorted lexicographically.
+ +
+ +
Example
+ +```ts +import { buildSchema, lexicographicSortSchema, printSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + zebra: String + apple: String + } + + enum Episode { + JEDI + NEW_HOPE + EMPIRE + } +`); + +const sortedSchema = lexicographicSortSchema(schema); + +printSchema(sortedSchema); +// => +// enum Episode { +// EMPIRE +// JEDI +// NEW_HOPE +// } +// +// type Query { +// apple: String +// zebra: String +// } +``` + +### Types + +#### BuildSchemaOptions + +**Interface.** Options used when building a schema from SDL or a parsed SDL document. + +
+ +
Members
+ + + + + + + + + + + + + + + + +
NameTypeDescription
assumeValidSDL?Set to true to assume the SDL is valid.
+Default: false
+ +## Category: Introspection + + + +### Functions + +#### buildClientSchema() + +Build a GraphQLSchema for use by client tools. + +Given the result of a client running the introspection query, creates and +returns a GraphQLSchema instance which can be then used with all graphql-js +tools, but cannot be used to execute a query, as introspection does not +represent the "resolver", "parse" or "serialize" functions or any other +server-internal mechanisms. + +This function expects a complete introspection result. Don't forget to check +the "errors" field of a server response before calling this function. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
introspectionIntrospection result data to build from.
options?Optional configuration for this operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The client schema represented by the introspection result.
+ +
+ +
Example
+ +```ts +import { buildClientSchema, introspectionFromSchema, buildSchema } from 'graphql/utilities'; + +const schema = buildSchema('type Query { hello: String }'); +const clientSchema = buildClientSchema(introspectionFromSchema(schema), { + assumeValid: true, +}); + +clientSchema.getQueryType().name; // => 'Query' +``` + +
+ +#### getIntrospectionQuery() + +Produce the GraphQL query recommended for a full schema introspection. +Accepts optional IntrospectionOptions. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
options?Optional configuration for this operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The resolved introspection query.
+ +
+ +
Example 1
+ +```ts +// Generate the default introspection query. +import { getIntrospectionQuery } from 'graphql/utilities'; + +const query = getIntrospectionQuery(); + +query; // matches /__schema/ +query; // matches /description/ +query; // does not match /specifiedByURL/ +``` + +
+ +
Example 2
+ +```ts +// This variant customizes optional introspection fields and nesting depth. +import { getIntrospectionQuery } from 'graphql/utilities'; + +const query = getIntrospectionQuery({ + descriptions: false, + specifiedByUrl: true, + directiveIsRepeatable: true, + schemaDescription: true, + inputValueDeprecation: true, + experimentalDirectiveDeprecation: true, + oneOf: true, + typeDepth: 3, +}); + +query; // does not match /description/ +query; // matches /specifiedByURL/ +query; // matches /isRepeatable/ +query; // matches /includeDeprecated: true/ +query; // matches /isOneOf/ +(query.match(/ofType/g)?.length ?? 0) > 0; // => true +``` + +
+ +#### introspectionFromSchema() + +Build an IntrospectionQuery from a GraphQLSchema + +IntrospectionQuery is useful for utilities that care about type and field +relationships, but do not need to traverse through those relationships. + +This is the inverse of buildClientSchema. The primary use case is outside +of the server context, for instance when doing schema comparisons. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
options?Optional configuration for this operation.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Introspection result data for the schema.
+ +
+ +
Example 1
+ +```ts +// Include schema metadata using the default introspection options. +import { buildSchema, introspectionFromSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + scalar Url @specifiedBy(url: "https://url.spec.whatwg.org/") + + type Query { + homepage: Url + } +`); + +const introspection = introspectionFromSchema(schema); +const urlType = introspection.__schema.types.find((type) => type.name === 'Url'); + +urlType.specifiedByURL; // => 'https://url.spec.whatwg.org/' +``` + +
+ +
Example 2
+ +```ts +// This variant disables optional introspection metadata. +import { buildSchema, introspectionFromSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + scalar Url @specifiedBy(url: "https://url.spec.whatwg.org/") + + type Query { + homepage: Url + } +`); + +const introspection = introspectionFromSchema(schema, { + descriptions: false, + specifiedByUrl: false, + directiveIsRepeatable: false, + schemaDescription: false, + inputValueDeprecation: false, + experimentalDirectiveDeprecation: false, + oneOf: false, +}); +const urlType = introspection.__schema.types.find((type) => type.name === 'Url'); +const deprecatedDirective = introspection.__schema.directives.find( + (directive) => directive.name === 'deprecated', +); + +urlType.specifiedByURL; // => undefined +urlType.description; // => undefined +introspection.__schema.description; // => undefined +deprecatedDirective.isRepeatable; // => undefined +``` + +### Types + +#### IntrospectionOptions + +**Interface.** Options controlling which fields are included in the introspection query. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
descriptions?Whether to include descriptions in the introspection result.
+Default: true
specifiedByUrl?Whether to include {"specifiedByURL"} in the introspection result.
+Default: false
directiveIsRepeatable?Whether to include {"isRepeatable"} flag on directives.
+Default: false
schemaDescription?Whether to include {"description"} field on schema.
+Default: false
inputValueDeprecation?Whether target GraphQL server support deprecation of input values.
+Default: false
experimentalDirectiveDeprecation?Whether target GraphQL server supports deprecation of directives.
+Default: false
oneOf?Whether target GraphQL server supports {"@oneOf"} input objects.
+Default: false
typeDepth?How deep to recurse into nested types, larger values will result in more
+accurate results, but have a higher load on the server.
+Some servers might restrict the maximum query depth or complexity.
+If that's the case, try decreasing this value.
+Default: 9
+ +
+ +#### IntrospectionQuery + +**Interface.** The result shape returned by a full introspection query. + +
+ +
Members
+ + + + + + + + + + + + + + + + +
NameTypeDescription
__schemaThe schema.
+ +
+ +#### IntrospectionSchema + +**Interface.** The introspection representation of a GraphQL schema. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
description?Human-readable description for this schema element, if provided.
queryTypeThe root object type used for query operations.
mutationTypeThe root object type used for mutation operations, if supported.
subscriptionTypeThe root object type used for subscription operations, if supported.
typesObject types that belong to this union type.
directivesDirectives available in this schema or applied to this AST node.
+ +
+ +#### IntrospectionType + +**Type alias.** Any introspection representation of a GraphQL type. + + + +
+ +#### IntrospectionOutputType + +**Type alias.** An introspection type that can appear in output position. + + + +
+ +#### IntrospectionInputType + +**Type alias.** An introspection type that can appear in input position. + + + +
+ +#### IntrospectionScalarType + +**Interface.** The introspection representation of a scalar type. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe introspection kind discriminator for this type reference or type.
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
specifiedByURL?URL identifying the behavior specified for this custom scalar.
+ +
+ +#### IntrospectionObjectType + +**Interface.** The introspection representation of an object type. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe introspection kind discriminator for this type reference or type.
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
fieldsFields declared by this object, interface, input object, or literal.
interfacesInterfaces implemented by this object or interface type.
+ +
+ +#### IntrospectionInterfaceType + +**Interface.** The introspection representation of an interface type. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe introspection kind discriminator for this type reference or type.
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
fieldsFields declared by this object, interface, input object, or literal.
interfacesInterfaces implemented by this object or interface type.
possibleTypesObject types that may be returned for this abstract type.
+ +
+ +#### IntrospectionUnionType + +**Interface.** The introspection representation of a union type. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe introspection kind discriminator for this type reference or type.
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
possibleTypesObject types that may be returned for this abstract type.
+ +
+ +#### IntrospectionEnumType + +**Interface.** The introspection representation of an enum type. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe introspection kind discriminator for this type reference or type.
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
enumValuesValues declared by this enum type.
+ +
+ +#### IntrospectionInputObjectType + +**Interface.** The introspection representation of an input object type. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe introspection kind discriminator for this type reference or type.
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
inputFieldsInput fields declared by this input object type.
isOneOfWhether this input object uses the experimental OneOf input object semantics.
+ +
+ +#### IntrospectionListTypeRef + +**Interface.** The introspection representation of a list type reference. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TThe introspection type reference wrapped by this list type reference.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe introspection kind discriminator for this type reference or type.
ofTypeThe type wrapped by this list or non-null type.
+ +
+ +#### IntrospectionNonNullTypeRef + +**Interface.** The introspection representation of a non-null type reference. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TThe introspection type reference wrapped by this non-null type reference.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe introspection kind discriminator for this type reference or type.
ofTypeThe type wrapped by this list or non-null type.
+ +
+ +#### IntrospectionTypeRef + +**Type alias.** Any introspection representation of a type reference. + + + +
+ +#### IntrospectionOutputTypeRef + +**Type alias.** An introspection type reference that can appear in output position. + + + +
+ +#### IntrospectionInputTypeRef + +**Type alias.** An introspection type reference that can appear in input position. + + + +
+ +#### IntrospectionNamedTypeRef + +**Interface.** The introspection representation of a named type reference. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TThe introspection type represented by this named type reference.
+ +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
kindThe introspection kind discriminator for this type reference or type.
nameThe GraphQL name for this schema element.
+ +
+ +#### IntrospectionField + +**Interface.** The introspection representation of a field. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
argsArguments accepted by this field or directive.
typeThe GraphQL type reference or runtime type for this element.
isDeprecatedWhether this field, argument, enum value, or input value is deprecated.
deprecationReasonReason this element is deprecated, if one was provided.
+ +
+ +#### IntrospectionInputValue + +**Interface.** The introspection representation of an argument or input field. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
typeThe GraphQL type reference or runtime type for this element.
defaultValueDefault value used when no explicit value is supplied.
isDeprecated?Whether this field, argument, enum value, or input value is deprecated.
deprecationReason?Reason this element is deprecated, if one was provided.
+ +
+ +#### IntrospectionEnumValue + +**Interface.** The introspection representation of an enum value. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
isDeprecatedWhether this field, argument, enum value, or input value is deprecated.
deprecationReasonReason this element is deprecated, if one was provided.
+ +
+ +#### IntrospectionDirective + +**Interface.** The introspection representation of a directive. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nameThe GraphQL name for this schema element.
description?Human-readable description for this schema element, if provided.
isRepeatable?Whether this directive may appear more than once at the same location.
isDeprecated?Whether this field, argument, enum value, or input value is deprecated.
deprecationReason?Reason this element is deprecated, if one was provided.
locationsLocations where this directive may be applied.
argsArguments accepted by this field or directive.
+ +## Category: AST Utilities + +
+

+ Functions:
+ concatAST() + + separateOperations() + + stripIgnoredCharacters() +

+
+ +### Functions + +#### concatAST() + +Provided a collection of ASTs, presumably each from different files, +concatenate the ASTs together into batched AST, useful for validating many +GraphQL source files which together represent one conceptual application. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
documentsDocument ASTs to concatenate.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A document AST containing all definitions from the provided documents.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { concatAST } from 'graphql/utilities'; + +const document = concatAST([parse('type Query { a: String }'), parse('type User { id: ID }')]); + +document.definitions.length; // => 2 +``` + +
+ +#### separateOperations() + +separateOperations accepts a single AST document which may contain many +operations and fragments and returns a collection of AST documents each of +which contains a single operation as well the fragment definitions it +refers to. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
documentASTThe parsed GraphQL document AST.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A map of operation names to documents containing each operation and its referenced fragments.
+ +
+ +
Example
+ +```ts +import { parse, print } from 'graphql/language'; +import { separateOperations } from 'graphql/utilities'; + +const document = parse(` + query GetUser { + viewer { + ...UserFields + } + } + + query GetStatus { + status + } + + fragment UserFields on User { + id + } +`); + +const separated = separateOperations(document); + +Object.keys(separated); // => ['GetUser', 'GetStatus'] +print(separated.GetUser); // matches /fragment UserFields/ +print(separated.GetStatus); // does not match /fragment UserFields/ +``` + +
+ +#### stripIgnoredCharacters() + +Strips characters that are not significant to the validity or execution +of a GraphQL document: + - UnicodeBOM + - WhiteSpace + - LineTerminator + - Comment + - Comma + - BlockString indentation + +Note: It is required to have a delimiter character between neighboring +non-punctuator tokens and this function always uses single space as delimiter. + +It is guaranteed that both input and output documents if parsed would result +in the exact same AST except for nodes location. + +Warning: It is guaranteed that this function will always produce stable results. +However, it's not guaranteed that it will stay the same between different +releases due to bugfixes or changes in the GraphQL specification. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
sourceThe GraphQL source text or source object.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A semantically equivalent GraphQL source string without ignored characters.
+ +
+ +
Example 1
+ +```graphql +query SomeQuery($foo: String!, $bar: String) { + someField(foo: $foo, bar: $bar) { + a + b { + c + d + } + } +} +``` + +Becomes: + +```graphql +query SomeQuery($foo:String!$bar:String){someField(foo:$foo bar:$bar){a b{c d}}} +``` + +
+ +
Example 2
+ +```graphql +""" +Type description +""" +type Foo { + """ + Field description + """ + bar: String +} +``` + +Becomes: + +```graphql +"""Type description""" type Foo{"""Field description""" bar:String} +``` + +
+ +
Example 3
+ +```ts +import { stripIgnoredCharacters } from 'graphql/utilities'; + +const source = stripIgnoredCharacters('query Example { name }'); + +source; // => 'query Example{name}' +``` + +## Category: Schema Changes + +
+

+ Functions:
+ findBreakingChanges() + + findDangerousChanges() + + findSchemaChanges() +

+

+ Enumerations:
+ BreakingChangeType + + DangerousChangeType + + SafeChangeType +

+

+ Types:
+ BreakingChange + + DangerousChange + + SafeChange + + SchemaChange +

+
+ +### Functions + +#### findBreakingChanges() Deprecated + +Given two schemas, returns an Array containing descriptions of all the types +of breaking changes covered by the other functions down below. This +deprecated wrapper will be removed in v18; use `findSchemaChanges()` instead +and filter for breaking changes. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oldSchemaSchema before the change.
newSchemaSchema after the change.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Breaking changes between the two schemas.
+ +
+ +
Example
+ +```ts +import { buildSchema, findBreakingChanges } from 'graphql/utilities'; + +const oldSchema = buildSchema(` + type Query { + greeting: String + } +`); +const newSchema = buildSchema(` + type Query { + hello: String + } +`); + +const changes = findBreakingChanges(oldSchema, newSchema); + +changes.map((change) => change.type); // => ['FIELD_REMOVED'] +``` + +
+ +#### findDangerousChanges() Deprecated + +Given two schemas, returns an Array containing descriptions of all the types +of potentially dangerous changes covered by the other functions down below. +This deprecated wrapper will be removed in v18; use `findSchemaChanges()` +instead and filter for dangerous changes. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oldSchemaSchema before the change.
newSchemaSchema after the change.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Dangerous changes between the two schemas.
+ +
+ +
Example
+ +```ts +import { buildSchema, findDangerousChanges } from 'graphql/utilities'; + +const oldSchema = buildSchema(` + enum Episode { + NEW_HOPE + } + + type Query { + episode: Episode + } +`); +const newSchema = buildSchema(` + enum Episode { + NEW_HOPE + EMPIRE + } + + type Query { + episode: Episode + } +`); + +const changes = findDangerousChanges(oldSchema, newSchema); + +changes.map((change) => change.type); // => ['VALUE_ADDED_TO_ENUM'] +``` + +
+ +#### findSchemaChanges() + +Finds all schema changes between two schemas. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oldSchemaSchema before the change.
newSchemaSchema after the change.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Safe, dangerous, and breaking changes between the two schemas.
+ +
+ +
Example
+ +```ts +import { buildSchema, findSchemaChanges } from 'graphql/utilities'; + +const oldSchema = buildSchema(` + type Query { + greeting: String + } +`); +const newSchema = buildSchema(` + type Query { + greeting(name: String): String + farewell: String + } +`); + +const changes = findSchemaChanges(oldSchema, newSchema); + +changes.map((change) => change.type); // => ['OPTIONAL_ARG_ADDED', 'FIELD_ADDED'] +``` + +### Enumerations + +#### BreakingChangeType + +**Enumeration.** Categories of schema changes that may break existing operations. + +> This is not a TypeScript `enum`. GraphQL.js exports `BreakingChangeType` as both a runtime const object of literal values and a TypeScript type alias for those values. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameValue
{"TYPE_REMOVED"}{"\"TYPE_REMOVED\""}
{"TYPE_CHANGED_KIND"}{"\"TYPE_CHANGED_KIND\""}
{"TYPE_REMOVED_FROM_UNION"}{"\"TYPE_REMOVED_FROM_UNION\""}
{"VALUE_REMOVED_FROM_ENUM"}{"\"VALUE_REMOVED_FROM_ENUM\""}
{"REQUIRED_INPUT_FIELD_ADDED"}{"\"REQUIRED_INPUT_FIELD_ADDED\""}
{"IMPLEMENTED_INTERFACE_REMOVED"}{"\"IMPLEMENTED_INTERFACE_REMOVED\""}
{"FIELD_REMOVED"}{"\"FIELD_REMOVED\""}
{"FIELD_CHANGED_KIND"}{"\"FIELD_CHANGED_KIND\""}
{"REQUIRED_ARG_ADDED"}{"\"REQUIRED_ARG_ADDED\""}
{"ARG_REMOVED"}{"\"ARG_REMOVED\""}
{"ARG_CHANGED_KIND"}{"\"ARG_CHANGED_KIND\""}
{"DIRECTIVE_REMOVED"}{"\"DIRECTIVE_REMOVED\""}
{"DIRECTIVE_ARG_REMOVED"}{"\"DIRECTIVE_ARG_REMOVED\""}
{"REQUIRED_DIRECTIVE_ARG_ADDED"}{"\"REQUIRED_DIRECTIVE_ARG_ADDED\""}
{"DIRECTIVE_REPEATABLE_REMOVED"}{"\"DIRECTIVE_REPEATABLE_REMOVED\""}
{"DIRECTIVE_LOCATION_REMOVED"}{"\"DIRECTIVE_LOCATION_REMOVED\""}
+ +
+ +#### DangerousChangeType + +**Enumeration.** Categories of schema changes that may be dangerous for existing operations. + +> This is not a TypeScript `enum`. GraphQL.js exports `DangerousChangeType` as both a runtime const object of literal values and a TypeScript type alias for those values. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameValue
{"VALUE_ADDED_TO_ENUM"}{"\"VALUE_ADDED_TO_ENUM\""}
{"TYPE_ADDED_TO_UNION"}{"\"TYPE_ADDED_TO_UNION\""}
{"OPTIONAL_INPUT_FIELD_ADDED"}{"\"OPTIONAL_INPUT_FIELD_ADDED\""}
{"OPTIONAL_ARG_ADDED"}{"\"OPTIONAL_ARG_ADDED\""}
{"IMPLEMENTED_INTERFACE_ADDED"}{"\"IMPLEMENTED_INTERFACE_ADDED\""}
{"ARG_DEFAULT_VALUE_CHANGE"}{"\"ARG_DEFAULT_VALUE_CHANGE\""}
+ +
+ +#### SafeChangeType + +**Enumeration.** Categories of schema changes that are considered safe for existing operations. + +> This is not a TypeScript `enum`. GraphQL.js exports `SafeChangeType` as both a runtime const object of literal values and a TypeScript type alias for those values. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameValue
{"DESCRIPTION_CHANGED"}{"\"DESCRIPTION_CHANGED\""}
{"TYPE_ADDED"}{"\"TYPE_ADDED\""}
{"OPTIONAL_INPUT_FIELD_ADDED"}{"\"OPTIONAL_INPUT_FIELD_ADDED\""}
{"OPTIONAL_ARG_ADDED"}{"\"OPTIONAL_ARG_ADDED\""}
{"DIRECTIVE_ADDED"}{"\"DIRECTIVE_ADDED\""}
{"FIELD_ADDED"}{"\"FIELD_ADDED\""}
{"DIRECTIVE_REPEATABLE_ADDED"}{"\"DIRECTIVE_REPEATABLE_ADDED\""}
{"DIRECTIVE_LOCATION_ADDED"}{"\"DIRECTIVE_LOCATION_ADDED\""}
{"OPTIONAL_DIRECTIVE_ARG_ADDED"}{"\"OPTIONAL_DIRECTIVE_ARG_ADDED\""}
{"FIELD_CHANGED_KIND_SAFE"}{"\"FIELD_CHANGED_KIND_SAFE\""}
{"ARG_CHANGED_KIND_SAFE"}{"\"ARG_CHANGED_KIND_SAFE\""}
{"ARG_DEFAULT_VALUE_ADDED"}{"\"ARG_DEFAULT_VALUE_ADDED\""}
+ +### Types + +#### BreakingChange + +**Interface.** Description of a schema change that may break existing operations. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
typeSpecific kind of breaking schema change.
descriptionHuman-readable description of the breaking schema change.
+ +
+ +#### DangerousChange + +**Interface.** Description of a schema change that may be dangerous for existing operations. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
typeSpecific kind of dangerous schema change.
descriptionHuman-readable description of the dangerous schema change.
+ +
+ +#### SafeChange + +**Interface.** Description of a schema change that is considered safe for existing operations. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
typeSpecific kind of safe schema change.
descriptionHuman-readable description of the safe schema change.
+ +
+ +#### SchemaChange + +**Type alias.** Any schema change detected between two schemas. + + + +## Category: Operations + +
+

+ Functions:
+ getOperationAST() +

+
+ +### Functions + +#### getOperationAST() + +Returns an operation AST given a document AST and optionally an operation +name. If a name is not provided, an operation is only returned if only one is +provided in the document. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
documentASTThe parsed GraphQL document AST.
operationName?The optional operation name to select.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The resolved operation ast.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { getOperationAST } from 'graphql/utilities'; + +const document = parse('query GetName { name }'); +const operation = getOperationAST(document, 'GetName'); + +operation.name.value; // => 'GetName' +getOperationAST(document, 'Missing'); // => undefined +``` + +## Category: Schema Printing + +
+

+ Functions:
+ printSchema() + + printIntrospectionSchema() + + printType() + + printDirective() +

+
+ +### Functions + +#### printSchema() + +Prints the schema. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The printed string representation.
+ +
+ +
Example
+ +```ts +import { buildSchema, printSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + directive @upper on FIELD_DEFINITION + + type Query { + greeting: String @upper + } +`); + +printSchema(schema); // => ['directive @upper on FIELD_DEFINITION', '', 'type Query {', ' greeting: String', '}'].join('\n') +``` + +
+ +#### printIntrospectionSchema() + +Prints the introspection schema. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The printed string representation.
+ +
+ +
Example
+ +```ts +import { buildSchema, printIntrospectionSchema } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); + +const printed = printIntrospectionSchema(schema); + +printed; // matches /type __Schema/ +printed; // matches /enum __TypeKind/ +printed; // does not match /type Query/ +``` + +
+ +#### printType() + +Prints the type. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
typeThe GraphQL type to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The printed string representation.
+ +
+ +
Example
+ +```ts +import { buildSchema, printType } from 'graphql/utilities'; + +const schema = buildSchema(` + type User { + id: ID! + name: String + } + + type Query { + viewer: User + } +`); + +printType(schema.getType('User')); // => ['type User {', ' id: ID!', ' name: String', '}'].join('\n') +``` + +
+ +#### printDirective() + +Prints a directive definition in GraphQL SDL. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
directiveDirective to print.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
SDL string for the directive definition.
+ +
+ +
Example
+ +```ts +import { DirectiveLocation, GraphQLDirective, GraphQLString } from 'graphql/type'; +import { printDirective } from 'graphql/utilities'; + +const authDirective = new GraphQLDirective({ + name: 'auth', + description: 'Requires authorization.', + locations: [DirectiveLocation.FIELD_DEFINITION], + args: { + scope: { type: GraphQLString }, + }, +}); + +printDirective(authDirective); // => '"""Requires authorization."""\ndirective @auth(scope: String) on FIELD_DEFINITION' +``` + +## Category: Schema Coordinates + + + +### Functions + +#### resolveSchemaCoordinate() + +A schema coordinate is resolved in the context of a GraphQL schema to +uniquely identify a schema element. It returns undefined if the schema +coordinate does not resolve to a schema element, meta-field, or introspection +schema element. It will throw if the containing schema element (if +applicable) does not exist. + +https://spec.graphql.org/draft/#sec-Schema-Coordinates.Semantics + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
schemaCoordinateThe schema coordinate to resolve.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema element identified by the coordinate, or undefined if none exists.
+ +
+ +
Example
+ +```ts +import { buildSchema, resolveSchemaCoordinate } from 'graphql/utilities'; + +const schema = buildSchema(` + directive @tag(name: String!) on FIELD_DEFINITION + + input ReviewInput { + stars: Int! + } + + enum Episode { + NEW_HOPE + } + + type Query { + reviews(input: ReviewInput): [String] @tag(name: "reviews") + } +`); + +resolveSchemaCoordinate(schema, 'Query').kind; // => 'NamedType' +resolveSchemaCoordinate(schema, 'Query.reviews').kind; // => 'Field' +resolveSchemaCoordinate(schema, 'Query.reviews(input:)').kind; // => 'FieldArgument' +resolveSchemaCoordinate(schema, 'ReviewInput.stars').kind; // => 'InputField' +resolveSchemaCoordinate(schema, 'Episode.NEW_HOPE').kind; // => 'EnumValue' +resolveSchemaCoordinate(schema, '@tag').kind; // => 'Directive' +resolveSchemaCoordinate(schema, '@tag(name:)').kind; // => 'DirectiveArgument' +resolveSchemaCoordinate(schema, 'Query.missing'); // => undefined +``` + +
+ +#### resolveASTSchemaCoordinate() + +Resolves schema coordinate from a parsed SchemaCoordinate node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
schemaCoordinateThe schema coordinate to resolve.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema element identified by the parsed coordinate, or undefined if none exists.
+ +
+ +
Example
+ +```ts +import { parseSchemaCoordinate } from 'graphql/language'; +import { buildSchema, resolveASTSchemaCoordinate } from 'graphql/utilities'; + +const schema = buildSchema(` + type Query { + greeting(name: String): String + } +`); +const coordinate = parseSchemaCoordinate('Query.greeting(name:)'); +const resolved = resolveASTSchemaCoordinate(schema, coordinate); + +resolved.kind; // => 'FieldArgument' +resolved.field.name; // => 'greeting' +resolved.fieldArgument.name; // => 'name' +``` + +### Types + +#### ResolvedSchemaElement + +**Type alias.** A schema element resolved from a schema coordinate. + + + +## Category: Type Comparisons + +
+

+ Functions:
+ isEqualType() + + isTypeSubTypeOf() + + doTypesOverlap() +

+
+ +### Functions + +#### isEqualType() + +Provided two types, return true if the types are equal (invariant). + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
typeAThe first GraphQL type to compare.
typeBThe second GraphQL type to compare.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when both types are equal.
+ +
+ +
Example
+ +```ts +import { + GraphQLList, + GraphQLNonNull, + GraphQLString, +} from 'graphql/type'; +import { isEqualType } from 'graphql/utilities'; + +isEqualType(GraphQLString, GraphQLString); // => true +isEqualType(new GraphQLList(GraphQLString), new GraphQLList(GraphQLString)); // => true +isEqualType(new GraphQLNonNull(GraphQLString), GraphQLString); // => false +``` + +
+ +#### isTypeSubTypeOf() + +Provided a type and a super type, return true if the first type is either +equal or a subset of the second super type (covariant). + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
maybeSubTypeThe possible subtype to compare.
superTypeThe possible supertype to compare.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when {"maybeSubType"} is equal to or a subtype of {"superType"}.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { + GraphQLNonNull, + assertInterfaceType, + assertObjectType, +} from 'graphql/type'; +import { isTypeSubTypeOf } from 'graphql/utilities'; + +const schema = buildSchema(` + interface Node { + id: ID! + } + + type User implements Node { + id: ID! + } + + type Query { + node: Node + } +`); +const Node = assertInterfaceType(schema.getType('Node')); +const User = assertObjectType(schema.getType('User')); + +isTypeSubTypeOf(schema, User, Node); // => true +isTypeSubTypeOf(schema, new GraphQLNonNull(User), Node); // => true +isTypeSubTypeOf(schema, Node, User); // => false +``` + +
+ +#### doTypesOverlap() + +Provided two composite types, determine if they "overlap". Two composite +types overlap when the Sets of possible concrete types for each intersect. + +This is often used to determine if a fragment of a given type could possibly +be visited in a context of another type. + +This function is commutative. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaGraphQL schema to use.
typeAThe first GraphQL type to compare.
typeBThe second GraphQL type to compare.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
True when the two composite types can apply to at least one common object type.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql/utilities'; +import { assertObjectType, assertUnionType } from 'graphql/type'; +import { doTypesOverlap } from 'graphql/utilities'; + +const schema = buildSchema(` + type Photo { + url: String! + } + + type Video { + url: String! + } + + union Media = Photo | Video + union StillImage = Photo + + type Query { + media: [Media] + } +`); +const Media = assertUnionType(schema.getType('Media')); +const StillImage = assertUnionType(schema.getType('StillImage')); +const Video = assertObjectType(schema.getType('Video')); + +doTypesOverlap(schema, Media, StillImage); // => true +doTypesOverlap(schema, StillImage, Video); // => false +``` + +## Category: Typed Documents + +
+

+ Types:
+ TypedQueryDocumentNode +

+
+ +### Types + +#### TypedQueryDocumentNode + +**Interface.** Wrapper type that contains DocumentNode and types that can be deduced from it. + +
+ +
Type Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + +
NameConstraintDefaultDescription
TResponseDataTyped GraphQL response data shape.
TRequestVariablesTyped GraphQL request variables shape.
+ + + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
definitionsTop-level executable and type-system definitions in this document.
__ensureTypesOfVariablesAndResultMatching?This type is used to ensure that the variables you pass in to the query are assignable to Variables
+and that the Result is assignable to whatever you pass your result to. The method is never actually
+implemented, but the type is valid because we list it as optional
diff --git a/website/pages/api-v17/utilities/_meta.ts b/website/pages/api-v17/utilities/_meta.ts new file mode 100644 index 0000000000..a0121b6973 --- /dev/null +++ b/website/pages/api-v17/utilities/_meta.ts @@ -0,0 +1,48 @@ +const meta = { + 'type-info': { + title: 'Category: Type Info', + href: '/api-v17/utilities#category-type-info', + }, + values: { + title: 'Category: Values', + href: '/api-v17/utilities#category-values', + }, + 'schema-construction': { + title: 'Category: Schema Construction', + href: '/api-v17/utilities#category-schema-construction', + }, + introspection: { + title: 'Category: Introspection', + href: '/api-v17/utilities#category-introspection', + }, + 'ast-utilities': { + title: 'Category: AST Utilities', + href: '/api-v17/utilities#category-ast-utilities', + }, + 'schema-changes': { + title: 'Category: Schema Changes', + href: '/api-v17/utilities#category-schema-changes', + }, + operations: { + title: 'Category: Operations', + href: '/api-v17/utilities#category-operations', + }, + 'schema-printing': { + title: 'Category: Schema Printing', + href: '/api-v17/utilities#category-schema-printing', + }, + 'schema-coordinates': { + title: 'Category: Schema Coordinates', + href: '/api-v17/utilities#category-schema-coordinates', + }, + 'type-comparisons': { + title: 'Category: Type Comparisons', + href: '/api-v17/utilities#category-type-comparisons', + }, + 'typed-documents': { + title: 'Category: Typed Documents', + href: '/api-v17/utilities#category-typed-documents', + }, +}; + +export default meta; diff --git a/website/pages/api-v17/validation.mdx b/website/pages/api-v17/validation.mdx new file mode 100644 index 0000000000..1055533069 --- /dev/null +++ b/website/pages/api-v17/validation.mdx @@ -0,0 +1,4744 @@ +import { ApiSignature, ApiType } from '../../components/ApiCode'; + +Validate GraphQL documents and schemas with the specified validation rules. + +These exports are also available from the root `graphql` package. + +For documentation purposes, these exports are grouped into the following categories: + +- [Validation Context](/api-v17/validation#category-validation-context) +- [Validation Rules](/api-v17/validation#category-validation-rules) +- [Custom Rules](/api-v17/validation#category-custom-rules) +- [Validation](/api-v17/validation#category-validation) + +## Category: Validation Context + +
+

+ Classes:
+ ValidationContext +

+

+ Types:
+ ValidationRule +

+
+ +### Classes + +#### ValidationContext + +Validation context passed to query validation rules. + +
+ +##### Constructor + +Creates a ValidationContext instance. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
schemaSchema used to validate the document.
astDocument AST being validated.
typeInfoTypeInfo instance used to track traversal state.
onErrorCallback invoked for each validation error.
hideSuggestions?Whether suggestion text should be omitted from errors.
+ +##### getSchema() + +Returns the schema being used by this validation context. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The schema being validated against.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { buildSchema, TypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const context = new ValidationContext( + schema, + parse('{ greeting }'), + new TypeInfo(schema), + () => {}, +); + +context.getSchema().getQueryType()?.name; // => 'Query' +``` + +
+ +##### getVariableUsages() + +Returns variable usages found directly within this node. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
nodeThe AST node to inspect or visit.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Variable usages found directly within this node.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { buildSchema, TypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + greeting(name: String): String + } +`); +const document = parse('query ($name: String) { greeting(name: $name) }'); +const operation = document.definitions[0]; +const context = new ValidationContext( + schema, + document, + new TypeInfo(schema), + () => {}, +); + +const usages = context.getVariableUsages(operation); + +usages[0].node.name.value; // => 'name' +String(usages[0].type); // => 'String' +``` + +
+ +##### getRecursiveVariableUsages() + +Returns variable usages for an operation, including variables used by referenced fragments. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
operationOperation definition to inspect.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Variable usages reachable from the operation.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { buildSchema, TypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + viewer: User + } + + type User { + name(prefix: String): String + } +`); +const document = parse(` + query ($prefix: String) { + viewer { + ...UserName + } + } + + fragment UserName on User { + name(prefix: $prefix) + } +`); +const operation = document.definitions[0]; +const context = new ValidationContext( + schema, + document, + new TypeInfo(schema), + () => {}, +); + +const usages = context.getRecursiveVariableUsages(operation); + +usages.map((usage) => usage.node.name.value); // => ['prefix'] +``` + +
+ +##### getType() + +Returns the current output type at this point in traversal. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current output type, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse('{ greeting }'); +const typeInfo = new TypeInfo(schema); +const context = new ValidationContext(schema, document, typeInfo, () => {}); +let typeName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + Field: () => { + typeName = String(context.getType()); + }, + }), +); + +typeName; // => 'String' +``` + +
+ +##### getParentType() + +Returns the current parent composite type. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current parent composite type, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse('{ greeting }'); +const typeInfo = new TypeInfo(schema); +const context = new ValidationContext(schema, document, typeInfo, () => {}); +let parentTypeName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + Field: () => { + parentTypeName = context.getParentType()?.name; + }, + }), +); + +parentTypeName; // => 'Query' +``` + +
+ +##### getInputType() + +Returns the current input type at this point in traversal. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current input type, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + reviews(limit: Int): [String] + } +`); +const document = parse('{ reviews(limit: 5) }'); +const typeInfo = new TypeInfo(schema); +const context = new ValidationContext(schema, document, typeInfo, () => {}); +let inputTypeName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + Argument: () => { + inputTypeName = String(context.getInputType()); + }, + }), +); + +inputTypeName; // => 'Int' +``` + +
+ +##### getParentInputType() + +Returns the parent input type for the current input position. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The parent input type, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + input ReviewFilter { + stars: Int + } + + type Query { + reviews(filter: ReviewFilter): [String] + } +`); +const document = parse('{ reviews(filter: { stars: 5 }) }'); +const typeInfo = new TypeInfo(schema); +const context = new ValidationContext(schema, document, typeInfo, () => {}); +let parentInputTypeName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + ObjectField: () => { + parentInputTypeName = String(context.getParentInputType()); + }, + }), +); + +parentInputTypeName; // => 'ReviewFilter' +``` + +
+ +##### getFieldDef() + +Returns the current field definition. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current field definition, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse('{ greeting }'); +const typeInfo = new TypeInfo(schema); +const context = new ValidationContext(schema, document, typeInfo, () => {}); +let fieldName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + Field: () => { + fieldName = context.getFieldDef()?.name; + }, + }), +); + +fieldName; // => 'greeting' +``` + +
+ +##### getDirective() + +Returns the current directive definition. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current directive definition, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse('{ greeting @include(if: true) }'); +const typeInfo = new TypeInfo(schema); +const context = new ValidationContext(schema, document, typeInfo, () => {}); +let directiveName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + Directive: () => { + directiveName = context.getDirective()?.name; + }, + }), +); + +directiveName; // => 'include' +``` + +
+ +##### getArgument() + +Returns the current argument definition. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current argument definition, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + reviews(limit: Int): [String] + } +`); +const document = parse('{ reviews(limit: 5) }'); +const typeInfo = new TypeInfo(schema); +const context = new ValidationContext(schema, document, typeInfo, () => {}); +let argumentName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + Argument: () => { + argumentName = context.getArgument()?.name; + }, + }), +); + +argumentName; // => 'limit' +``` + +
+ +##### getFragmentSignature() + +Returns the fragment signature at the current traversal position. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current fragment signature, if one is active.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse( + ` + { + ...GreetingFields + } + + fragment GreetingFields on Query { + greeting + } + `, + { experimentalFragmentArguments: true }, +); +const typeInfo = new TypeInfo(schema); +const context = new ValidationContext(schema, document, typeInfo, () => {}); +let fragmentName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + FragmentSpread: () => { + fragmentName = context.getFragmentSignature()?.definition.name.value; + }, + }), +); + +fragmentName; // => 'GreetingFields' +``` + +
+ +##### getFragmentSignatureByName() + +Returns the function used to look up fragment signatures by name. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A function that maps fragment names to fragment signatures.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse( + ` + { + ...GreetingFields + } + + fragment GreetingFields on Query { + greeting + } + `, + { experimentalFragmentArguments: true }, +); +const typeInfo = new TypeInfo(schema); +const context = new ValidationContext(schema, document, typeInfo, () => {}); +let fragmentName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + Document: () => { + const getFragmentSignature = context.getFragmentSignatureByName(); + fragmentName = + getFragmentSignature('GreetingFields')?.definition.name.value; + }, + }), +); + +fragmentName; // => 'GreetingFields' +``` + +
+ +##### getEnumValue() + +Returns the current enum value definition. + +**Signature:** + + + +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
The current enum value definition, if known.
+ +
+ +
Example
+ +```ts +import { parse, visit } from 'graphql/language'; +import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities'; +import { ValidationContext } from 'graphql/validation'; + +const schema = buildSchema(` + enum Sort { + NEWEST + OLDEST + } + + type Query { + reviews(sort: Sort): [String] + } +`); +const document = parse('{ reviews(sort: OLDEST) }'); +const typeInfo = new TypeInfo(schema); +const context = new ValidationContext(schema, document, typeInfo, () => {}); +let enumValueName; + +visit( + document, + visitWithTypeInfo(typeInfo, { + EnumValue: () => { + enumValueName = context.getEnumValue()?.name; + }, + }), +); + +enumValueName; // => 'OLDEST' +``` + +### Types + +#### ValidationRule + +**Type alias.** A function that creates an AST visitor for validating a GraphQL document. + + + +## Category: Validation Rules + +
+

+ Functions:
+ DeferStreamDirectiveLabelRule() + + DeferStreamDirectiveOnRootFieldRule() + + DeferStreamDirectiveOnValidOperationsRule() + + ExecutableDefinitionsRule() + + FieldsOnCorrectTypeRule() + + FragmentsOnCompositeTypesRule() + + KnownArgumentNamesRule() + + KnownDirectivesRule() + + KnownFragmentNamesRule() + + KnownOperationTypesRule() + + KnownTypeNamesRule() + + LoneAnonymousOperationRule() + + LoneSchemaDefinitionRule() + + MaxIntrospectionDepthRule() + + NoFragmentCyclesRule() + + NoUndefinedVariablesRule() + + NoUnusedFragmentsRule() + + NoUnusedVariablesRule() + + OverlappingFieldsCanBeMergedRule() + + PossibleFragmentSpreadsRule() + + PossibleTypeExtensionsRule() + + ProvidedRequiredArgumentsRule() + + ScalarLeafsRule() + + SingleFieldSubscriptionsRule() + + StreamDirectiveOnListFieldRule() + + UniqueArgumentDefinitionNamesRule() + + UniqueArgumentNamesRule() + + UniqueDirectiveNamesRule() + + UniqueDirectivesPerLocationRule() + + UniqueEnumValueNamesRule() + + UniqueFieldDefinitionNamesRule() + + UniqueFragmentNamesRule() + + UniqueInputFieldNamesRule() + + UniqueOperationNamesRule() + + UniqueOperationTypesRule() + + UniqueTypeNamesRule() + + UniqueVariableNamesRule() + + ValuesOfCorrectTypeRule() + + VariablesAreInputTypesRule() + + VariablesInAllowedPositionRule() +

+

+ Constants:
+ recommendedRules + + specifiedRules +

+
+ +### Functions + +#### DeferStreamDirectiveLabelRule() + +Defer and stream directive labels are unique + +A GraphQL document is only valid if defer and stream directives' label argument is static and unique. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { validate, DeferStreamDirectiveLabelRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + friends: [String] + } +`); +const invalidDocument = parse(` + { + friends @stream(label: "friends") + other: friends @stream(label: "friends") + } +`); +const validDocument = parse(` + { + friends @stream(label: "friends") + other: friends @stream(label: "otherFriends") + } +`); + +validate(schema, invalidDocument, [DeferStreamDirectiveLabelRule]).length; // => 1 +validate(schema, validDocument, [DeferStreamDirectiveLabelRule]); // => [] +``` + +
+ +#### DeferStreamDirectiveOnRootFieldRule() + +Defer and stream directives are used on valid root field + +A GraphQL document is only valid if defer directives are not used on root mutation or subscription types. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { validate, DeferStreamDirectiveOnRootFieldRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + message: String + } + + type Mutation { + updateMessage: String + } +`); +const invalidDocument = parse(` + mutation { ... @defer { updateMessage } } +`); +const validDocument = parse(` + { ... @defer { message } } +`); + +validate(schema, invalidDocument, [DeferStreamDirectiveOnRootFieldRule]).length; // => 1 +validate(schema, validDocument, [DeferStreamDirectiveOnRootFieldRule]); // => [] +``` + +
+ +#### DeferStreamDirectiveOnValidOperationsRule() + +Defer And Stream Directives Are Used On Valid Operations + +A GraphQL document is only valid if defer directives are not used on root mutation or subscription types. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { + validate, + DeferStreamDirectiveOnValidOperationsRule, +} from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + message: Message + } + + type Subscription { + message: Message + } + + type Message { + body: String + } +`); +const invalidDocument = parse(` + subscription { + message { + ...MessageBody @defer + } + } + + fragment MessageBody on Message { + body + } +`); +const validDocument = parse(` + subscription { + message { + ...MessageBody @defer(if: false) + } + } + + fragment MessageBody on Message { + body + } +`); + +validate(schema, invalidDocument, [DeferStreamDirectiveOnValidOperationsRule]) + .length; // => 1 +validate(schema, validDocument, [DeferStreamDirectiveOnValidOperationsRule]); // => [] +``` + +
+ +#### ExecutableDefinitionsRule() + +Executable definitions + +A GraphQL document is only valid for execution if all definitions are either +operation or fragment definitions. + +See https://spec.graphql.org/draft/#sec-Executable-Definitions + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { ExecutableDefinitionsRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + type Extra { field: String } +`); +const invalidErrors = validate(schema, invalidDocument, [ExecutableDefinitionsRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { name } +`); +const validErrors = validate(schema, validDocument, [ExecutableDefinitionsRule]); + +validErrors; // => [] +``` + +
+ +#### FieldsOnCorrectTypeRule() + +Fields on correct type + +A GraphQL document is only valid if all fields selected are defined by the +parent type, or are an allowed meta field such as __typename. + +See https://spec.graphql.org/draft/#sec-Field-Selections + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { FieldsOnCorrectTypeRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + { missing } +`); +const invalidErrors = validate(schema, invalidDocument, [FieldsOnCorrectTypeRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { name } +`); +const validErrors = validate(schema, validDocument, [FieldsOnCorrectTypeRule]); + +validErrors; // => [] +``` + +
+ +#### FragmentsOnCompositeTypesRule() + +Fragments on composite type + +Fragments use a type condition to determine if they apply, since fragments +can only be spread into a composite type (object, interface, or union), the +type condition must also be a composite type. + +See https://spec.graphql.org/draft/#sec-Fragments-On-Composite-Types + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { FragmentsOnCompositeTypesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + fragment Bad on String { length } +`); +const invalidErrors = validate(schema, invalidDocument, [FragmentsOnCompositeTypesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + fragment Good on Query { name } +`); +const validErrors = validate(schema, validDocument, [FragmentsOnCompositeTypesRule]); + +validErrors; // => [] +``` + +
+ +#### KnownArgumentNamesRule() + +Known argument names + +A GraphQL field is only valid if all supplied arguments are defined by +that field. + +See https://spec.graphql.org/draft/#sec-Argument-Names +See https://spec.graphql.org/draft/#sec-Directives-Are-In-Valid-Locations + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { KnownArgumentNamesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + field(arg: String): String + } +`); + +const invalidDocument = parse(` + { field(unknown: "1") } +`); +const invalidErrors = validate(schema, invalidDocument, [KnownArgumentNamesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { field(arg: "1") } +`); +const validErrors = validate(schema, validDocument, [KnownArgumentNamesRule]); + +validErrors; // => [] +``` + +
+ +#### KnownDirectivesRule() + +Known directives + +A GraphQL document is only valid if all `@directives` are known by the +schema and legally positioned. + +See https://spec.graphql.org/draft/#sec-Directives-Are-Defined + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { KnownDirectivesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + { name @unknown } +`); +const invalidErrors = validate(schema, invalidDocument, [KnownDirectivesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { name @include(if: true) } +`); +const validErrors = validate(schema, validDocument, [KnownDirectivesRule]); + +validErrors; // => [] +``` + +
+ +#### KnownFragmentNamesRule() + +Known fragment names + +A GraphQL document is only valid if all `...Fragment` fragment spreads refer +to fragments defined in the same document. + +See https://spec.graphql.org/draft/#sec-Fragment-spread-target-defined + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { KnownFragmentNamesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + { ...Missing } +`); +const invalidErrors = validate(schema, invalidDocument, [KnownFragmentNamesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + fragment NameFields on Query { name } query { ...NameFields } +`); +const validErrors = validate(schema, validDocument, [KnownFragmentNamesRule]); + +validErrors; // => [] +``` + +
+ +#### KnownOperationTypesRule() + +Known Operation Types + +A GraphQL document is only valid if when it contains an operation, +the root type for the operation exists within the schema. + +See https://spec.graphql.org/draft/#sec-Operation-Type-Existence + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { validate, KnownOperationTypesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const invalidDocument = parse('mutation { greeting }'); +const validDocument = parse('{ greeting }'); + +validate(schema, invalidDocument, [KnownOperationTypesRule])[0].message; // => 'The mutation operation is not supported by the schema.' +validate(schema, validDocument, [KnownOperationTypesRule]); // => [] +``` + +
+ +#### KnownTypeNamesRule() + +Known type names + +A GraphQL document is only valid if referenced types (specifically +variable definitions and fragment conditions) are defined by the type schema. + +See https://spec.graphql.org/draft/#sec-Fragment-Spread-Type-Existence + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { KnownTypeNamesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + fragment Bad on Missing { name } +`); +const invalidErrors = validate(schema, invalidDocument, [KnownTypeNamesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + fragment Good on Query { name } +`); +const validErrors = validate(schema, validDocument, [KnownTypeNamesRule]); + +validErrors; // => [] +``` + +
+ +#### LoneAnonymousOperationRule() + +Lone anonymous operation + +A GraphQL document is only valid if when it contains an anonymous operation +(the query short-hand) that it contains only that one operation definition. + +See https://spec.graphql.org/draft/#sec-Lone-Anonymous-Operation + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { LoneAnonymousOperationRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + query { name } query Other { name } +`); +const invalidErrors = validate(schema, invalidDocument, [LoneAnonymousOperationRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { name } +`); +const validErrors = validate(schema, validDocument, [LoneAnonymousOperationRule]); + +validErrors; // => [] +``` + +
+ +#### LoneSchemaDefinitionRule() + +Lone Schema definition + +A GraphQL document is only valid if it contains only one schema definition. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql'; +import { LoneSchemaDefinitionRule } from 'graphql/validation'; + +const invalidSDL = ` + schema { query: Query } schema { query: Query } type Query { name: String } +`; + +LoneSchemaDefinitionRule.name; // => 'LoneSchemaDefinitionRule' +buildSchema(invalidSDL); // throws an error + +const validSDL = ` + schema { query: Query } type Query { name: String } +`; + +buildSchema(validSDL); // does not throw +``` + +
+ +#### MaxIntrospectionDepthRule() + +Implements the max introspection depth validation rule. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { MaxIntrospectionDepthRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + { __schema { types { fields { type { fields { type { fields { name } } } } } } } } +`); +const invalidErrors = validate(schema, invalidDocument, [MaxIntrospectionDepthRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { __schema { queryType { name } } } +`); +const validErrors = validate(schema, validDocument, [MaxIntrospectionDepthRule]); + +validErrors; // => [] +``` + +
+ +#### NoFragmentCyclesRule() + +No fragment cycles + +The graph of fragment spreads must not form any cycles including spreading itself. +Otherwise an operation could infinitely spread or infinitely execute on cycles in the underlying data. + +See https://spec.graphql.org/draft/#sec-Fragment-spreads-must-not-form-cycles + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { NoFragmentCyclesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + fragment A on Query { ...B } fragment B on Query { ...A } query { ...A } +`); +const invalidErrors = validate(schema, invalidDocument, [NoFragmentCyclesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + fragment A on Query { name } query { ...A } +`); +const validErrors = validate(schema, validDocument, [NoFragmentCyclesRule]); + +validErrors; // => [] +``` + +
+ +#### NoUndefinedVariablesRule() + +No undefined variables + +A GraphQL operation is only valid if all variables encountered, both directly +and via fragment spreads, are defined by that operation. + +See https://spec.graphql.org/draft/#sec-All-Variable-Uses-Defined + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { NoUndefinedVariablesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + field(arg: ID): String + } +`); + +const invalidDocument = parse(` + query ($id: ID) { field(arg: $missing) } +`); +const invalidErrors = validate(schema, invalidDocument, [NoUndefinedVariablesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + query ($id: ID) { field(arg: $id) } +`); +const validErrors = validate(schema, validDocument, [NoUndefinedVariablesRule]); + +validErrors; // => [] +``` + +
+ +#### NoUnusedFragmentsRule() + +No unused fragments + +A GraphQL document is only valid if all fragment definitions are spread +within operations, or spread within other fragments spread within operations. + +See https://spec.graphql.org/draft/#sec-Fragments-Must-Be-Used + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { NoUnusedFragmentsRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + fragment Unused on Query { name } query { name } +`); +const invalidErrors = validate(schema, invalidDocument, [NoUnusedFragmentsRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + fragment Used on Query { name } query { ...Used } +`); +const validErrors = validate(schema, validDocument, [NoUnusedFragmentsRule]); + +validErrors; // => [] +``` + +
+ +#### NoUnusedVariablesRule() + +No unused variables + +A GraphQL operation is only valid if all variables defined by an operation +are used, either directly or within a spread fragment. + +See https://spec.graphql.org/draft/#sec-All-Variables-Used + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { NoUnusedVariablesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + field(arg: ID): String + name: String + } +`); + +const invalidDocument = parse(` + query ($id: ID) { name } +`); +const invalidErrors = validate(schema, invalidDocument, [NoUnusedVariablesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + query ($id: ID) { field(arg: $id) } +`); +const validErrors = validate(schema, validDocument, [NoUnusedVariablesRule]); + +validErrors; // => [] +``` + +
+ +#### OverlappingFieldsCanBeMergedRule() + +Overlapping fields can be merged + +A selection set is only valid if all fields (including spreading any +fragments) either correspond to distinct response names or can be merged +without ambiguity. + +See https://spec.graphql.org/draft/#sec-Field-Selection-Merging + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { OverlappingFieldsCanBeMergedRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + dog: Dog + } + + type Dog { + name: String + barkVolume: Int + } +`); + +const invalidDocument = parse(` + { dog { value: barkVolume value: name } } +`); +const invalidErrors = validate(schema, invalidDocument, [OverlappingFieldsCanBeMergedRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { dog { barkVolume name } } +`); +const validErrors = validate(schema, validDocument, [OverlappingFieldsCanBeMergedRule]); + +validErrors; // => [] +``` + +
+ +#### PossibleFragmentSpreadsRule() + +Possible fragment spread + +A fragment spread is only valid if the type condition could ever possibly +be true: if there is a non-empty intersection of the possible parent types, +and possible types which pass the type condition. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { PossibleFragmentSpreadsRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + dog: Dog + } + + type Dog { + barkVolume: Int + } + + type Cat { + meowVolume: Int + } +`); + +const invalidDocument = parse(` + { dog { ... on Cat { meowVolume } } } +`); +const invalidErrors = validate(schema, invalidDocument, [PossibleFragmentSpreadsRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { dog { ... on Dog { barkVolume } } } +`); +const validErrors = validate(schema, validDocument, [PossibleFragmentSpreadsRule]); + +validErrors; // => [] +``` + +
+ +#### PossibleTypeExtensionsRule() + +Possible type extension + +A type extension is only valid if the type is defined and has the same kind. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql'; +import { PossibleTypeExtensionsRule } from 'graphql/validation'; + +const invalidSDL = ` + extend type Missing { name: String } type Query { name: String } +`; + +PossibleTypeExtensionsRule.name; // => 'PossibleTypeExtensionsRule' +buildSchema(invalidSDL); // throws an error + +const validSDL = ` + type Query { name: String } extend type Query { other: String } +`; + +buildSchema(validSDL); // does not throw +``` + +
+ +#### ProvidedRequiredArgumentsRule() + +Provided required arguments + +A field or directive is only valid if all required (non-null without a +default value) field arguments have been provided. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { ProvidedRequiredArgumentsRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + field(required: String!): String + } +`); + +const invalidDocument = parse(` + { field } +`); +const invalidErrors = validate(schema, invalidDocument, [ProvidedRequiredArgumentsRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { field(required: "x") } +`); +const validErrors = validate(schema, validDocument, [ProvidedRequiredArgumentsRule]); + +validErrors; // => [] +``` + +
+ +#### ScalarLeafsRule() + +Scalar leafs + +A GraphQL document is valid only if all leaf fields (fields without +sub selections) are of scalar or enum types. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { ScalarLeafsRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + { name { length } } +`); +const invalidErrors = validate(schema, invalidDocument, [ScalarLeafsRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { name } +`); +const validErrors = validate(schema, validDocument, [ScalarLeafsRule]); + +validErrors; // => [] +``` + +
+ +#### SingleFieldSubscriptionsRule() + +Subscriptions must only include a non-introspection field. + +A GraphQL subscription is valid only if it contains a single root field and +that root field is not an introspection field. + +See https://spec.graphql.org/draft/#sec-Single-root-field + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { SingleFieldSubscriptionsRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } + + type Subscription { + a: String + b: String + } +`); + +const invalidDocument = parse(` + subscription { a b } +`); +const invalidErrors = validate(schema, invalidDocument, [SingleFieldSubscriptionsRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + subscription { a } +`); +const validErrors = validate(schema, validDocument, [SingleFieldSubscriptionsRule]); + +validErrors; // => [] +``` + +
+ +#### StreamDirectiveOnListFieldRule() + +Stream directives are used on list fields + +A GraphQL document is only valid if stream directives are used on list fields. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { validate, StreamDirectiveOnListFieldRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + friends: [String] + } +`); +const invalidDocument = parse('{ name @stream(initialCount: 0) }'); +const validDocument = parse('{ friends @stream(initialCount: 0) }'); + +validate(schema, invalidDocument, [StreamDirectiveOnListFieldRule]).length; // => 1 +validate(schema, validDocument, [StreamDirectiveOnListFieldRule]); // => [] +``` + +
+ +#### UniqueArgumentDefinitionNamesRule() + +Unique argument definition names + +A GraphQL Object or Interface type is only valid if all its fields have uniquely named arguments. +A GraphQL Directive is only valid if all its arguments are uniquely named. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql'; +import { UniqueArgumentDefinitionNamesRule } from 'graphql/validation'; + +const invalidSDL = ` + type Query { field(arg: String, arg: Int): String } +`; + +UniqueArgumentDefinitionNamesRule.name; // => 'UniqueArgumentDefinitionNamesRule' +buildSchema(invalidSDL); // throws an error + +const validSDL = ` + type Query { field(arg: String): String } +`; + +buildSchema(validSDL); // does not throw +``` + +
+ +#### UniqueArgumentNamesRule() + +Unique argument names + +A GraphQL field or directive is only valid if all supplied arguments are +uniquely named. + +See https://spec.graphql.org/draft/#sec-Argument-Names + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { UniqueArgumentNamesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + field(arg: String): String + } +`); + +const invalidDocument = parse(` + { field(arg: "1", arg: "2") } +`); +const invalidErrors = validate(schema, invalidDocument, [UniqueArgumentNamesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { field(arg: "1") } +`); +const validErrors = validate(schema, validDocument, [UniqueArgumentNamesRule]); + +validErrors; // => [] +``` + +
+ +#### UniqueDirectiveNamesRule() + +Unique directive names + +A GraphQL document is only valid if all defined directives have unique names. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql'; +import { UniqueDirectiveNamesRule } from 'graphql/validation'; + +const invalidSDL = ` + directive @tag on FIELD directive @tag on QUERY type Query { name: String } +`; + +UniqueDirectiveNamesRule.name; // => 'UniqueDirectiveNamesRule' +buildSchema(invalidSDL); // throws an error + +const validSDL = ` + directive @tag on FIELD type Query { name: String } +`; + +buildSchema(validSDL); // does not throw +``` + +
+ +#### UniqueDirectivesPerLocationRule() + +Unique directive names per location + +A GraphQL document is only valid if all non-repeatable directives at +a given location are uniquely named. + +See https://spec.graphql.org/draft/#sec-Directives-Are-Unique-Per-Location + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { UniqueDirectivesPerLocationRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + { name @include(if: true) @include(if: false) } +`); +const invalidErrors = validate(schema, invalidDocument, [UniqueDirectivesPerLocationRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { name @include(if: true) } +`); +const validErrors = validate(schema, validDocument, [UniqueDirectivesPerLocationRule]); + +validErrors; // => [] +``` + +
+ +#### UniqueEnumValueNamesRule() + +Unique enum value names + +A GraphQL enum type is only valid if all its values are uniquely named. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql'; +import { UniqueEnumValueNamesRule } from 'graphql/validation'; + +const invalidSDL = ` + enum Status { ACTIVE ACTIVE } type Query { status: Status } +`; + +UniqueEnumValueNamesRule.name; // => 'UniqueEnumValueNamesRule' +buildSchema(invalidSDL); // throws an error + +const validSDL = ` + enum Status { ACTIVE INACTIVE } type Query { status: Status } +`; + +buildSchema(validSDL); // does not throw +``` + +
+ +#### UniqueFieldDefinitionNamesRule() + +Unique field definition names + +A GraphQL complex type is only valid if all its fields are uniquely named. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql'; +import { UniqueFieldDefinitionNamesRule } from 'graphql/validation'; + +const invalidSDL = ` + type Query { name: String name: String } +`; + +UniqueFieldDefinitionNamesRule.name; // => 'UniqueFieldDefinitionNamesRule' +buildSchema(invalidSDL); // throws an error + +const validSDL = ` + type Query { name: String other: String } +`; + +buildSchema(validSDL); // does not throw +``` + +
+ +#### UniqueFragmentNamesRule() + +Unique fragment names + +A GraphQL document is only valid if all defined fragments have unique names. + +See https://spec.graphql.org/draft/#sec-Fragment-Name-Uniqueness + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { UniqueFragmentNamesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + fragment A on Query { name } fragment A on Query { name } query { ...A } +`); +const invalidErrors = validate(schema, invalidDocument, [UniqueFragmentNamesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + fragment A on Query { name } query { ...A } +`); +const validErrors = validate(schema, validDocument, [UniqueFragmentNamesRule]); + +validErrors; // => [] +``` + +
+ +#### UniqueInputFieldNamesRule() + +Unique input field names + +A GraphQL input object value is only valid if all supplied fields are +uniquely named. + +See https://spec.graphql.org/draft/#sec-Input-Object-Field-Uniqueness + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { UniqueInputFieldNamesRule } from 'graphql/validation'; + +const schema = buildSchema(` + input Filter { + name: String + } + + type Query { + search(filter: Filter): String + } +`); + +const invalidDocument = parse(` + { search(filter: { name: "a", name: "b" }) } +`); +const invalidErrors = validate(schema, invalidDocument, [UniqueInputFieldNamesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { search(filter: { name: "a" }) } +`); +const validErrors = validate(schema, validDocument, [UniqueInputFieldNamesRule]); + +validErrors; // => [] +``` + +
+ +#### UniqueOperationNamesRule() + +Unique operation names + +A GraphQL document is only valid if all defined operations have unique names. + +See https://spec.graphql.org/draft/#sec-Operation-Name-Uniqueness + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { UniqueOperationNamesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + query Same { name } query Same { name } +`); +const invalidErrors = validate(schema, invalidDocument, [UniqueOperationNamesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + query One { name } query Two { name } +`); +const validErrors = validate(schema, validDocument, [UniqueOperationNamesRule]); + +validErrors; // => [] +``` + +
+ +#### UniqueOperationTypesRule() + +Unique operation types + +A GraphQL document is only valid if it has only one type per operation. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql'; +import { UniqueOperationTypesRule } from 'graphql/validation'; + +const invalidSDL = ` + schema { query: Query query: Other } type Query { name: String } type Other { name: String } +`; + +UniqueOperationTypesRule.name; // => 'UniqueOperationTypesRule' +buildSchema(invalidSDL); // throws an error + +const validSDL = ` + schema { query: Query } type Query { name: String } +`; + +buildSchema(validSDL); // does not throw +``` + +
+ +#### UniqueTypeNamesRule() + +Unique type names + +A GraphQL document is only valid if all defined types have unique names. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema } from 'graphql'; +import { UniqueTypeNamesRule } from 'graphql/validation'; + +const invalidSDL = ` + type Query { name: String } type Query { other: String } +`; + +UniqueTypeNamesRule.name; // => 'UniqueTypeNamesRule' +buildSchema(invalidSDL); // throws an error + +const validSDL = ` + type Query { name: String } type Other { name: String } +`; + +buildSchema(validSDL); // does not throw +``` + +
+ +#### UniqueVariableNamesRule() + +Unique variable names + +A GraphQL operation is only valid if all its variables are uniquely named. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { UniqueVariableNamesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + field(arg: ID): String + } +`); + +const invalidDocument = parse(` + query ($id: ID, $id: ID) { field(arg: $id) } +`); +const invalidErrors = validate(schema, invalidDocument, [UniqueVariableNamesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + query ($id: ID) { field(arg: $id) } +`); +const validErrors = validate(schema, validDocument, [UniqueVariableNamesRule]); + +validErrors; // => [] +``` + +
+ +#### ValuesOfCorrectTypeRule() + +Value literals of correct type + +A GraphQL document is only valid if all value literals are of the type +expected at their position. + +See https://spec.graphql.org/draft/#sec-Values-of-Correct-Type + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { ValuesOfCorrectTypeRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + count(limit: Int): Int + } +`); + +const invalidDocument = parse(` + { count(limit: "many") } +`); +const invalidErrors = validate(schema, invalidDocument, [ValuesOfCorrectTypeRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { count(limit: 1) } +`); +const validErrors = validate(schema, validDocument, [ValuesOfCorrectTypeRule]); + +validErrors; // => [] +``` + +
+ +#### VariablesAreInputTypesRule() + +Variables are input types + +A GraphQL operation is only valid if all the variables it defines are of +input types (scalar, enum, or input object). + +See https://spec.graphql.org/draft/#sec-Variables-Are-Input-Types + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { VariablesAreInputTypesRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + field(arg: ID): String + } + + type User { + name: String + } +`); + +const invalidDocument = parse(` + query ($user: User) { field(arg: "1") } +`); +const invalidErrors = validate(schema, invalidDocument, [VariablesAreInputTypesRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + query ($id: ID) { field(arg: $id) } +`); +const validErrors = validate(schema, validDocument, [VariablesAreInputTypesRule]); + +validErrors; // => [] +``` + +
+ +#### VariablesInAllowedPositionRule() + +Variables in allowed position + +Variable usages must be compatible with the arguments they are passed to. + +See https://spec.graphql.org/draft/#sec-All-Variable-Usages-are-Allowed + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { VariablesInAllowedPositionRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + field(arg: ID!): String + } +`); + +const invalidDocument = parse(` + query ($id: String) { field(arg: $id) } +`); +const invalidErrors = validate(schema, invalidDocument, [VariablesInAllowedPositionRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + query ($id: ID!) { field(arg: $id) } +`); +const validErrors = validate(schema, validDocument, [VariablesInAllowedPositionRule]); + +validErrors; // => [] +``` + +### Constants + +#### recommendedRules + +Technically these aren't part of the spec but they are strongly encouraged +validation rules. + +
+ +
Type
+ + + +
+ +#### specifiedRules + +This set includes all validation rules defined by the GraphQL spec. + +The order of the rules in this list has been adjusted to lead to the +most clear output when encountering multiple validation errors. + +
+ +
Type
+ + + +## Category: Custom Rules + + + +### Functions + +#### NoDeprecatedCustomRule() + +No deprecated + +A GraphQL document is only valid if all selected fields and all used enum values have not been +deprecated. + +Note: This rule is optional and is not part of the Validation section of the GraphQL +Specification. The main purpose of this rule is detection of deprecated usages and not +necessarily to forbid their use when querying a service. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { + GraphQLObjectType, + GraphQLSchema, + GraphQLString, + parse, + validate, +} from 'graphql'; +import { NoDeprecatedCustomRule } from 'graphql/validation'; + +const schema = new GraphQLSchema({ + query: new GraphQLObjectType({ + name: 'Query', + fields: { + name: { type: GraphQLString }, + oldName: { + type: GraphQLString, + deprecationReason: 'Use name instead.', + }, + }, + }), +}); + +const invalidDocument = parse(` + { oldName } +`); +const invalidErrors = validate(schema, invalidDocument, [NoDeprecatedCustomRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { name } +`); +const validErrors = validate(schema, validDocument, [NoDeprecatedCustomRule]); + +validErrors; // => [] +``` + +
+ +#### NoSchemaIntrospectionCustomRule() + +Prohibit introspection queries + +A GraphQL document is only valid if all fields selected are not fields that +return an introspection type. + +Note: This rule is optional and is not part of the Validation section of the +GraphQL Specification. This rule effectively disables introspection, which +does not reflect best practices and should only be done if absolutely necessary. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + +
NameTypeDescription
contextThe validation context used while checking the document.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
A visitor that reports validation errors for this rule.
+ +
+ +
Example
+ +```ts +import { buildSchema, parse, validate } from 'graphql'; +import { NoSchemaIntrospectionCustomRule } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + name: String + } +`); + +const invalidDocument = parse(` + { __schema { queryType { name } } } +`); +const invalidErrors = validate(schema, invalidDocument, [NoSchemaIntrospectionCustomRule]); + +invalidErrors.length; // => 1 + +const validDocument = parse(` + { name } +`); +const validErrors = validate(schema, validDocument, [NoSchemaIntrospectionCustomRule]); + +validErrors; // => [] +``` + +## Category: Validation + +
+

+ Functions:
+ validate() +

+

+ Types:
+ ValidationOptions +

+
+ +### Functions + +#### validate() + +Implements the "Validation" section of the spec. + +Validation runs synchronously, returning an array of encountered errors, or +an empty array if no errors were encountered and the document is valid. + +A list of specific validation rules may be provided. If not provided, the +default list of rules defined by the GraphQL specification will be used. + +Each validation rule is a function that returns a visitor +(see the language/visitor API). Visitor methods are expected to return +GraphQLErrors, or Arrays of GraphQLErrors when invalid. + +Validate will stop validation after a `maxErrors` limit has been reached. +Attackers can send pathologically invalid queries to induce a DoS attack, +so `maxErrors` defaults to 100 errors. + +**Signature:** + + + +
+ +
Arguments
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
schemaSchema to validate against.
documentASTDocument AST to validate.
rulesValidation rules to apply.
options?Validation options, including error limits and suggestions.
+ +
+ +
Returns
+ + + + + + + + + + + + + + +
TypeDescription
Validation errors, or an empty array when the document is valid.
+ +
+ +
Example 1
+ +```ts +// Validate with the default specified rules. +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { validate } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + fullName: String + } +`); + +validate(schema, parse('{ greeting }')); // => [] + +const errors = validate(schema, parse('{ missing }')); +errors[0].message; // => 'Cannot query field "missing" on type "Query".' +``` + +
+ +
Example 2
+ +```ts +// This variant uses a custom rule list and validation options. +import { parse } from 'graphql/language'; +import { buildSchema } from 'graphql/utilities'; +import { FieldsOnCorrectTypeRule, validate } from 'graphql/validation'; + +const schema = buildSchema(` + type Query { + greeting: String + } +`); +const document = parse('{ missingOne missingTwo }'); + +const errors = validate( + schema, + document, + [FieldsOnCorrectTypeRule], + { maxErrors: 1 }, +); + +errors.length; // => 2 +errors[1].message; // => 'Too many validation errors, error limit reached. Validation aborted.' + +const hiddenSuggestionErrors = validate( + schema, + parse('{ name }'), + [FieldsOnCorrectTypeRule], + { hideSuggestions: true }, +); + +hiddenSuggestionErrors[0].message; // => 'Cannot query field "name" on type "Query".' +``` + +### Types + +#### ValidationOptions + +**Interface.** Options used when validating a GraphQL document. + +
+ +
Members
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
maxErrors?Maximum number of validation errors before validation stops.
hideSuggestions?Whether suggestion text should be omitted from validation errors.
diff --git a/website/pages/api-v17/validation/_meta.ts b/website/pages/api-v17/validation/_meta.ts new file mode 100644 index 0000000000..a05fa0b6da --- /dev/null +++ b/website/pages/api-v17/validation/_meta.ts @@ -0,0 +1,20 @@ +const meta = { + 'validation-context': { + title: 'Category: Validation Context', + href: '/api-v17/validation#category-validation-context', + }, + 'validation-rules': { + title: 'Category: Validation Rules', + href: '/api-v17/validation#category-validation-rules', + }, + 'custom-rules': { + title: 'Category: Custom Rules', + href: '/api-v17/validation#category-custom-rules', + }, + validation: { + title: 'Category: Validation', + href: '/api-v17/validation#category-validation', + }, +}; + +export default meta; diff --git a/website/pages/docs/_meta.ts b/website/pages/docs/_meta.ts index 79f17fa754..cabe4d07e8 100644 --- a/website/pages/docs/_meta.ts +++ b/website/pages/docs/_meta.ts @@ -6,6 +6,9 @@ const meta = { }, 'getting-started': '', 'running-an-express-graphql-server': '', + 'graphql-http': { + display: 'hidden', + }, 'migrating-from-express-graphql': '', 'graphql-clients': '', 'authentication-and-express-middleware': '', diff --git a/website/pages/docs/graphql-http.mdx b/website/pages/docs/graphql-http.mdx new file mode 100644 index 0000000000..4d4c92636c --- /dev/null +++ b/website/pages/docs/graphql-http.mdx @@ -0,0 +1,56 @@ +--- +title: graphql-http +--- + +# `graphql-http` + +The official [`graphql-http`](https://github.com/graphql/graphql-http) package +provides a simple way to create a fully compliant GraphQL server. It has a +handler for Node.js native [`http`](https://nodejs.org/api/http.html), together +with handlers for well-known frameworks like +[Express](https://expressjs.com/), [Fastify](https://www.fastify.io/) and +[Koa](https://koajs.com/); as well as handlers for different runtimes like +[Deno](https://deno.land/) and [Bun](https://bun.sh/). + +`graphql-http` is a companion package, not part of the `graphql` npm package's +API surface. This page preserves the GraphQL.js docs context and points to the +official project for full server, client, and compliance documentation. + +## Official Resources + +- [graphql-http.com](https://graphql-http.com/) +- [GitHub repository](https://github.com/graphql/graphql-http) +- [npm package](https://www.npmjs.com/package/graphql-http) + +## Express + +```js +import { createHandler } from 'graphql-http/lib/use/express'; +``` + +### `createHandler` + +```ts +function createHandler({ + schema, + rootValue, + context, + formatError, + validationRules, +}: { + rootValue?: any; + context?: any; + formatError?: Function; + validationRules?: any[]; +}): Handler; +``` + +Constructs an Express handler based on a GraphQL schema. + +See [Running an Express GraphQL Server](/docs/running-an-express-graphql-server) +for sample usage. + +See [graphql-http.com](https://graphql-http.com/) and the +[GitHub README](https://github.com/graphql/graphql-http) for more extensive +documentation, including how to use `graphql-http` with other server +frameworks and runtimes. \ No newline at end of file diff --git a/website/theme.config.tsx b/website/theme.config.tsx index 270d99a1eb..e7b1cb6c33 100644 --- a/website/theme.config.tsx +++ b/website/theme.config.tsx @@ -237,6 +237,7 @@ const cfg: DocsThemeConfig = { hue: 319, }, sidebar: { + autoCollapse: true, defaultMenuCollapseLevel: 1, }, footer: { diff --git a/website/typedoc-api.json b/website/typedoc-api.json new file mode 100644 index 0000000000..f4f3c8373c --- /dev/null +++ b/website/typedoc-api.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "name": "GraphQL.js API", + "entryPoints": [], + "entryPointStrategy": "resolve", + "json": "", + "readme": "none", + "disableSources": true, + "githubPages": false, + "skipErrorChecking": true, + "treatValidationWarningsAsErrors": true, + "excludeInternal": true, + "excludePrivate": true, + "validation": { + "notExported": false + }, + "categorizeByGroup": true, + "sort": ["source-order"], + "tsconfig": "" +} From b43ccb11a4e29fb865d0a73ca6f80c50909a2cb2 Mon Sep 17 00:00:00 2001 From: Yaacov Rydzinski Date: Wed, 20 May 2026 02:50:30 +0300 Subject: [PATCH 2/2] docs: refresh upgrade guide and v17 topics (#4737) --- website/pages/docs/_meta.ts | 29 +- website/pages/docs/abort-signals.mdx | 277 ++++++++ .../pages/docs/advanced-custom-scalars.mdx | 42 +- .../docs/advanced-execution-pipelines.mdx | 186 ++++++ website/pages/docs/custom-scalars.mdx | 71 +- website/pages/docs/defer-stream.mdx | 186 +++++- .../pages/docs/directives-on-directives.mdx | 130 ++++ website/pages/docs/execution-hooks.mdx | 192 ++++++ .../experimental-specification-features.mdx | 55 ++ website/pages/docs/fragment-arguments.mdx | 140 ++++ website/pages/docs/getting-started.mdx | 24 +- website/pages/docs/graphql-clients.mdx | 55 +- website/pages/docs/graphql-harness.mdx | 154 +++++ website/pages/docs/index.mdx | 27 +- .../pages/docs/mutations-and-input-types.mdx | 35 + website/pages/docs/oneof-input-objects.mdx | 22 +- website/pages/docs/passing-arguments.mdx | 47 ++ website/pages/docs/schema-coordinates.mdx | 128 ++++ website/pages/docs/schema-evolution.mdx | 177 +++++ website/pages/docs/subscriptions.mdx | 39 +- website/pages/upgrade-guides/v16-v17.mdx | 609 ++++++++++++++---- website/vercel.json | 5 + 22 files changed, 2432 insertions(+), 198 deletions(-) create mode 100644 website/pages/docs/abort-signals.mdx create mode 100644 website/pages/docs/advanced-execution-pipelines.mdx create mode 100644 website/pages/docs/directives-on-directives.mdx create mode 100644 website/pages/docs/execution-hooks.mdx create mode 100644 website/pages/docs/experimental-specification-features.mdx create mode 100644 website/pages/docs/fragment-arguments.mdx create mode 100644 website/pages/docs/graphql-harness.mdx create mode 100644 website/pages/docs/schema-coordinates.mdx create mode 100644 website/pages/docs/schema-evolution.mdx diff --git a/website/pages/docs/_meta.ts b/website/pages/docs/_meta.ts index cabe4d07e8..dffed77ed8 100644 --- a/website/pages/docs/_meta.ts +++ b/website/pages/docs/_meta.ts @@ -23,14 +23,31 @@ const meta = { nullability: '', 'abstract-types': '', 'custom-scalars': '', + 'constructing-types': '', + 'oneof-input-objects': '', + 'schema-coordinates': '', + 'schema-evolution': '', + subscriptions: '', '-- 3': { type: 'separator', - title: 'Advanced Guides', + title: 'Experimental Specification Features', }, - 'constructing-types': '', - 'oneof-input-objects': '', + 'experimental-specification-features': '', 'defer-stream': '', - subscriptions: '', + 'fragment-arguments': '', + 'directives-on-directives': '', + '-- 4': { + type: 'separator', + title: 'GraphQL.js Runtime Features', + }, + 'graphql-harness': '', + 'advanced-execution-pipelines': '', + 'abort-signals': '', + 'execution-hooks': '', + '-- 5': { + type: 'separator', + title: 'Advanced Guides', + }, 'type-generation': '', 'cursor-based-pagination': '', 'advanced-custom-scalars': '', @@ -41,7 +58,7 @@ const meta = { 'graphql-errors': '', 'using-directives': '', 'authorization-strategies': '', - '-- 4': { + '-- 6': { type: 'separator', title: 'Testing', }, @@ -50,7 +67,7 @@ const meta = { 'testing-operations': '', 'testing-resolvers': '', 'testing-best-practices': '', - '-- 5': { + '-- 7': { type: 'separator', title: 'Production & Scaling', }, diff --git a/website/pages/docs/abort-signals.mdx b/website/pages/docs/abort-signals.mdx new file mode 100644 index 0000000000..5238a0871e --- /dev/null +++ b/website/pages/docs/abort-signals.mdx @@ -0,0 +1,277 @@ +--- +title: Handling Abort Signals +sidebarTitle: Abort Signals +--- + +import { Callout } from 'nextra/components'; + +# Handling Abort Signals + + + Abort signal support is available in GraphQL.js v17 and newer. It is a + GraphQL.js runtime API, not GraphQL syntax or a transport protocol. + + +## What the specification says + +The GraphQL specification mentions cancellation in a narrow execution case. +During ordinary execution, when a non-null execution error propagates to a +parent response position, sibling response positions that have not executed or +yielded a value +[may be cancelled](https://spec.graphql.org/draft/#sec-Errors-and-Non-Null-Types) +to avoid unnecessary work. The +[conformance appendix](https://spec.graphql.org/draft/#sec-Appendix-Conformance) +makes lowercase key words in normative portions of the specification carry +their RFC 2119 meaning, so this is a normative `MAY`. It permits cancellation; +it does not require every implementation to cancel work in that case. + +The subscription algorithms also describe cancellation of response streams and +source streams. Those algorithms are still about GraphQL execution and stream +lifecycle, not about a user or host cancelling a request that is already in +flight. + +The specification does not define a cancellation primitive or a transport +cancellation protocol. + +## What GraphQL.js v17 adds + +GraphQL.js v17 exposes cancellation for two related situations: + +- Internally, GraphQL.js can signal work that no longer contributes to the + returned result, such as work from response positions cancelled under the + specification's execution rules. +- Externally, a host can pass `abortSignal` to `execute()`, `subscribe()`, + `graphql()`, or `experimentalExecuteIncrementally()` to cancel an issued + request while it is in flight. + +Both cases matter because long-running GraphQL operations often start other +asynchronous work: database queries, HTTP requests, async iterators, loaders, +and subscription streams. In v16, GraphQL.js had no standard way to ask that +work to stop. In v17, GraphQL.js uses `AbortSignal` as its JavaScript runtime +API for cancellation. + +GraphQL.js v17 uses the same resolver-scoped signal for internal cancellation +and external request cancellation. Resolvers read that shared signal with +`info.getAbortSignal()` and pass it to downstream APIs that support +cancellation. + +Abort signals are cooperative. They let GraphQL.js and resolvers pass a +cancellation request to downstream work, but JavaScript cannot force an +arbitrary promise, database driver, HTTP client, or async iterator to stop. The +downstream API has to accept the signal and honor it. + +GraphQL.js does not currently provide fine-grained per-field or per-branch +abort signals. Resolvers in an operation share one resolver `AbortSignal`. For +internally cancelled portions of an operation, GraphQL.js aborts that shared +signal when the result that will actually be returned has finished, notifying +pending resolver work together. An external abort also aborts the same shared +resolver signal. This coarseness may change in future versions. + +## Using the signal in resolvers + +Resolvers obtain the abort signal via `info.getAbortSignal()`. Pass that +signal to downstream APIs that support cancellation. + +```js +const Query = new GraphQLObjectType({ + name: 'Query', + fields: { + user: { + type: User, + args: { id: { type: new GraphQLNonNull(GraphQLID) } }, + async resolve(_source, args, _context, info) { + const abortSignal = info.getAbortSignal(); + + const response = await fetch(`https://users.example/${args.id}`, { + signal: abortSignal, + }); + + return response.json(); + }, + }, + }, +}); +``` + +As noted, this signal can be triggered by GraphQL.js itself. For example, +suppose a query selects `user { profile recommendations }`, `profile` is +non-null, and the `recommendations` resolver starts a slow downstream request. +If `profile` throws and the error bubbles so that `user` becomes `null`, the +`recommendations` result can no longer appear in the response. GraphQL.js does +not currently create a separate signal for that one sibling branch. Instead, +when the response that will actually be returned has finished, GraphQL.js +aborts the shared resolver signal, so any still-pending resolver work that +honors the signal can stop together. + +For work that does not accept `AbortSignal`, check the signal before starting +and again between expensive steps. This is useful even for synchronous chunks: +JavaScript cannot interrupt code that is already running, but the next check can +avoid starting more work. + +```js +async function loadReport(info) { + const abortSignal = info.getAbortSignal(); + + if (abortSignal?.aborted) { + throw abortSignal.reason; + } + + const rows = await loadReportRows(); + + if (abortSignal?.aborted) { + throw abortSignal.reason; + } + + const totals = calculateTotals(rows); + + if (abortSignal?.aborted) { + throw abortSignal.reason; + } + + return formatReport(totals); +} +``` + +If the API exposes its own cancellation method, connect the abort event to that +method: + +```js +async function loadReportFromJob(info) { + const abortSignal = info.getAbortSignal(); + + if (abortSignal?.aborted) { + throw abortSignal.reason; + } + + const job = startReportJob(); + abortSignal?.addEventListener( + 'abort', + () => { + job.cancel(); + }, + { once: true }, + ); + + return job.result; +} +``` + +Here `startReportJob()` represents an async API that does not accept +`AbortSignal` directly, but does return an object with a `result` promise and a +`cancel()` method. + +## Passing an external signal to execution + +GraphQL.js also lets a host cancel an issued request while it is in flight. +Pass `abortSignal` to `graphql()`, `execute()`, `subscribe()`, or +`experimentalExecuteIncrementally()`. If that external signal is aborted, +GraphQL.js aborts the same resolver signal exposed through +`info.getAbortSignal()`. + +```js +import { execute, parse } from 'graphql'; + +const controller = new AbortController(); +const document = parse(` + query User($id: ID!) { + user(id: $id) { + id + name + } + } +`); + +const resultPromise = execute({ + schema, + document, + variableValues: { id: '123' }, + abortSignal: controller.signal, +}); + +setTimeout(() => { + controller.abort(new Error('Request timed out')); +}, 500); + +const result = await resultPromise; +``` + +If the signal is aborted before execution finishes, asynchronous execution +rejects. The abort reason becomes the rejection cause when possible. + +## Wiring HTTP request life cycles + +Most servers already know when a request is no longer useful: the client +disconnects, a gateway timeout fires, or a framework cancellation token is +triggered. Bridge that lifecycle to GraphQL.js so resolver cancellation follows +request cancellation. + +```js +const controller = new AbortController(); + +req.on('close', () => { + controller.abort(new Error('Client disconnected')); +}); + +const result = await execute({ + schema, + document, + variableValues, + contextValue, + abortSignal: controller.signal, +}); +``` + +This helps avoid expensive resolver work after the client is already gone. + +## Handling aborted execution + +GraphQL.js rejects with `AbortedGraphQLExecutionError` when execution is +aborted after it has started. The error exposes the best partial result +GraphQL.js can still produce. + +```js +import { AbortedGraphQLExecutionError, execute } from 'graphql'; + +try { + const result = await execute({ + schema, + document, + abortSignal, + }); + return result; +} catch (error) { + if (error instanceof AbortedGraphQLExecutionError) { + const partialResult = await error.abortedResult; + logger.info({ partialResult }, 'GraphQL execution aborted'); + } + + throw error; +} +``` + +`abortedResult` may be either a result or a promise for a result. For +incremental delivery, it may contain the initial incremental result if that was +already available. + +## Observing async cleanup + +An abort can stop GraphQL.js from producing more response data before every +tracked async task has settled. Cleanup can continue after the response +boundary, especially when resolvers use async iterators or when downstream +libraries perform their own shutdown work. + +Use the experimental `asyncWorkFinished` execution hook when a host needs to +observe that boundary. See [Execution Hooks](/docs/execution-hooks) for +examples of logging cleanup completion, delaying response delivery until +tracked work settles, and tracking resolver-started async work. + +## Practical guidance + +- Treat abort as cooperative cancellation. A resolver or downstream client that + ignores the signal may keep doing work outside GraphQL.js. +- Pass the signal to downstream clients early, before starting expensive work. +- Avoid swallowing abort errors in resolvers. Let GraphQL.js stop the operation. +- Keep request timeouts at the server or transport layer, and connect those + timeouts to an `AbortController`. +- Do not expose abort signals in the GraphQL schema. They are a JavaScript + runtime concern, not client query syntax. diff --git a/website/pages/docs/advanced-custom-scalars.mdx b/website/pages/docs/advanced-custom-scalars.mdx index b71aa450fc..930284b283 100644 --- a/website/pages/docs/advanced-custom-scalars.mdx +++ b/website/pages/docs/advanced-custom-scalars.mdx @@ -2,11 +2,39 @@ title: Best Practices for Custom Scalars --- +import { Callout } from 'nextra/components'; + # Custom Scalars: Best Practices and Testing Custom scalars must behave predictably and clearly. To maintain a consistent, reliable schema, follow these best practices. + + GraphQL.js v17 renames the scalar hooks to the coercion terms used by the + specification. The v16 names still work in v17, but are deprecated for + removal in v18. + + +### Map v16 names to v17 names + +| v16 name | v17 name | Purpose | +| --- | --- | --- | +| `serialize` | `coerceOutputValue` | Convert resolver values into response values. | +| `parseValue` | `coerceInputValue` | Convert variable values into internal values. | +| `parseLiteral` | `coerceInputLiteral` | Convert constant GraphQL literals into internal values. | +| `astFromValue()` | `valueToLiteral()` | Convert external input values into GraphQL literals. | + +If your scalar supports both v16 and v17, keep the v16 method names for now. +When your minimum version is v17, implement the v17 names and add +`valueToLiteral()` if tooling needs to print defaults or external values for +that scalar. + +In v16, `parseLiteral(ast, variables)` could receive variable values directly. +In v17, `coerceInputLiteral()` receives a constant literal. During execution, +GraphQL.js calls `replaceVariables()` before scalar literal coercion. If +tooling calls `coerceInputLiteral()` directly outside execution, it must call +`replaceVariables()` first. + ### Document expected formats and validation Provide a clear description of the scalar's accepted input and output formats. For example, a @@ -14,11 +42,12 @@ Provide a clear description of the scalar's accepted input and output formats. F Clear descriptions help clients understand valid input and reduce mistakes. -### Validate consistently across `parseValue` and `parseLiteral` +### Validate consistently across value and literal coercion Clients can send values either through variables or inline literals. -Your `parseValue` and `parseLiteral` functions should apply the same validation logic in -both cases. +Your value and literal coercion functions should apply the same validation +logic in both cases. In v16 those functions are `parseValue` and +`parseLiteral`; in v17 they are `coerceInputValue` and `coerceInputLiteral`. Use a shared helper to avoid duplication: @@ -32,7 +61,7 @@ function parseDate(value) { } ``` -Both `parseValue` and `parseLiteral` should call this function. +Both input coercion paths should call this function. ### Return clear errors @@ -69,8 +98,9 @@ Tests should cover three areas: coercion functions, schema integration, and erro ### Unit test serialization and parsing -Write unit tests for each function: `serialize`, `parseValue`, and `parseLiteral`. -Test with both valid and invalid inputs. +Write unit tests for each function: `serialize`, `parseValue`, and +`parseLiteral` in v16, or `coerceOutputValue`, `coerceInputValue`, and +`coerceInputLiteral` in v17. Test with both valid and invalid inputs. ```js describe('DateTime scalar', () => { diff --git a/website/pages/docs/advanced-execution-pipelines.mdx b/website/pages/docs/advanced-execution-pipelines.mdx new file mode 100644 index 0000000000..85a82059e5 --- /dev/null +++ b/website/pages/docs/advanced-execution-pipelines.mdx @@ -0,0 +1,186 @@ +--- +title: Advanced Execution Pipelines +sidebarTitle: Advanced Execution Pipelines +--- + +import { Callout } from 'nextra/components'; + +# Advanced Execution Pipelines + + + The APIs on this page are low-level GraphQL.js v17 execution APIs. Most + servers should call `execute()`, `subscribe()`, or a framework abstraction. + + +GraphQL.js v17 exposes validated execution argument objects so hosts can split +the execution step without rebuilding GraphQL.js internals. These helpers are +for code that already has a parsed document and has decided to execute it. A +complete request pipeline still needs to parse, validate, authorize, execute, +and serialize results in the places that make sense for the host. + +The central types are `ValidatedExecutionArgs` and +`ValidatedSubscriptionArgs`. The validator functions return one of those +objects, or a list of `GraphQLError` values that can be returned as the +operation result. They validate and normalize execution arguments; they do not +replace operation validation with `validate()`. + +## Build a custom `execute()` + +`validateExecutionArgs()` checks the schema, selects the operation, coerces +variables, prepares fragment information, and fills in default resolvers and +execution options. `executeRootSelectionSet()` then runs the same +single-result root selection set executor used by `execute()`. + +```js +import { executeRootSelectionSet, validateExecutionArgs } from 'graphql'; + +function executeWithTiming(args) { + const startedAt = Date.now(); + const validatedArgs = validateExecutionArgs(args); + + if (!('schema' in validatedArgs)) { + return { errors: validatedArgs }; + } + + const result = executeRootSelectionSet(validatedArgs); + const addTiming = (executionResult) => { + return { + ...executionResult, + extensions: { + ...executionResult.extensions, + durationMs: Date.now() - startedAt, + }, + }; + }; + + return typeof result.then === 'function' ? result.then(addTiming) : addTiming(result); +} +``` + +The native `execute()` and `subscribe()` functions preserve synchronous results +when execution completes synchronously. They do not wrap every result in a +promise. Custom wrappers that want the same behavior need to handle both the +synchronous and asynchronous paths, which is why the example returns either an +`ExecutionResult` or a promise for one. + +For incremental delivery, use +`experimentalExecuteRootSelectionSet(validatedArgs)` instead. It accepts the +same `ValidatedExecutionArgs` object and returns either an `ExecutionResult` or +the experimental incremental result shape. + +## Build a custom `subscribe()` + +`validateSubscriptionArgs()` performs the same base validation and also asserts +that the selected operation is a subscription. `createSourceEventStream()` +expects the resulting `ValidatedSubscriptionArgs` object and resolves the +source event stream from the root subscription field. + +```js +import { + createSourceEventStream, + mapSourceToResponseEvent, + validateSubscriptionArgs, +} from 'graphql'; + +function subscribeWithHostPipeline(args) { + const validatedArgs = validateSubscriptionArgs(args); + + if (!('schema' in validatedArgs)) { + return { errors: validatedArgs }; + } + + const source = createSourceEventStream(validatedArgs); + const mapSource = (sourceEventStream) => { + if ( + sourceEventStream == null || + typeof sourceEventStream[Symbol.asyncIterator] !== 'function' + ) { + return sourceEventStream; + } + + return mapSourceToResponseEvent(validatedArgs, sourceEventStream); + }; + + return typeof source.then === 'function' ? source.then(mapSource) : mapSource(source); +} +``` + +Subscription execution has two phases: + +1. Create the source event stream. +2. Execute the subscription selection set once for each source event. + +`subscribe()` performs both phases for you. The lower-level helpers are useful +when a host owns one phase directly, for example when source events are +produced by a broker process and response execution happens in a separate +worker. + +`mapSourceToResponseEvent()` maps each source event into an `ExecutionResult`. +With two arguments, it uses the default subscription event executor. + +## Customize per-event execution + +The third argument to `mapSourceToResponseEvent()` is a +`RootSelectionSetExecutor`. That function receives the validated subscription +arguments for one source event. It is responsible for executing the +subscription selection set for that event and returning an `ExecutionResult`, +or a promise for one. + +By default, `mapSourceToResponseEvent()` uses `executeSubscriptionEvent()` as +that executor. Pass a custom executor when each event needs extra context, +instrumentation, or execution policy. + +```js +import { + createSourceEventStream, + executeSubscriptionEvent, + mapSourceToResponseEvent, + validateSubscriptionArgs, +} from 'graphql'; + +const validatedArgs = validateSubscriptionArgs({ + schema, + document, + contextValue, + variableValues, + operationName, +}); + +if (!('schema' in validatedArgs)) { + return { errors: validatedArgs }; +} + +const source = await createSourceEventStream(validatedArgs); + +if (source == null || typeof source[Symbol.asyncIterator] !== 'function') { + return source; +} + +const stream = mapSourceToResponseEvent( + validatedArgs, + source, + (validatedEventArgs) => + executeSubscriptionEvent({ + ...validatedEventArgs, + contextValue: { + requestContext: validatedEventArgs.contextValue, + sourceEventStartedAt: Date.now(), + }, + }), +); +``` + +## Choosing the right API + +- Use `execute()` or `subscribe()` when the built-in execution behavior is + enough. +- Use [GraphQL Harness](/docs/graphql-harness) when you want to replace the + parse, validate, execute, or subscribe phase used by `graphql()`. +- Use the helpers on this page when you are building a custom execution or + subscription function and need the same validated argument objects that + GraphQL.js uses internally. + +These helpers do not replace request parsing, validation, transport framing, or +response serialization. They give hosts precise control over the execution +boundary while keeping GraphQL.js's argument normalization, variable coercion, +fragment handling, and default resolver behavior intact. diff --git a/website/pages/docs/custom-scalars.mdx b/website/pages/docs/custom-scalars.mdx index 043a729b29..d50c8fbf6c 100644 --- a/website/pages/docs/custom-scalars.mdx +++ b/website/pages/docs/custom-scalars.mdx @@ -2,6 +2,8 @@ title: Using Custom Scalars --- +import { Callout } from 'nextra/components'; + # Custom Scalars: When and How to Use Them In GraphQL, scalar types represent primitive data like strings, numbers, and booleans. @@ -21,6 +23,14 @@ Here’s a simple example of a custom scalar that handles date-time strings: ```js import { GraphQLScalarType, Kind } from 'graphql'; +function parseDate(value) { + const date = new Date(value); + if (isNaN(date.getTime())) { + throw new TypeError(`DateTime cannot represent an invalid date: ${value}`); + } + return date; +} + const DateTime = new GraphQLScalarType({ name: 'DateTime', description: 'An ISO-8601 encoded UTC date string.', @@ -126,6 +136,65 @@ const DateTime = new GraphQLScalarType({ These functions give you full control over validation and data flow. +## v17 scalar method names + + + GraphQL.js v16 uses `serialize`, `parseValue`, and `parseLiteral`. GraphQL.js + v17 keeps those names as deprecated aliases and introduces names that match + the GraphQL specification's coercion terminology. + + +When writing code that only needs to run on v17 and newer, prefer: + +- `coerceOutputValue`: Result coercion for values returned by resolvers. +- `coerceInputValue`: Input coercion for variable values. +- `coerceInputLiteral`: Input coercion for constant GraphQL literals. +- `valueToLiteral`: Conversion from an external input value to a GraphQL + literal. + +During execution, GraphQL.js replaces variables before calling +`coerceInputLiteral()`. If tooling or application code calls scalar literal +coercion directly outside execution, it must call `replaceVariables()` itself +before passing the literal to `coerceInputLiteral()`. + +```js +import { GraphQLScalarType, Kind } from 'graphql'; + +const DateTime = new GraphQLScalarType({ + name: 'DateTime', + description: 'An ISO-8601 encoded UTC date string.', + + coerceOutputValue(value) { + if (!(value instanceof Date)) { + throw new TypeError('DateTime can only serialize Date instances'); + } + return value.toISOString(); + }, + + coerceInputValue(value) { + return parseDate(value); + }, + + coerceInputLiteral(ast) { + if (ast.kind !== Kind.STRING) { + throw new TypeError( + `DateTime can only parse string values, but got: ${ast.kind}`, + ); + } + return parseDate(ast.value); + }, + + valueToLiteral(value) { + if (typeof value === 'string') { + return { kind: Kind.STRING, value, block: false }; + } + }, +}); +``` + +If you need one scalar definition that supports both v16 and v17, keep the +v16 method names until your minimum GraphQL.js version is v17. + ## Learn more -- [Custom Scalars: Best Practices and Testing](./advanced-custom-scalars): Dive deeper into validation, testing, and building production-grade custom scalars. \ No newline at end of file +- [Custom Scalars: Best Practices and Testing](./advanced-custom-scalars): Dive deeper into validation, testing, and building production-grade custom scalars. diff --git a/website/pages/docs/defer-stream.mdx b/website/pages/docs/defer-stream.mdx index d52296f0a5..5252fa26a5 100644 --- a/website/pages/docs/defer-stream.mdx +++ b/website/pages/docs/defer-stream.mdx @@ -1,23 +1,35 @@ --- -title: Enabling Defer & Stream +title: Enabling Defer and Stream +sidebarTitle: Defer and Stream --- +import { Callout } from 'nextra/components'; + # Enabling Defer and Stream -import { Callout } from 'nextra/components' - - - These exports are only available in v17 and beyond. + + `@defer`, `@stream`, and `experimentalExecuteIncrementally()` are available + in GraphQL.js v17 and newer. Incremental delivery is pending GraphQL + specification work. -The `@defer` and `@stream` directives are not enabled by default. -In order to use these directives, you must add them to your GraphQL Schema and -use the `experimentalExecuteIncrementally` function instead of `execute`. +`@defer` and `@stream` allow a GraphQL operation to produce an initial result +and later incremental payloads. This is useful when part of a response is slow, +large, or naturally delivered over time. + +GraphQL.js keeps this feature explicit. You must add the directives to the +schema and use the experimental executor. + +## Add the directives to your schema + +If the `directives` option is passed to `GraphQLSchema`, the default directive +list is replaced. Include `specifiedDirectives` when adding experimental +directives. ```js import { - GraphQLSchema, GraphQLDeferDirective, + GraphQLSchema, GraphQLStreamDirective, specifiedDirectives, } from 'graphql'; @@ -30,11 +42,163 @@ const schema = new GraphQLSchema({ GraphQLStreamDirective, ], }); +``` + +Once a schema includes `@defer` or `@stream`, execute operations against that +schema with `experimentalExecuteIncrementally()`. `execute()` is the +single-result executor and will reject schemas that contain the experimental +incremental directives. + +## Execute incrementally + +```js +import { experimentalExecuteIncrementally, parse } from 'graphql'; + +const document = parse(` + query ProductPage { + product(id: "abc") { + id + name + ...Reviews @defer(label: "reviews") + } + } + + fragment Reviews on Product { + reviews { + body + rating + } + } +`); + +const result = await experimentalExecuteIncrementally({ + schema, + document, +}); +``` + +The result is either a normal `ExecutionResult` or an incremental result object. + +```js +if ('initialResult' in result) { + sendInitialPayload(result.initialResult); + + for await (const subsequentResult of result.subsequentResults) { + sendIncrementalPayload(subsequentResult); + } +} else { + sendSinglePayload(result); +} +``` + +GraphQL.js produces the execution results; your server transport is responsible +for serializing and delivering them to the client. + +## Transport framing guidance + +`experimentalExecuteIncrementally()` gives you result objects, not a wire +protocol. Pick a transport framing format that your clients already support and +test it end to end. + +- HTTP multipart responses for clients that support incremental patches. +- Server-sent events when your stack already uses event streams. +- WebSocket message streams for subscription-like transports. + +Keep transport concerns separate from execution concerns: validate operation +behavior first, then validate framing and client reassembly separately. + +## `@defer` -const result = experimentalExecuteIncrementally({ +`@defer` can be applied to fragment spreads and inline fragments. It defers the +fragment when `if` is `true` or omitted. + +```graphql +query ProductPage($includeReviews: Boolean! = true) { + product(id: "abc") { + id + name + ...Reviews @defer(if: $includeReviews, label: "reviews") + } +} +``` + +The `label` argument is optional, but labels must be unique for active +`@defer` and `@stream` usages in the operation. + +## `@stream` + +`@stream` can be applied to list fields. It sends `initialCount` items in the +initial result and streams later items in subsequent payloads. + +```graphql +query Feed { + feed(first: 100) @stream(initialCount: 10, label: "feed") { + id + title + } +} +``` + +`initialCount` is non-null and defaults to `0`. + +Resolvers may return normal iterables, promises, or async iterables for list +fields. Async iterables are especially useful with `@stream` because the +executor can complete list items as they become available. + +## Early execution + +`enableEarlyExecution` allows deferred work to begin before all non-deferred +work has completed. + +```js +const result = await experimentalExecuteIncrementally({ schema, document, + enableEarlyExecution: true, }); ``` -If the `directives` option is passed to `GraphQLSchema`, the default directives will not be included. `specifiedDirectives` must be passed to ensure all standard directives are added in addition to `defer` & `stream`. +This can reduce total latency for expensive deferred sections, but it can also +increase concurrent work. Measure before enabling it broadly. + +## Validation limits + +GraphQL.js validates the current incremental delivery rules: + +- `@defer` and `@stream` are not supported on subscription operations. +- `@stream` must be used on list fields. +- `@stream(initialCount:)` must be non-null. +- Active `@defer` and `@stream` labels must be unique. +- Root field usage must follow the current proposal rules. +- Multiple active `@stream` instances cannot target the same field instance. + +Those checks are exposed through the validation rules +`DeferStreamDirectiveLabelRule`, `DeferStreamDirectiveOnRootFieldRule`, +`DeferStreamDirectiveOnValidOperationsRule`, and +`StreamDirectiveOnListFieldRule`. + +If a fragment is shared between query and subscription operations, use the +directive `if` argument to disable incremental behavior in the subscription. + +```graphql +subscription Events($incremental: Boolean! = false) { + event { + ...EventFields @defer(if: $incremental) + } +} +``` + +## Cancellation + +Incremental execution accepts `abortSignal`. Aborting stops new payload +production and attempts to close async iterators. + +```js +const controller = new AbortController(); + +const result = await experimentalExecuteIncrementally({ + schema, + document, + abortSignal: controller.signal, +}); +``` diff --git a/website/pages/docs/directives-on-directives.mdx b/website/pages/docs/directives-on-directives.mdx new file mode 100644 index 0000000000..6407175531 --- /dev/null +++ b/website/pages/docs/directives-on-directives.mdx @@ -0,0 +1,130 @@ +--- +title: Directives on Directive Definitions +sidebarTitle: Directives on Directives +--- + +import { Callout } from 'nextra/components'; + +# Directives on Directive Definitions + + + GraphQL.js supports directives applied to directive definitions, directive + extensions, and directive deprecation metadata through experimental APIs. + + +When the experiment is enabled, GraphQL directives can be applied to directive +definitions. This is the SDL shape introduced by the directives-on-directives +proposal: + +```graphql +directive @tag(name: String!) on DIRECTIVE_DEFINITION + +directive @cacheControl(maxAge: Int) @tag(name: "runtime") on FIELD_DEFINITION +``` + +The directive location is `DIRECTIVE_DEFINITION`. + +```js +import { DirectiveLocation } from 'graphql'; + +DirectiveLocation.DIRECTIVE_DEFINITION; +``` + +## Parser surface + +Directive definition directives are represented on the AST: + +- `DirectiveDefinitionNode.directives` +- `DirectiveExtensionNode.directives` +- `Kind.DIRECTIVE_EXTENSION` + +Parsing this syntax is controlled by +`experimentalDirectivesOnDirectiveDefinitions`. + +```js +import { parse } from 'graphql'; + +const document = parse(source, { + experimentalDirectivesOnDirectiveDefinitions: true, +}); +``` + +Directive extensions use the same option: + +```graphql +extend directive @cacheControl @tag(name: "performance") +``` + +## Runtime schema surface + +GraphQL.js does not add a generic `GraphQLDirective.directives` property. The +applied directives remain available through the AST nodes: + +- `GraphQLDirective.astNode?.directives` +- `GraphQLDirective.extensionASTNodes` + +GraphQL.js does derive directive deprecation metadata from those AST nodes. +`GraphQLDirective` includes: + +- `deprecationReason` +- `extensionASTNodes` + +```js +const directive = schema.getDirective('cacheControl'); + +directive.deprecationReason; +directive.astNode?.directives; +directive.extensionASTNodes; +``` + +## Deprecating custom directives + +`@deprecated` can be used on directive definitions. The built-in +`GraphQLDeprecatedDirective` includes `DIRECTIVE_DEFINITION` in its locations. + +```graphql +directive @oldAuth @deprecated(reason: "Use @auth instead") on FIELD_DEFINITION +``` + +The introspection type `__Directive` includes: + +- `isDeprecated` +- `deprecationReason` + +`__Schema.directives` accepts `includeDeprecated: Boolean! = false` when +directive deprecation support is present. + +```graphql +query DeprecatedDirectives { + __schema { + directives(includeDeprecated: true) { + name + isDeprecated + deprecationReason + } + } +} +``` + +## Directive extensions + +Directive extensions can attach deprecation metadata to a directive defined in +another document: + +```graphql +directive @oldAuth on FIELD_DEFINITION + +extend directive @oldAuth @deprecated(reason: "Use @auth instead") +``` + +When a schema is extended, GraphQL.js preserves directive extension AST nodes on +`GraphQLDirective.extensionASTNodes` and uses them when computing +`deprecationReason`. + +## Validation + +`KnownDirectivesRule` understands `DIRECTIVE_DEFINITION`, so a directive applied +to a directive definition must itself be declared for that location. + +`UniqueDirectivesPerLocationRule` also treats a directive definition and its +extensions as one directive location for non-repeatable directive uniqueness. diff --git a/website/pages/docs/execution-hooks.mdx b/website/pages/docs/execution-hooks.mdx new file mode 100644 index 0000000000..f14b5c11c7 --- /dev/null +++ b/website/pages/docs/execution-hooks.mdx @@ -0,0 +1,192 @@ +--- +title: Execution Hooks and Async Cleanup +sidebarTitle: Execution Hooks +--- + +import { Callout } from 'nextra/components'; + +# Execution Hooks and Async Cleanup + + + Execution hooks are experimental in GraphQL.js v17. The current hook surface + may change before it becomes stable. + + +GraphQL execution can stop producing a result before every piece of async work +started by execution has settled. This is most visible with cancellation: +JavaScript does not have preemptive cancellation for promises. An +`AbortSignal` is cooperative, so it only helps when downstream async functions +accept the signal and honor it. + +GraphQL.js cannot force arbitrary JavaScript work to stop. What it can do is +track async work it knows about and tell the host when that tracked work has +finished. The `asyncWorkFinished` hook is that boundary. + +## `asyncWorkFinished` + +Pass hooks through `execute()`, `subscribe()`, `graphql()`, or +`experimentalExecuteIncrementally()`. + +```js +import { execute } from 'graphql'; + +await execute({ + schema, + document, + hooks: { + asyncWorkFinished({ validatedExecutionArgs }) { + logger.debug( + { + operationName: validatedExecutionArgs.operation.name?.value, + }, + 'GraphQL async work finished', + ); + }, + }, +}); +``` + +The hook fires after GraphQL.js has stopped producing payloads and all tracked +async execution work has settled. It is useful when a host needs to observe +work that continues after the response boundary, such as async iterator +cleanup, cleanup after an aborted execution, or resolver-started work that was +explicitly registered for tracking. + +## What GraphQL.js can track + +GraphQL.js tracks async work that is part of execution and work registered +through resolver info helpers. It does not automatically know about arbitrary +background work started by your application. + +Use `promiseAll()` when a resolver awaits several async branches and you want +rejected branches to be tracked consistently: + +```js +async resolve(_source, args, _context, info) { + const { promiseAll } = info.getAsyncHelpers(); + + const [user, permissions] = await promiseAll([ + loadUser(args.id), + loadPermissions(args.id), + ]); + + return { user, permissions }; +} +``` + +Use `track()` for async cleanup or side effects that a resolver starts but does +not return or await: + +```js +async resolve(_source, _args, _context, info) { + const { track } = info.getAsyncHelpers(); + const cleanup = closeResourceLater().catch(() => undefined); + + track([cleanup]); + + return 'ok'; +} +``` + +If the resolver is already awaiting or returning the work, do that normally. +Use `track()` only for work that would otherwise be invisible to GraphQL.js. + +## Logging and telemetry + +For many hosts, the hook is an observability point. It can record how long +tracked async cleanup continued after execution started or after a response was +produced. + +```js +const startedAt = Date.now(); + +await execute({ + schema, + document, + hooks: { + asyncWorkFinished({ validatedExecutionArgs }) { + metrics.record('graphql.async_work_finished', { + operationName: validatedExecutionArgs.operation.name?.value, + elapsedMs: Date.now() - startedAt, + }); + }, + }, +}); +``` + +## Waiting before returning a result + +Some hosts prefer not to return the GraphQL result to the transport until +tracked async cleanup has finished. For example, a test harness may want the +operation to leave no pending execution work before assertions run. + +```js +import { + executeRootSelectionSet, + validateExecutionArgs, +} from 'graphql'; + +async function executeAndWaitForAsyncWork(args) { + const validatedArgs = validateExecutionArgs(args); + + if (!('schema' in validatedArgs)) { + return { errors: validatedArgs }; + } + + let markAsyncWorkFinished; + const asyncWorkFinished = new Promise((resolve) => { + markAsyncWorkFinished = resolve; + }); + + const result = executeRootSelectionSet({ + ...validatedArgs, + hooks: { + ...validatedArgs.hooks, + asyncWorkFinished(info) { + validatedArgs.hooks?.asyncWorkFinished?.(info); + markAsyncWorkFinished(); + }, + }, + }); + + const executionResult = await result; + await asyncWorkFinished; + + return executionResult; +} +``` + +This pattern trades response latency for a stronger lifecycle boundary. It is +usually better for tests, controlled batch jobs, and framework internals than +for latency-sensitive HTTP handlers. + +## Host cleanup + +The hook can also release host-owned bookkeeping that should stay alive until +GraphQL.js has finished tracked async work. + +```js +await execute({ + schema, + document, + contextValue: requestContext, + hooks: { + asyncWorkFinished({ validatedExecutionArgs }) { + requestRegistry.delete(validatedExecutionArgs); + requestContext.loaderCache.clear(); + }, + }, +}); +``` + +## Aborts and incremental delivery + +Hooks are especially useful when execution is aborted or incremental delivery is +used: + +- Abort may stop payload production before cleanup is complete. +- Async iterator `return()` paths can continue after the response boundary. +- Deferred work can leave short-lived cleanup tasks after the final patch. + +Pair hooks with [Handling Abort Signals](/docs/abort-signals) for timeout and +cancellation instrumentation. diff --git a/website/pages/docs/experimental-specification-features.mdx b/website/pages/docs/experimental-specification-features.mdx new file mode 100644 index 0000000000..165f551aa2 --- /dev/null +++ b/website/pages/docs/experimental-specification-features.mdx @@ -0,0 +1,55 @@ +--- +title: Experimental Specification Features +sidebarTitle: Experimental Specification Features +--- + +# Experimental Specification Features + +GraphQL.js v17 beta supports several GraphQL specification proposals. This page +lists experimental features available in the v17 beta line; not every feature +listed here is new to v17. These features are intentionally explicit: syntax +usually requires a parser option or schema directive, and execution behavior +usually requires a specific executor. + +GraphQL.js-specific runtime APIs, such as abort signals, execution hooks, and +the harness API, are documented separately because they are not GraphQL language +features. + +## Incremental delivery + +Incremental delivery adds `@defer`, `@stream`, and execution results with +initial and subsequent payloads. + +The relevant GraphQL.js APIs are `GraphQLDeferDirective`, +`GraphQLStreamDirective`, and `experimentalExecuteIncrementally()`. +GraphQL.js does not include the directives in `specifiedDirectives`; a schema +that uses them should add them explicitly and execute matching operations with +`experimentalExecuteIncrementally()`. If you add them programmatically with the +`GraphQLSchema` `directives` config property, include `specifiedDirectives` as +well. Providing `directives` replaces the default directive list, whose default +value is `specifiedDirectives`. + +See [Defer and Stream](/docs/defer-stream). + +## Fragment arguments + +Fragment arguments add fragment-local variable definitions and fragment-spread +arguments. GraphQL.js exposes the syntax through the +`experimentalFragmentArguments` parser option. The AST surface includes +`FragmentArgumentNode`, and execution supports the resulting values. + +See [Fragment Arguments](/docs/fragment-arguments). + +## Directives on directive definitions + +The directives-on-directives proposal adds `DIRECTIVE_DEFINITION` as a +directive location and allows directive metadata to be attached to directive +definitions and directive extensions. + +GraphQL.js exposes the syntax through +`experimentalDirectivesOnDirectiveDefinitions`. The AST surface includes +`DirectiveLocation.DIRECTIVE_DEFINITION` and `DirectiveExtensionNode`. +Directive deprecation metadata is surfaced on `GraphQLDirective`, +introspection, and schema printing. + +See [Directives on Directives](/docs/directives-on-directives). diff --git a/website/pages/docs/fragment-arguments.mdx b/website/pages/docs/fragment-arguments.mdx new file mode 100644 index 0000000000..2d4c1205ec --- /dev/null +++ b/website/pages/docs/fragment-arguments.mdx @@ -0,0 +1,140 @@ +--- +title: Fragment Arguments +sidebarTitle: Fragment Arguments +--- + +import { Callout } from 'nextra/components'; + +# Fragment Arguments + + + Fragment arguments are available behind an experimental parser option in + GraphQL.js v17 and newer. They are pending GraphQL specification work. + + +GraphQL operation variables are defined at the operation level. That works for +many documents, but reusable fragments sometimes need local parameters. Fragment +arguments let a fragment define its own variables and let each fragment spread +provide values for those variables. + +The feature is also called fragment variables because the fragment-level +parameters are conceptually "variables" scoped to that fragment. They are passed +as arguments on the fragment spread, using syntax similar to field arguments. + +## Changed from legacy fragment variables + +Older GraphQL.js versions had an experimental `allowLegacyFragmentVariables` +parser option that added only syntax support for fragment definitions with +variable-like syntax. That v16 experiment was parser-only: it could parse the +syntax, but GraphQL.js did not apply fragment variable values during execution. + +`allowLegacyFragmentVariables` was removed in favor of the more complete +`experimentalFragmentArguments` feature. `experimentalFragmentArguments` +includes parser support and runtime execution support, including coercion and +default value handling through the execution layer. + +## Syntax + +```graphql +query Profile($viewerID: ID!) { + node(id: $viewerID) { + ...UserCard(size: 96) + } +} + +fragment UserCard($size: Int = 48) on User { + id + name + avatar(size: $size) +} +``` + +`$viewerID` is an operation variable. `$size` is local to `UserCard`. + +Different spreads can call the same fragment with different values: + +```graphql +query Team { + lead { + ...UserCard(size: 96) + } + members { + ...UserCard(size: 32) + } +} +``` + +## Enabling fragment arguments + +The parser rejects fragment arguments unless the experiment is enabled. + +```js +import { parse } from 'graphql'; + +const document = parse(source, { + experimentalFragmentArguments: true, +}); +``` + +`graphql()` in v17 accepts parse options too, so simple hosts can pass the same +option through the top-level API: + +```js +import { graphql } from 'graphql'; + +const result = await graphql({ + schema, + source, + experimentalFragmentArguments: true, +}); +``` + +## Runtime values and scope + +Fragment arguments are coerced using the fragment definition's variable +definitions. If a fragment argument has a default value, the default is applied +when a spread omits that argument. + +```graphql +fragment UserCard($size: Int = 48) on User { + avatar(size: $size) +} + +query { + viewer { + ...UserCard + } +} +``` + +When an operation variable and a fragment argument share a name, the fragment +argument is used inside that fragment. Avoid name reuse unless it is deliberate; +distinct names are easier for humans and tools to follow. + +Resolvers do not need a separate API for fragment arguments. By the time a +field resolver runs, GraphQL.js has applied the fragment argument values to the +field arguments, directives, and nested fragment spreads that reference them. + +## AST and tooling changes + +When enabled, GraphQL.js adds: + +- `FragmentDefinitionNode.variableDefinitions`. +- `FragmentSpreadNode.arguments`. +- `FragmentArgumentNode`. +- `Kind.FRAGMENT_ARGUMENT`. +- The `FRAGMENT_VARIABLE_DEFINITION` directive location. + +The printer and visitor understand these nodes in v17. Tooling that uses custom +visitors should include the new node kind when it needs to inspect or transform +fragment spread arguments. + +```js +import { Kind, visit } from 'graphql'; + +visit(document, { + [Kind.FRAGMENT_ARGUMENT](node) { + console.log(node.name.value); + }, +}); +``` diff --git a/website/pages/docs/getting-started.mdx b/website/pages/docs/getting-started.mdx index 0a12557526..6f7b089836 100644 --- a/website/pages/docs/getting-started.mdx +++ b/website/pages/docs/getting-started.mdx @@ -24,14 +24,32 @@ GraphQL.js v16 is the current stable release. v17 is available as an alpha for early testing and feedback. The alpha may change and should not be used in production. +## Setting Up Your Project + To create a new project and install the latest stable release (v16) in your current directory: ```sh npm2yarn -npm init +npm init -y npm install graphql --save ``` +After running these commands, you'll have: +- `package.json` - your project configuration file +- `node_modules/` - directory where npm packages are installed + +Next, you need to configure your project to support ES6 import/export syntax. +Update your `package.json` to include `"type": "module"`: + +```json +{ + "type": "module", + "name": "graphql-starter", + "version": "1.0.0", + ... +} +``` + To try the v17 alpha instead: ```sh npm2yarn @@ -40,7 +58,7 @@ npm install graphql@alpha --save ## Writing Code -To handle GraphQL queries, we need a schema that defines the `Query` type, and we need an API root with a function called a "resolver" for each API endpoint. For an API that just returns "Hello world!", we can put this code in a file named `server.js`: +To handle GraphQL queries, we need a schema that defines the `Query` type, and we need an API root with a function called a "resolver" for each API endpoint. For an API that just returns "Hello world!", create a file named `server.js` in your project root (the same directory as your `package.json`): @@ -113,4 +131,4 @@ You should see the GraphQL response printed out: Congratulations - you just executed a GraphQL query! -For practical applications, you'll probably want to run GraphQL queries from an API server, rather than executing GraphQL with a command line tool. To use GraphQL for an API server over HTTP, check out [Running an Express GraphQL Server](./running-an-express-graphql-server). \ No newline at end of file +For practical applications, you'll probably want to run GraphQL queries from an API server, rather than executing GraphQL with a command line tool. To use GraphQL for an API server over HTTP, check out [Running an Express GraphQL Server](./running-an-express-graphql-server). diff --git a/website/pages/docs/graphql-clients.mdx b/website/pages/docs/graphql-clients.mdx index e1c56e1fa7..5c34cd8068 100644 --- a/website/pages/docs/graphql-clients.mdx +++ b/website/pages/docs/graphql-clients.mdx @@ -6,13 +6,33 @@ title: GraphQL Clients Since a GraphQL API has more underlying structure than a REST API, there are more powerful clients like [Relay](https://facebook.github.io/relay/) which can automatically handle batching, caching, and other features. But you don't need a complex client to call a GraphQL server. With `graphql-http`, you can just send an HTTP POST request to the endpoint you mounted your GraphQL server on, passing the GraphQL query as the `query` field in a JSON payload. -For example, let's say we mounted a GraphQL server on http://localhost:4000/graphql as in the example code for [running an Express GraphQL server](./running-an-express-graphql-server), and we want to send the GraphQL query `{ hello }`. We can do this from the command line with `curl`. If you paste this into a terminal: +For example, let's say we mounted a GraphQL server on http://localhost:4000/graphql as in the example code for [running an Express GraphQL server](./running-an-express-graphql-server), and we want to send the GraphQL query `{ hello }`. We can do this from the command line with `curl`. + +**On Linux or macOS:** ```bash curl -X POST \ --H "Content-Type: application/json" \ --d '{"query": "{ hello }"}' \ -http://localhost:4000/graphql + -H "Content-Type: application/json" \ + -d '{"query": "{ hello }"}' \ + http://localhost:4000/graphql +``` + +**On Windows (Command Prompt):** + +```bash +curl -X POST ^ + -H "Content-Type: application/json" ^ + -d "{\"query\": \"{ hello }\"}" ^ + http://localhost:4000/graphql +``` + +**On Windows (PowerShell):** + +```powershell +curl.exe -X POST ` + -H "Content-Type: application/json" ` + -d '{"query": "{ hello }"}' ` + http://localhost:4000/graphql ``` You should see the output returned as JSON: @@ -21,9 +41,19 @@ You should see the output returned as JSON: { "data": { "hello": "Hello world!" } } ``` -If you prefer to use a graphical user interface to send a test query, you can use clients such as [GraphiQL](https://github.com/graphql/graphiql), [Insomnia](https://github.com/getinsomnia/insomnia), and [Postman](https://www.postman.com/product/graphql-client/). +If you prefer to use a graphical user interface to send a test query, use a +GraphQL client such as [GraphiQL](https://github.com/graphql/graphiql), +[Insomnia](https://github.com/getinsomnia/insomnia), or +[Postman](https://www.postman.com/product/graphql-client/). The +[Running an Express GraphQL Server](./running-an-express-graphql-server) guide +shows how to serve GraphiQL locally with +[Ruru](https://github.com/graphile/crystal/blob/main/grafast/ruru/README.md). -It's also simple to send GraphQL from the browser. Open up http://localhost:4000/graphql, open a developer console, and paste in: +## Using Fetch from the Browser + +It's also simple to send GraphQL from the browser. Open +[http://localhost:4000/graphql](http://localhost:4000/graphql), open a developer +console, and paste in the following code: ```js fetch('/graphql', { @@ -38,12 +68,21 @@ fetch('/graphql', { .then((data) => console.log('data returned:', data)); ``` -You should see the data returned, logged in the console: +You should see the GraphQL response logged in the console: ```text -data returned: Object { hello: "Hello world!" } +data returned: { data: { hello: "Hello world!" } } ``` +This works because the developer console and the `/graphql` endpoint are both +on `http://localhost:4000`, so `fetch('/graphql', ...)` is same-origin. The +browser may show an error when you visit the endpoint directly because that +navigation does not send a GraphQL operation yet, but the developer console is +still on the right origin. If you run the same code from a page on a different +origin, use the full endpoint URL and make sure the GraphQL server is configured +for CORS. Otherwise, use `curl`, a GraphQL IDE, or an HTTP client such as +Insomnia or Postman. + In this example, the query was just a hardcoded string. As your application becomes more complex, and you add GraphQL endpoints that take arguments as described in [Passing Arguments](./passing-arguments), you will want to construct GraphQL queries using variables in client code. You can do this by including a keyword prefixed with a dollar sign in the query, and passing an extra `variables` field on the payload. For example, let's say you're running the example server from [Passing Arguments](./passing-arguments) that has a schema of diff --git a/website/pages/docs/graphql-harness.mdx b/website/pages/docs/graphql-harness.mdx new file mode 100644 index 0000000000..7d44f743c2 --- /dev/null +++ b/website/pages/docs/graphql-harness.mdx @@ -0,0 +1,154 @@ +--- +title: GraphQL Harness +sidebarTitle: GraphQL Harness +--- + +import { Callout } from 'nextra/components'; + +# GraphQL Harness + + + `GraphQLHarness` is new in GraphQL.js v17. It customizes the phases used by + `graphql()` and `graphqlSync()`. + + +`graphql()` is the convenience entry point that parses, validates, and executes +a GraphQL operation. In v17, those phases are represented by a harness: + +```ts +type GraphQLHarness = { + parse: GraphQLParseFn; + validate: GraphQLValidateFn; + execute: GraphQLExecuteFn; + subscribe: GraphQLSubscribeFn; +}; +``` + +`defaultHarness` is the built-in harness used by `graphql()` and +`graphqlSync()`. + +```js +import { defaultHarness, graphql } from 'graphql'; + +const result = await graphql({ + schema, + source, + harness: defaultHarness, +}); +``` + +## Why this exists + +The harness is a host integration API modeled after +[Envelop](https://the-guild.dev/graphql/envelop), The Guild's GraphQL plugin +system. Envelop showed that many servers need to customize the same request +phases: parsing, validation, execution, subscription execution, and the +cross-cutting behavior around those phases. + +GraphQL.js remains a reference implementation, not a full plugin framework. +The harness brings the broader phase types used by that ecosystem closer to the +reference implementation so frameworks and plugin systems can share a common +shape. For example, `GraphQLParseFn` can return a `DocumentNode` or a promise +for a `DocumentNode`, even though the built-in GraphQL.js `parse()` function is +synchronous. + +For application servers, prefer Envelop or a framework built on Envelop over +using a raw `GraphQLHarness` directly. The goal is that frameworks can accept a +custom harness, and plugin systems that customize these phases can interoperate +without each framework inventing a different integration surface. + +## What can be customized + +Each harness function receives the same arguments as the corresponding +GraphQL.js phase. The difference is that a harness phase may finish immediately +or by returning a promise: + +```ts +type MaybePromise = T | Promise; + +type GraphQLParseFn = ( + source: string | Source, + options?: ParseOptions, +) => MaybePromise; + +type GraphQLValidateFn = ( + schema: GraphQLSchema, + documentAST: DocumentNode, + rules?: readonly ValidationRule[], + options?: ValidationOptions, +) => MaybePromise; + +type GraphQLExecuteFn = (args: ExecutionArgs) => MaybePromise; + +type GraphQLSubscribeFn = ( + args: ExecutionArgs, +) => MaybePromise< + ExecutionResult | AsyncGenerator +>; +``` + +Any harness phase may return synchronously or asynchronously. `graphqlSync()` +still requires every phase and resolver it reaches to complete synchronously. +`GraphQLExecuteFn` deliberately returns only `ExecutionResult`; it does not +include the experimental incremental delivery result type. + +## Cached documents + +A host that has a trusted document cache can replace the parse phase while +keeping the default validation and execution behavior. + +```js +import { defaultHarness, graphql } from 'graphql'; + +const harness = { + ...defaultHarness, + parse(source, options) { + const cached = documents.get(String(source)); + return cached ?? defaultHarness.parse(source, options); + }, +}; + +const result = await graphql({ + schema, + source, + variableValues, + operationName, + harness, +}); +``` + +## External validation + +A host can also replace validation. This is useful for persisted operation +registries that validate at build time and return stored validation results at +runtime. + +```js +import { defaultHarness, graphql } from 'graphql'; + +const harness = { + ...defaultHarness, + async validate(schema, document, rules, options) { + const cached = await registry.getValidationResult(document, schema); + return cached ?? defaultHarness.validate(schema, document, rules, options); + }, +}; + +const result = await graphql({ + schema, + source, + harness, +}); +``` + +## Relationship to incremental delivery + +`graphql()` remains a single-result operation pipeline. A harness does not make +`graphql()` return incremental delivery payloads, and the harness `execute` +function has the same single-result contract. + +Operations that use `@defer` or `@stream` should use +`experimentalExecuteIncrementally()` after parsing and validation. See +[Advanced Execution Pipelines](/docs/advanced-execution-pipelines) for the +lower-level execution APIs and [Defer and Stream](/docs/defer-stream) for the +incremental result shape. diff --git a/website/pages/docs/index.mdx b/website/pages/docs/index.mdx index 3b45c15e4b..9f47a06b32 100644 --- a/website/pages/docs/index.mdx +++ b/website/pages/docs/index.mdx @@ -3,17 +3,22 @@ title: Overview sidebarTitle: Overview --- -GraphQL.js is the official JavaScript implementation of the -[GraphQL Specification](https://spec.graphql.org/draft/). It provides the core building blocks -for constructing GraphQL servers, clients, tools, and utilities in JavaScript and TypeScript. +# GraphQL.js Documentation -This documentation site is for developers who want to: +GraphQL.js is the official JavaScript implementation of the GraphQL +specification. It provides the parser, validator, executor, type system, and +utilities used to build GraphQL servers, clients, tools, and schema workflows in +JavaScript and TypeScript. -- Understand how GraphQL works -- Build a GraphQL API using GraphQL.js -- Extend, customize, or introspect GraphQL systems -- Learn best practices for using GraphQL.js in production +## Version reference -Whether you're writing your own server, building a GraphQL clients, or creating tools -that work with GraphQL, this site guides you through core concepts, APIs, and -advanced use cases of GraphQL.js. +| Version area | Start here | +| --- | --- | +| Stable v16 API | [v16 API reference](/api-v16/graphql) | +| v17 beta API | [v17 API reference](/api-v17/graphql) | +| v16 to v17 changes | [What changed in GraphQL.js v17](/upgrade-guides/v16-v17) | +| v17 specification experiments | [Experimental Specification Features](/docs/experimental-specification-features) | +| v17 runtime features | [GraphQL Harness](/docs/graphql-harness), [Abort Signals](/docs/abort-signals), [Execution Hooks](/docs/execution-hooks) | + +The guides in this section describe GraphQL concepts and GraphQL.js behavior. +The API sections document the public exports by package module. diff --git a/website/pages/docs/mutations-and-input-types.mdx b/website/pages/docs/mutations-and-input-types.mdx index 8948c69b34..f659d2f6f9 100644 --- a/website/pages/docs/mutations-and-input-types.mdx +++ b/website/pages/docs/mutations-and-input-types.mdx @@ -201,6 +201,41 @@ Input types can't have fields that are other objects, only basic scalar types, l Naming input types with `Input` on the end is a useful convention, because you will often want both an input type and an output type that are slightly different for a single conceptual object. +Input object fields can also define defaults for omitted fields. In SDL, use +the same `= value` syntax as field arguments: + +```graphql +input MessageInput { + content: String + author: String = "Anonymous" +} +``` + +When constructing input object types in code, GraphQL.js v16 uses +`defaultValue`: + +```js +const MessageInput = new GraphQLInputObjectType({ + name: 'MessageInput', + fields: { + content: { type: GraphQLString }, + author: { type: GraphQLString, defaultValue: 'Anonymous' }, + }, +}); +``` + +`defaultValue` is the legacy way to provide an already-coerced JavaScript +value. GraphQL.js v17 also supports the new `default: { value }` shape for the +raw JavaScript input value before coercion; on the built schema, that same case +is represented as `inputField.default.value`. Keeping the raw value lets +GraphQL.js validate the default and report it through introspection without +reconstructing the GraphQL literal from an already-coerced value, which fixes a +subtle source of incorrect default values for some schemas. If you already have +a GraphQL literal instead, use `default: { literal }`. GraphQL.js now uses the +literal form internally when building a schema from SDL. Invalid defaults are +reported by schema validation instead of waiting until a query happens to use +that field. + Here's some runnable code that implements this schema, keeping the data in memory: diff --git a/website/pages/docs/oneof-input-objects.mdx b/website/pages/docs/oneof-input-objects.mdx index 516da5b538..8ac5bd7ac9 100644 --- a/website/pages/docs/oneof-input-objects.mdx +++ b/website/pages/docs/oneof-input-objects.mdx @@ -1,8 +1,8 @@ --- -title: OneOf input objects +title: OneOf Input Objects --- -# OneOf input objects +# OneOf Input Objects import { Tabs } from 'nextra/components'; @@ -55,11 +55,10 @@ const Product = new GraphQLObjectType({ const ProductLocation = new GraphQLInputObjectType({ name: 'ProductLocation', - isOneOf: true, fields: { - aisleNumber: { type: GraphQLInt }, - shelfNumber: { type: GraphQLInt }, - positionOnShelf: { type: GraphQLInt }, + aisleNumber: { type: new GraphQLNonNull(GraphQLInt) }, + shelfNumber: { type: new GraphQLNonNull(GraphQLInt) }, + positionOnShelf: { type: new GraphQLNonNull(GraphQLInt) }, }, }); @@ -79,7 +78,7 @@ const schema = new GraphQLSchema({ fields: { product: { type: Product, - args: { by: { type: ProductSpecifier } }, + args: { by: { type: new GraphQLNonNull(ProductSpecifier) } }, }, }, }), @@ -91,3 +90,12 @@ const schema = new GraphQLSchema({ It doesn't matter whether you have 2 or more inputs here, all that matters is that your user will have to specify one, and only one, for this input to be valid. The values are not limited to scalars, lists and other input object types are also allowed. + +OneOf fields themselves must be nullable and must not define defaults. Nested +input object types can still have their own required fields, as shown by +`ProductLocation`. + +In GraphQL.js v17, OneOf coercion is stricter around defaults, unknown fields, +`undefined`, and values that are present before coercion but invalid after +coercion. Schemas that accidentally rely on ambiguous OneOf inputs should fail +earlier and with clearer errors. diff --git a/website/pages/docs/passing-arguments.mdx b/website/pages/docs/passing-arguments.mdx index 45eb087cd8..87e6a3f1f1 100644 --- a/website/pages/docs/passing-arguments.mdx +++ b/website/pages/docs/passing-arguments.mdx @@ -74,6 +74,53 @@ console.log('Running a GraphQL API server at localhost:4000/graphql'); The exclamation point in `Int!` indicates that `numDice` can't be null, which means we can skip a bit of validation logic to make our server code simpler. We can let `numSides` be null and assume that by default a die has 6 sides. +## Default argument values + +When an argument has a natural default, define that default in the schema +instead of filling it in inside every resolver. In SDL, add `= value` after the +argument type: + +```graphql +type Query { + rollDice(numDice: Int!, numSides: Int = 6): [Int] +} +``` + +When constructing a schema in code, GraphQL.js v16 uses `defaultValue`: + +```js +const rollDiceField = { + type: new GraphQLList(GraphQLFloat), + args: { + numDice: { type: new GraphQLNonNull(GraphQLInt) }, + numSides: { type: GraphQLInt, defaultValue: 6 }, + }, +}; +``` + +GraphQL.js v17 also supports the more explicit `default` shape for new code: + +```js +const rollDiceField = { + type: new GraphQLList(GraphQLFloat), + args: { + numDice: { type: new GraphQLNonNull(GraphQLInt) }, + numSides: { type: GraphQLInt, default: { value: 6 } }, + }, +}; +``` + +`defaultValue` is the legacy way to provide an already-coerced JavaScript +value. For new code in v17, use `default: { value }` with the raw JavaScript +input value before coercion; on the built schema, that same case is represented +as `argument.default.value`. Keeping the raw value lets GraphQL.js validate the +default and report it through introspection without reconstructing the GraphQL +literal from an already-coerced value, which fixes a subtle source of incorrect +default values for some schemas. If you already have a GraphQL +literal instead, use `default: { literal }`. GraphQL.js now uses the literal +form internally when building a schema from SDL. `defaultValue` still works in +v17, but is deprecated for removal in v18. + So far, our resolver functions took no arguments. When a resolver takes arguments, they are passed as one "args" object, as the first argument to the function. So rollDice could be implemented as: ```js diff --git a/website/pages/docs/schema-coordinates.mdx b/website/pages/docs/schema-coordinates.mdx new file mode 100644 index 0000000000..7a9042b94c --- /dev/null +++ b/website/pages/docs/schema-coordinates.mdx @@ -0,0 +1,128 @@ +--- +title: Schema Coordinates +sidebarTitle: Schema Coordinates +--- + +import { Callout } from 'nextra/components'; + +# Schema Coordinates + + + Schema coordinate helpers are available in GraphQL.js v17 and newer. They + implement the GraphQL schema-coordinate grammar and resolution semantics, + which have now been merged into the specification work. + + +A schema coordinate is a compact string that identifies a schema element. It is +useful when logs, registries, schema checks, documentation tools, or policy +systems need to refer to the same field, argument, directive, or enum value +without embedding a whole schema document. + +Examples: + +```text +Business +Business.name +Query.searchBusiness(criteria:) +SearchCriteria.filter +SearchFilter.OPEN_NOW +@private +@private(scope:) +``` + +## Resolving coordinates + +Use `resolveSchemaCoordinate(schema, coordinate)` when you want to resolve a +coordinate string directly against a schema: + +```js +import { buildSchema, resolveSchemaCoordinate } from 'graphql'; + +const schema = buildSchema(` + type Query { + searchBusiness(criteria: SearchCriteria!): [Business] + } + + input SearchCriteria { + name: String + filter: SearchFilter + } + + enum SearchFilter { + OPEN_NOW + DELIVERS_TAKEOUT + } + + type Business { + id: ID + name: String + } +`); + +const resolved = resolveSchemaCoordinate( + schema, + 'Query.searchBusiness(criteria:)', +); + +if (resolved?.kind === 'FieldArgument') { + console.log(resolved.fieldArgument.type.toString()); +} +``` + +The result is a discriminated object. Depending on the coordinate, the `kind` +can be `NamedType`, `Field`, `InputField`, `EnumValue`, `FieldArgument`, +`Directive`, or `DirectiveArgument`. + +If the final element does not exist, GraphQL.js returns `undefined`. If the +coordinate refers through a containing element that cannot exist, GraphQL.js +throws. For example, `Business.unknown` returns `undefined`, but +`Unknown.field` throws because `Unknown` is not a type in the schema. + +## Parsing coordinates + +Use `parseSchemaCoordinate()` when tooling needs the AST form before resolving: + +```js +import { parseSchemaCoordinate } from 'graphql'; + +const coordinateNode = parseSchemaCoordinate('@private(scope:)'); +``` + +GraphQL.js exposes coordinate AST node types and kinds: + +- `TypeCoordinateNode` +- `MemberCoordinateNode` +- `ArgumentCoordinateNode` +- `DirectiveCoordinateNode` +- `DirectiveArgumentCoordinateNode` +- `isSchemaCoordinateNode()` + +The coordinate parser uses a restricted lexer. It accepts coordinate syntax +only; it is not the same as parsing an executable GraphQL document or SDL +document. + +## Meta fields and introspection + +GraphQL.js can resolve meta fields and introspection schema elements: + +```js +resolveSchemaCoordinate(schema, 'Business.__typename'); +resolveSchemaCoordinate(schema, '__Directive.name'); +resolveSchemaCoordinate(schema, '__DirectiveLocation.INLINE_FRAGMENT'); +``` + +Meta-field resolution is implementation-defined rather than required for every +GraphQL server. Treat it as GraphQL.js behavior when building tooling that must +work across implementations. + +## Common uses + +- Store schema change approvals against coordinates such as + `Query.searchBusiness(criteria:)`. +- Attach ownership metadata to fields, directives, or enum values. +- Connect validation errors, usage metrics, and schema registry entries. +- Build documentation links without relying on display text. + +Schema coordinates identify schema elements; they do not describe executable +operation paths. For operation-specific paths, use GraphQL response paths such +as `["viewer", "name"]`. diff --git a/website/pages/docs/schema-evolution.mdx b/website/pages/docs/schema-evolution.mdx new file mode 100644 index 0000000000..5212f4a1d7 --- /dev/null +++ b/website/pages/docs/schema-evolution.mdx @@ -0,0 +1,177 @@ +--- +title: Schema Evolution +sidebarTitle: Schema Evolution +--- + +# Schema Evolution + +GraphQL schemas tend to evolve continuously. Fields are added, arguments are +introduced, enum values are deprecated, and object types move through product +life cycles. GraphQL.js provides schema comparison helpers so teams can make +those changes intentionally. + +Use these helpers in CI, release tooling, schema registries, or local migration +scripts. They compare two `GraphQLSchema` instances, not two SDL strings, so +you can build the schemas however your project normally does. + +## Comparing schemas in v16 + +GraphQL.js v16 exports two comparison helpers: + +```js +import { + buildSchema, + findBreakingChanges, + findDangerousChanges, +} from 'graphql'; + +const oldSchema = buildSchema(` + type Query { + product(id: ID!): Product + } + + type Product { + id: ID! + name: String + } +`); + +const newSchema = buildSchema(` + type Query { + product(id: ID!): Product + } + + type Product { + id: ID! + title: String + } +`); + +const breaking = findBreakingChanges(oldSchema, newSchema); +const dangerous = findDangerousChanges(oldSchema, newSchema); +``` + +`findBreakingChanges()` reports changes that can make existing operations fail, +such as removing a field, removing a type, removing an enum value, or adding a +required argument. + +`findDangerousChanges()` reports changes that are not always breaking but can +change client behavior, such as adding an enum value or adding an optional +argument. + +## Comparing schemas in v17 + +GraphQL.js v17 adds `findSchemaChanges()`. + +```js +import { findSchemaChanges } from 'graphql'; + +const changes = findSchemaChanges(oldSchema, newSchema); + +for (const change of changes) { + console.log(change.type, change.description); +} +``` + +`findSchemaChanges()` returns breaking, dangerous, and safe changes from one +call. The older `findBreakingChanges()` and `findDangerousChanges()` helpers +remain in v17, but they are deprecated for removal in v18. + +## Change Categories + +Breaking changes are changes that can make a previously valid operation invalid +or change the response shape in a way clients cannot safely ignore. Examples +include: + +- Removing a type, field, directive, argument, enum value, or union member. +- Adding a required argument or required input field. +- Changing a field or argument to an incompatible type. +- Removing an implemented interface from an object or interface. + +Dangerous changes may be safe for many clients, but they deserve review because +some clients can observe them. Examples include: + +- Adding an enum value. +- Adding a member to a union. +- Adding an optional argument or input field. +- Changing or removing a default value. + +Safe changes are additions or metadata changes that should not break existing +operations. In v17, `findSchemaChanges()` can report examples such as: + +- Adding a type, field, or directive. +- Adding an optional directive argument. +- Adding a directive location. +- Changing a description. +- Widening an argument or field type in a safe direction. + +## CI Gate Example + +This example fails a build on breaking changes and prints dangerous changes for +review. + +```js +import { + BreakingChangeType, + buildSchema, + findSchemaChanges, +} from 'graphql'; +import { readFile } from 'node:fs/promises'; + +const oldSchema = buildSchema(await readFile('schema-old.graphql', 'utf8')); +const newSchema = buildSchema(await readFile('schema-new.graphql', 'utf8')); + +const changes = findSchemaChanges(oldSchema, newSchema); +const breakingTypes = new Set(Object.values(BreakingChangeType)); +const breaking = changes.filter((change) => breakingTypes.has(change.type)); + +for (const change of changes) { + console.log(`${change.type}: ${change.description}`); +} + +if (breaking.length > 0) { + process.exitCode = 1; +} +``` + +In production tooling, prefer checking the exported change type objects instead +of matching strings. That lets TypeScript track the known set of change +categories. + +## Deprecate Before Removing + +The safest way to remove a field, enum value, argument, input field, or +directive is to deprecate it first, publish that deprecation, and wait until +usage is gone. + +```graphql +type Product { + name: String @deprecated(reason: "Use title.") + title: String +} +``` + +You can combine GraphQL.js schema comparison with operation analytics or a +schema registry: + +1. Add the replacement API. +2. Mark the old API as deprecated with a useful reason. +3. Monitor whether operations still use the deprecated API. +4. Remove the old API only after clients have migrated. +5. Let `findBreakingChanges()` or `findSchemaChanges()` confirm the removal is + intentional. + +## Working With Printed Schemas + +Schema comparison is most useful when the schemas are deterministic. If your +schema is constructed programmatically, print and sort it before storing a +baseline. + +```js +import { lexicographicSortSchema, printSchema } from 'graphql'; + +const sdl = printSchema(lexicographicSortSchema(schema)); +``` + +Use the sorted printed schema for human review, and use the actual +`GraphQLSchema` objects for `findBreakingChanges()` or `findSchemaChanges()`. diff --git a/website/pages/docs/subscriptions.mdx b/website/pages/docs/subscriptions.mdx index 7afeefed1b..fbe2261ddf 100644 --- a/website/pages/docs/subscriptions.mdx +++ b/website/pages/docs/subscriptions.mdx @@ -16,8 +16,9 @@ GraphQL.js implements the subscription execution algorithm, but it's up to you t ## How execution works -The core of subscription execution in GraphQL.js is the `subscribe` function. It works similarly to `graphql()`, but returns an `AsyncIterable` of execution results -instead of a single response: +The core of subscription execution in GraphQL.js is the `subscribe` function. +It starts the subscription and, when successful, returns an async iterable of +execution results instead of a single response: ```js import { subscribe, parse } from 'graphql'; @@ -29,14 +30,40 @@ const document = parse(` } `); -const iterator = await subscribe({ schema, document }); +const result = await subscribe({ schema, document }); -for await (const result of iterator) { - console.log(result); +if (isAsyncIterableObject(result)) { + for await (const payload of result) { + console.log(payload); + } +} else { + console.error(result.errors); +} + +function isAsyncIterableObject(value) { + return value != null && typeof value[Symbol.asyncIterator] === 'function'; } ``` -Each time your application publishes a new `messageSent` event, the iterator emits a new result. It's up to your transport layer to manage the connection and forward these updates to the client. +Each time your application publishes a new `messageSent` event, the iterator +emits a new result. It is up to your transport layer to manage the connection +and forward these updates to the client. + +## Why `subscribe()` is separate from `execute()` + +GraphQL.js keeps `execute()` and `subscribe()` as separate entry points for +historical and behavioral reasons. `execute()` is the older API for running one +execution and producing a single result. Subscriptions were added as a separate +GraphQL algorithm because starting a subscription has to resolve a source event +stream before executing the selection set for each event. + +The return type reflects that split. `execute()` returns one `ExecutionResult`, +or a promise for one. `subscribe()` returns an `ExecutionResult` when the +subscription cannot start, or an async stream of `ExecutionResult` values when +it can. In GraphQL.js v17, that return is a `PromiseOrValue`. It contains +either an `ExecutionResult` or an +`AsyncGenerator`, and `await subscribe(args)` still +works whether the implementation completes synchronously or asynchronously. ## When to use subscriptions diff --git a/website/pages/upgrade-guides/v16-v17.mdx b/website/pages/upgrade-guides/v16-v17.mdx index 29e44d2338..9cc129b875 100644 --- a/website/pages/upgrade-guides/v16-v17.mdx +++ b/website/pages/upgrade-guides/v16-v17.mdx @@ -1,221 +1,552 @@ --- -title: Upgrading from v16 to v17 +title: What changed in GraphQL.js v17 sidebarTitle: v16 to v17 --- -import { Tabs } from 'nextra/components'; -import { Callout } from 'nextra/components' - - - Currently GraphQL v17 is in alpha, this guide is based on the alpha release and is subject to change. +import { Callout } from 'nextra/components'; + +# What Changed in GraphQL.js v17 + + + GraphQL.js v17 is currently available as `17.0.0-beta.1`. This guide + describes migration-impacting changes from the v16 stable line to the v17 + beta line. -# Breaking changes +GraphQL.js v17 keeps the core programming model: build a schema, parse a +document, validate it, and execute it. Most changes make boundaries more +explicit. Stable single-result execution is separate from experimental +incremental delivery, input coercion is split from diagnostic validation, and +development checks are opt-in. Host integration features such as harnesses, +abort signals, and execution hooks are explicit GraphQL.js runtime APIs. + +## Reading the Labels + +Migration items below use these labels: -## Required Node.js versions +- **Breaking change:** v16 code may need to change before it runs on v17. +- **Behavioral tightening:** v17 validates or reports a case more precisely. +- **Deprecation:** the v16 API still works in v17, but should be migrated + before v18. +- **New stable API:** a new public API that can be adopted independently. +- **Experimental or opt-in:** available in v17, but proposal-backed or outside + the default execution path. -The v17 release drops support for end-of-life versions of Node.JS, retaining support for versions 20, 22, and 24 or above. +## Platform and Package Shape -## ESM and conditional exports +### Node.js and TypeScript -Earlier versions of GraphQL.js shipped dual builds for CommonJS and ESM, with ESM ".mjs" files sitting alongside CommonJS ".js" files. -The ESM build was accessible via tooling recognizing the `module` field in `package.json`, while the CommonJS build was accessible via -the `main` field. Unless configured carefully, this could sometimes lead to multiple copies of GraphQL.js being loaded in the same -process, i.e. the dual-package hazard. +**Breaking change.** GraphQL.js v17 requires Node.js 22, 24, 25, or 26 and +later: -v17 enables access to the ESM build via the `exports` field in `package.json` in a scheme designed to avoid the dual-package hazard as -best as possible, relying on the ability of bun and newer versions of Node.js to consistently load ESM modules via `require` by -indicating support for specific conditions. __ESM will now be served by default__, unless the requesting environment tooling __both__ -(A) supports the `node` or `require` conditions __and__ (B) does NOT support `bun`, `module`, `module-sync`. In that scenario, the -CommonJS build will be served instead. +```json +{ + "engines": { + "node": "^22.0.0 || ^24.0.0 || ^25.0.0 || >=26.0.0" + } +} +``` -Note: ESM is not served to deno even though it supports require(esm) because deno not yet support the `module-sync` condition, nor -does it seem to provide the `deno` condition when calling `require`, see https://github.com/denoland/deno/issues/29970. +Upgrade Node.js before upgrading GraphQL.js. This separates runtime and +package-manager errors from GraphQL.js migration errors. -Deno users can access a Typescript build for deno via git://github.com/graphql/graphql-js.git#deno as well as by specifically loading -the index.mjs file, i.e. `import { graphql } from 'graphql/index.mjs'`, although this does not protect against the dual-package hazard. +**Breaking change.** The published type definitions target TypeScript 4.4 and +newer. -## Development mode no longer enabled by default and no longer dependent on NODE_ENV value +### Conditional exports -GraphQl.js development mode in v17 is disabled by default and can be enabled by the `development` condition on supporting platforms or -by explicitly enabling it within user code by calling `enableDevMode()`. Development mode may trigger permanent de-optimizations and -therefore cannot be disabled once enabled. The new `isDevModeEnabled()` function can be used to check whether development mode has -been enabled. +**Breaking change.** v17 uses package `exports` and modern package conditions +to select the right build. Use public entry points such as `graphql`, +`graphql/execution`, `graphql/language`, `graphql/type`, `graphql/utilities`, +and `graphql/validation`. -GraphQL.js development mode no longer depends on the `NODE_ENV` environment variable; build tools other than Node.js no longer need -to replace this Node.js specific code. See [Development Mode](./development-mode) for further details regarding how to enable these -checks in v17. +Deep imports into GraphQL.js internals may still work in some environments, but +they are not officially supported. Prefer the public entry points above for +application and library code. -## Default values +**Breaking change.** The deprecated `graphql/subscription` compatibility +subpath is gone. Import subscription APIs from `graphql` or +`graphql/execution`. -GraphQL schemas allow default values for input fields and arguments. Historically, GraphQL.js did not rigorously validate or coerce these -defaults during schema construction, leading to potential runtime errors or inconsistencies. For example: +```diff +- import { subscribe } from 'graphql/subscription'; ++ import { subscribe } from 'graphql/execution'; +``` -- A default value of "5" (string) for an Int-type argument would pass schema validation but fail at runtime. -- Internal serialization methods like astFromValue could produce invalid ASTs if inputs were not properly coerced. +### Development mode -With the new changes default values will be validated and coerced during schema construction. +**Breaking change.** Development mode is disabled by default and no longer +depends on `NODE_ENV`. Enable it with the `development` package condition or by +calling `enableDevMode()` during application startup. -```graphql -input ExampleInput { - value: Int = "invalid" # Now triggers a validation error +```js +import { enableDevMode, isDevModeEnabled } from 'graphql'; + +if (process.env.NODE_ENV === 'development') { + enableDevMode(); } + +console.log(isDevModeEnabled()); ``` -This goes hand-in-hand with the deprecation of `astFromValue` in favor of `valueToLiteral` or `default: { value: }`. +Development mode currently helps diagnose accidental use of multiple GraphQL.js +module instances. See [Development Mode](/docs/development-mode) for runtime +and bundler setup. + +## Request Pipeline and Harnesses + +### `graphql()` and `graphqlSync()` -```ts -// Before (deprecated) -const defaultValue = astFromValue(internalValue, type); -// After -const defaultValue = valueToLiteral(externalValue, type); +**New stable API.** The high-level `graphql()` and `graphqlSync()` APIs still +use the object-argument form from v16. In v17, that object can also carry +parser options, validation options, execution options, `hideSuggestions`, +`abortSignal`, hooks, and a custom harness. + +```js +const result = await graphql({ + schema, + source, + variableValues, + operationName: 'Viewer', + hideSuggestions: true, + abortSignal, +}); ``` -If you want to continue using the old behavior, you can use `defaultValue` in your schema definitions. The new -behavior will be exposed as `default: { literal: }`. +This does not make `graphql()` a framework. It remains the convenience API for +a single-result "parse, validate, execute" request. The new arguments let +simple hosts use common v17 options without rebuilding the whole pipeline. + +### GraphQL Harness + +**New stable API.** `GraphQLHarness` lets hosts replace the parse, validate, +execute, and subscribe phases used by `graphql()` and `graphqlSync()`. -## GraphQLError constructor arguments +The harness is modeled after Envelop-style plugin pipelines. It brings the +broader phase types used by that ecosystem closer to the reference +implementation, so frameworks can accept a custom harness and plugin systems +can interoperate around a shared request-pipeline shape. -The `GraphQLError` constructor now only accepts a message and options object as arguments. Previously, it also accepted positional arguments. +For example, `GraphQLParseFn` can return either a parsed `DocumentNode` or a +promise for one, even though the built-in `parse()` function is synchronous. +The harness `execute` function follows `execute()` and does not include the +experimental incremental delivery return type. + +Use [GraphQL Harness](/docs/graphql-harness) for examples, and call +`experimentalExecuteIncrementally()` directly when an operation may use +`@defer` or `@stream`. + +## Execution and Incremental Delivery + +### Single-result execution + +**Breaking change.** `execute()` is now the stable single-result executor. It +does not support incremental delivery. If a schema or operation opts into +`@defer` or `@stream`, execute it with `experimentalExecuteIncrementally()` +instead. ```diff -- new GraphQLError('message', nodes, source, positions, path, originalError, extensions); -+ new GraphQLError('message', { nodes, source, positions, path, originalError, extensions }); +- import { execute } from 'graphql'; ++ import { experimentalExecuteIncrementally } from 'graphql'; ``` -## `createSourceEventStream` arguments +This keeps the `execute()` contract simple: callers receive one +`ExecutionResult`, or a promise for one. -The `createSourceEventStream` function now only accepts an object as an argument. Previously, it also accepted positional arguments. +**Breaking change.** Incremental execution no longer uses the old +`singleResult` discriminator. Remove branches that check for `singleResult`. -```diff -- createSourceEventStream(schema, document, rootValue, contextValue, variableValues, operationName); -+ createSourceEventStream({ schema, document, rootValue, contextValue, variableValues, operationName }); +### Incremental delivery + +**Experimental or opt-in.** `experimentalExecuteIncrementally()` returns either +a normal `ExecutionResult` or an object with `initialResult` and an async +iterator of `subsequentResults`. + +```js +const result = await experimentalExecuteIncrementally({ schema, document }); + +if ('initialResult' in result) { + send(result.initialResult); + + for await (const subsequentResult of result.subsequentResults) { + send(subsequentResult); + } +} else { + send(result); +} ``` -## `execute` will error for incremental delivery +**Experimental or opt-in.** `legacyExecuteIncrementally()` remains available +for hosts that still need the older incremental delivery payload shape. The +legacy shape identifies deferred and streamed payloads with fields such as +`path` and optional `label`, and can duplicate field data across payloads. The +current experimental shape registers pending work by `id` and reports +completion with `completed` entries. + +Schema setup, directive validation, result shapes, and transport guidance are +covered in [Defer and Stream](/docs/defer-stream). + +### Resolver return values + +**New stable API.** List fields can resolve to async iterables. This is useful +for values that naturally arrive over time and is especially relevant when a +host opts into `@stream`. + +### Custom execution helpers + +**New stable API.** v17 exposes the helper boundary used by `execute()` itself. +`validateExecutionArgs()` validates and normalizes `ExecutionArgs`, including +schema checks, operation selection, variable coercion, fragment information, +default resolvers, and execution options. It returns either +`ValidatedExecutionArgs` or a list of `GraphQLError` values. -The `execute` function will now throw an error if it sees a `@defer` or `@stream` directive. Use `experimentalExecuteIncrementally` instead. -If you know you are dealing with incremental delivery requests, you can replace the import. +Then use the root selection set helper that matches the executor you are +building: + +- `executeRootSelectionSet()` for stable single-result execution. +- `experimentalExecuteRootSelectionSet()` for current incremental delivery. +- `legacyExecuteRootSelectionSet()` for the legacy incremental payload shape. + +These helpers do not replace operation validation with `validate()`. They are +for hosts that already parsed and validated a document and need a custom +execution function. + +The native `execute()` and `subscribe()` functions preserve synchronous +results when execution completes synchronously; they do not wrap every result +in a promise. Custom wrappers that want the same behavior need to handle both +sync and async paths. See +[Advanced Execution Pipelines](/docs/advanced-execution-pipelines) for complete +examples. + +## Subscriptions and Source Event Streams + +### Subscription return type + +**Breaking change.** `subscribe()` returns a `PromiseOrValue` in v17 instead +of always returning a promise. Existing `await subscribe(args)` code continues +to work, but TypeScript code that assumed a promise return type must be updated +to handle the synchronous path. + +**Breaking change.** `subscribe()` does not support incremental delivery. If a +fragment is shared between queries and subscriptions, use the `if` argument on +`@defer` or `@stream` to disable incremental behavior in subscription +operations. + +### Lower-level subscription helpers + +**Breaking change.** `createSourceEventStream()` now accepts only +`ValidatedSubscriptionArgs`. If you call it directly, call +`validateSubscriptionArgs()` first and handle validation errors before passing +the result onward. Use `subscribe()` when you want GraphQL.js to run the full +subscription pipeline. + +`validateSubscriptionArgs()` builds on `validateExecutionArgs()` and additionally +asserts that the selected operation is a subscription. + +**New stable API.** `mapSourceToResponseEvent()` maps a subscription source +stream to execution results. Its third argument is a `RootSelectionSetExecutor`, +which customizes how each source event is executed after the source stream has +already been created. If you omit it, GraphQL.js uses the default +subscription-event executor. + +See [Advanced Execution Pipelines](/docs/advanced-execution-pipelines) for +complete helper examples. + +## Abort Signals + +**Experimental or opt-in.** GraphQL.js v17 adds `AbortSignal` support as its +JavaScript runtime API for cancellation. + +The GraphQL specification discusses cancellation in narrower execution cases. +During non-null error propagation, sibling response positions that have not +executed or yielded a value +[may be cancelled](https://spec.graphql.org/draft/#sec-Errors-and-Non-Null-Types) +to avoid unnecessary work; in the specification's +[normative sections](https://spec.graphql.org/draft/#sec-Appendix-Conformance), +lowercase `may` has RFC 2119 `MAY` force. The subscription algorithms also +describe cancelling response and source streams. The specification does not +define a user or host cancelling an already issued query or mutation request. + +GraphQL.js also accepts an external `abortSignal` on `graphql()`, `execute()`, +`subscribe()`, and `experimentalExecuteIncrementally()`. Resolvers read the +resolver-scoped signal with `info.getAbortSignal()` and pass it to downstream +APIs that support cancellation. + +At this time, GraphQL.js does not expose fine-grained per-field cancellation. +Resolvers in an operation share one signal. For internally cancelled portions +of an operation, GraphQL.js aborts that shared resolver signal when the result +that will actually be returned has finished, notifying still-pending resolver +work together. This may change in future versions. + +See [Abort Signals](/docs/abort-signals) for resolver examples, HTTP request +lifecycle wiring, and aborted execution handling. + +## Execution Hooks + +**Experimental or opt-in.** Execution hooks are separate from abort signals. +They let a host observe execution lifecycle boundaries; they do not force +JavaScript work to stop. + +The first hook is `asyncWorkFinished`. It fires after GraphQL.js has stopped +producing payloads and all tracked async execution work has settled. This is +useful for cleanup, logging, telemetry, tests that need a strong lifecycle +boundary, or hosts that choose to delay returning a result until tracked async +work is finished. + +Resolvers can use `info.getAsyncHelpers()` to make additional work visible to +that tracking. See [Execution Hooks](/docs/execution-hooks) for examples. + +## Input Coercion, Defaults, and Custom Scalars + +### Default values + +**Behavioral tightening.** Argument, input-field, and directive-argument +defaults are now validated as part of schema validation performed by +`validateSchema()`. Invalid defaults that v16 could leave latent now make the +schema invalid with a targeted validation error. + +**Deprecation.** `defaultValue` is the legacy programmatic default format. It +represents an already-coerced JavaScript value and remains available as a +migration bridge. + +**New stable API.** Prefer the new `default` model for programmatic schemas. +Use `default: { value }` when you have the raw JavaScript input value before +coercion. Use `default: { literal }` when you have the GraphQL literal. When +GraphQL.js builds a schema from SDL, it now uses the literal form internally. + +```js +const field = { + type: GraphQLString, + args: { + format: { + type: GraphQLString, + default: { value: 'short' }, + }, + }, +}; +``` + +This fixes subtle cases where introspection could report default values +incorrectly from an already-coerced internal value. + +See [Passing Arguments](/docs/passing-arguments) and +[Mutations and Input Types](/docs/mutations-and-input-types). + +### Coercion and validation helpers + +**Behavioral change.** `coerceInputValue()` and `coerceInputLiteral()` now +return `undefined` when coercion fails. They are optimized for callers that +want either a coerced value or failure. + +**New stable API.** Use `validateInputValue()` and `validateInputLiteral()` when +you need diagnostic errors. Use `valueToLiteral()` when converting an external +JavaScript input value into a GraphQL literal. + +**New stable API.** `replaceVariables()` replaces variables inside complex +scalar literals. GraphQL.js calls it automatically during execution. If you use +literal coercion helpers directly outside execution, call `replaceVariables()` +yourself before coercing literals that may contain variables. + +### Custom scalar method names + +**Deprecation.** v17 introduces scalar method names that match the GraphQL +coercion model: + +| v16 name | v17 name | Purpose | +| --- | --- | --- | +| `serialize` | `coerceOutputValue` | Convert resolver values into response values. | +| `parseValue` | `coerceInputValue` | Convert variable values into internal values. | +| `parseLiteral` | `coerceInputLiteral` | Convert GraphQL literals into internal values. | +| `astFromValue()` | `valueToLiteral()` | Convert external input values into GraphQL literals. | + +The v16 scalar method names still work in v17 and are deprecated for removal in +v18. See [Advanced Custom Scalars](/docs/advanced-custom-scalars). + +## Variable Values and Resolver Info + +**Breaking change.** `getVariableValues()` now returns `{ variableValues }` on +success. That value contains source information and coerced runtime values. ```diff -- import { execute } from 'graphql'; -+ import { experimentalExecuteIncrementally as execute } from 'graphql'; +- const { coerced } = getVariableValues(schema, variableDefinitions, inputs); ++ const { variableValues } = getVariableValues(schema, variableDefinitions, inputs); ++ const coerced = variableValues.coerced; ``` -## Remove incremental delivery support from `subscribe` +This matters because v17 supports fragment-local variables and more precise +default handling. Passing only the coerced object loses information about where +values came from. + +**Breaking change.** `info.variableValues` follows the same model. Use +`info.variableValues.coerced` for runtime values inside resolvers. + +**Behavioral change.** Resolver argument maps and variable maps may use +null-prototype objects. Use `Object.hasOwn(obj, key)` or direct property access +instead of methods inherited from `Object.prototype`. + +**New stable API.** `GraphQLResolveInfo` adds `getAbortSignal()` and +`getAsyncHelpers()` for the abort-signal and execution-hook APIs. + +## Schema, Type System, Directives, and Introspection -In case you have fragments that you use with `defer/stream` that end up in a subscription, -use the `if` argument of the directive to disable it in your subscription operation +### Schema validation -## `subscribe` return type +**Behavioral tightening.** `GraphQLSchema.toConfig().assumeValid` now preserves +the original `assumeValid` setting instead of changing after schema validation +has run. -The `subscribe` function can now also return a non-Promise value, previously this was only a Promise. -This shouldn't change a lot as `await value` will still work as expected. This could lead to -some typing inconsistencies though. +**Behavioral tightening.** Schema validation reports duplicate use of the same +object type for more than one operation root. -## Remove `singleResult` from incremental results +**Behavioral tightening.** Directive argument defaults are validated as part of +schema validation. -You can remove branches that check for `singleResult` in your code, as it is no longer used. +**Behavioral tightening.** The built-in `@deprecated(reason:)` argument is now +non-null. In v16 the argument type was nullable `String`, so a directive use +could explicitly pass `reason: null`. In v17, omit `reason` to use the default +deprecation reason; explicit `null` is no longer valid. -## Node support +### Programmatic schema APIs -Dropped support for Node 14 (subject to change) +**New stable API.** v17 exposes public schema element types and assertions for +programmatic schema work, including `GraphQLField`, `GraphQLArgument`, +`GraphQLInputField`, `GraphQLEnumValue`, `assertField()`, `assertArgument()`, +`assertInputField()`, and `assertEnumValue()`. -## Removed `TokenKindEnum`, `KindEnum` and `DirectiveLocationEnum` types +**New stable API.** `GraphQLSchema.getField(parentType, fieldName)` resolves +ordinary fields and GraphQL meta fields such as `__typename`, `__schema`, and +`__type`. -We have removed the `TokenKindEnum`, `KindEnum` and `DirectiveLocationEnum` types, -use `Kind`, `TokenKind` and `DirectiveLocation` instead. https://github.com/graphql/graphql-js/pull/3579 +**New stable API.** Custom `extensions` maps on schema elements support symbol +keys as well as string keys. -## Removed `graphql/subscription` module +**New stable API.** `printDirective()` prints a directive definition without +printing an entire schema. -use `graphql/execution` instead for subscriptions, all execution related exports have been -unified there. +**Breaking change.** If you imported `GraphQLInterfaceTypeNormalizedConfig` +from a public entry point, replace that import with +`ReturnType`. -## Removed `GraphQLInterfaceTypeNormalizedConfig` export +## Language, AST, Parser, Printer, and Visitor APIs -Use `ReturnType` if you really need this +### AST constants and visitors -## Empty AST collections will be undefined +**Breaking change.** The v16 alias types `KindEnum`, `TokenKindEnum`, and +`DirectiveLocationEnum` are gone. Use `Kind`, `TokenKind`, and +`DirectiveLocation`, which are const objects with matching union types. -Empty AST collections will be presented by `undefined` rather than an empty array. +```diff +- import type { KindEnum } from 'graphql'; ++ import type { Kind } from 'graphql'; +``` -## `Info.variableValues` +**Breaking change.** `getVisitFn()` is gone. Use +`getEnterLeaveForKind()` instead. -The shape of `Info.variableValues` has changed to be an object containing -`sources` and `coerced` as keys. +```js +const { enter, leave } = getEnterLeaveForKind(visitor, Kind.FIELD); +``` -A Source contains the `signature` and provided `value` pre-coercion for the -variable. A `signature` is an object containing the `name`, `input-type` and -`defaultValue` for the variable. +**Behavioral change.** Empty AST collections may be omitted as `undefined`. +Code that reads properties such as `arguments`, `directives`, +`variableDefinitions`, `interfaces`, `fields`, `types`, or `operationTypes` +should treat them as optional. -## Stream directive can't be on multiple instances of the same field +**New stable API.** `isSubscriptionOperationDefinitionNode()` narrows +subscription operation nodes. -The `@stream` directive can't be on multiple instances of the same field, -this won't pass `validate` anymore. +### Fragment arguments -See https://github.com/graphql/graphql-js/pull/4342 +**Experimental or opt-in.** v17 adds proposal-backed fragment arguments behind +the `experimentalFragmentArguments` parser option. Older GraphQL.js versions +had an experimental `allowLegacyFragmentVariables` option, but that was +parser-only and did not work at runtime. -## Stream initialCount becomes non-nullable +When enabled, fragment definitions can declare variables and fragment spreads +can pass arguments. See [Fragment Arguments](/docs/fragment-arguments). -The `initialCount` argument of the `@stream` directive is now non-nullable. +## Validation -See https://github.com/graphql/graphql-js/pull/4322 +**Breaking change.** Passing a custom `TypeInfo` instance as a fifth argument +to `validate()` was removed. If you need a custom traversal with custom type +tracking, compose your visitor with `visitWithTypeInfo()`. -## GraphQLSchemas converted to configuration may no longer be assumed valid +```diff +- const errors = validate(schema, document, rules, options, customTypeInfo); ++ const errors = validate(schema, document, rules, options); +``` -The `assumeValid` config property exported by the `GraphQLSchema.toConfig()` method now passes through the original -flag passed on creation of the `GraphQLSchema`. -Previously, the `assumeValid` property would be to `true` if validation had been run, potentially concealing the original intent. +**New stable API.** `hideSuggestions` removes "Did you mean ..." suggestion +text from diagnostics. This is useful for public APIs that do not want to leak +schema shape through error messages. -See https://github.com/graphql/graphql-js/pull/4244 and https://github.com/graphql/graphql-js/issues/3448 +**New stable API.** `KnownOperationTypesRule` validates that an operation's +root type exists in the schema. For example, a `mutation` operation is invalid +when the schema has no mutation root type. -## `coerceInputValue` returns `undefined` on error +The defer/stream validation rules are documented with the experimental +incremental delivery feature rather than repeated here. See +[Defer and Stream](/docs/defer-stream). -`coerceInputValue` now aborts early when an error occurs, to optimize execution speed on the happy path. -Use the `validateInputValue` helper to retrieve the actual errors. +## Utilities and Error Handling -## Removals +### Schema Change utilities -- Removed deprecated `getOperationType` function, use `getRootType` on the `GraphQLSchema` instance instead -- Removed deprecated `getVisitFn` function, use `getEnterLeaveForKind` instead -- Removed deprecated `printError` and `formatError` utilities, you can use `toString` or `toJSON` on the error as a replacement -- Removed deprecated `assertValidName` and `isValidNameError` utilities, use `assertName` instead -- Removed deprecated `assertValidExecutionArguments` function, use `assertValidSchema` instead -- Removed deprecated `getFieldDefFn` from `TypeInfo` -- Removed deprecated `TypeInfo` from `validate` https://github.com/graphql/graphql-js/pull/4187 +**Deprecation.** `findBreakingChanges()` and `findDangerousChanges()` still +exist in v17 and are deprecated for removal in v18. Use +`findSchemaChanges()` for new schema registry and CI tooling. -## Deprecations +**New stable API.** `findSchemaChanges()` reports breaking, dangerous, and safe +changes from one call. Code that switches to it should handle all three +categories; safe changes use the `SafeChangeType` and `SafeChange` shapes. -- Deprecated `astFromValue` use `valueToLiteral` instead, when leveraging `valueToLiteral` ensure - that you are working with externally provided values i.e. the SDL provided defaultValue to a variable. -- Deprecated `valueFromAST` use `coerceInputLiteral` instead -- Deprecated `findBreakingChanges()` and `findDangerousChanges()`. Use `findSchemaChanges()` instead, which can also be used to find safe changes. -- Deprecated `serialize`. `parseValue`, and `parseLiteral` properties on scalar type configuration. Use `coerceOutputValue`, `coerceInputValue`, and `coerceInputLiteral` instead. +See [Schema Evolution](/docs/schema-evolution) for schema comparison examples. -## Experimental Features +### Removed helpers -### Experimental Support for Incremental Delivery +**Breaking change.** The following deprecated helpers were removed: -- [Spec PR](https://github.com/graphql/graphql-spec/pull/1110) / [RFC](https://github.com/graphql/graphql-wg/blob/main/rfcs/DeferStream.md) -- enabled only when using `experimentalExecuteIncrementally()`, use of a schema or operation with `@defer`/`@stream` directives within `execute()` will now throw. -- enable early execution with the new `enableEarlyExecution` configuration option for `experimentalExecuteIncrementally()`. +- `assertValidName()` and `isValidNameError()`; use `assertName()`. +- `assertValidExecutionArguments()`; use `assertValidSchema()` for schema + validation and `validateExecutionArgs()` for execution argument validation. +- `getOperationRootType()`; use `schema.getRootType(operation)`. +- `getFieldDefFn` from `TypeInfo`. +- `printError()` and `formatError()`; use `error.toString()` or + `error.toJSON()`. -### Experimental Support for Fragment Arguments +### `GraphQLError` -- [Spec PR](https://github.com/graphql/graphql-spec/pull/1081) -- enable with the new `experimentalFragmentArguments` configuration option for `parse()`. -- new experimental `Kind.FRAGMENT_ARGUMENT` for visiting -- new experimental `TypeInfo` methods and options for handling fragment arguments. -- coerce AST via new function `coerceInputLiteral()` with experimental fragment variables argument (as opposed to deprecated `valueFromAST()` function). +**Breaking change.** The positional `GraphQLError` constructor was removed. +Pass a message and an options object. -## Features +```diff +- new GraphQLError(message, nodes, source, positions, path, originalError); ++ new GraphQLError(message, { ++ nodes, ++ source, ++ positions, ++ path, ++ originalError, ++ extensions, ++ }); +``` -- Added `hideSuggestions` option to `execute`/`validate`/`subscribe`/... to hide schema-suggestions in error messages -- Added `abortSignal` option to `graphql()`, `execute()`, and `subscribe()` allows cancellation of these methods; - `info.abortSignal` can also be used in field resolvers to cancel asynchronous work that they initiate. -- `extensions` support `symbol` keys, in addition to the normal string keys. -- Added ability for resolver functions to return async iterables. -- Added `perEventExecutor` execution option to allows specifying a custom executor for subscription source stream events, which can be useful for preparing a per event execution context argument. -- Added `validateInputValue` and `validateInputLiteral` helpers to validate input values and literals, respectively. -- Added `replaceVariableValues` helper to replace variables within complex scalars uses as inputs. Internally, this allows variables embedded within complex scalars to finally use the correct default values. -- Added new `printDirective` helper. +## Practical Migration Order + +1. Update Node.js, TypeScript, and package-entry imports. +2. Compile and replace removed helpers, removed alias types, and positional + `GraphQLError` calls. +3. Run `validateSchema()` and migrate invalid or ambiguous defaults to the new + `default` model. +4. Update execution hosts: `execute()` versus + `experimentalExecuteIncrementally()`, `createSourceEventStream()` validation, + and subscription return types. +5. Migrate custom scalars to the v17 coercion method names while keeping the + v16 names if you still support v16. +6. Adopt optional host features such as development mode, harnesses, abort + signals, execution hooks, and fragment arguments only where they match your + server design. + +Run schema validation, operation validation, execution tests, and TypeScript +checks after each group. The upgrade is easiest to review when mechanical +changes are separated from behavior changes. diff --git a/website/vercel.json b/website/vercel.json index 9f11ce21b7..7914fe17eb 100644 --- a/website/vercel.json +++ b/website/vercel.json @@ -1,5 +1,10 @@ { "redirects": [ + { + "source": "/api-v16/graphql-http", + "destination": "/docs/graphql-http", + "permanent": true + }, { "source": "/api", "destination": "/api-v16/graphql",