Socket
Socket
Sign inDemoInstall

graphql

Package Overview
Dependencies
Maintainers
8
Versions
258
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

graphql - npm Package Compare versions

Comparing version 16.8.2 to 16.9.0-canary.pr.4159.0fa29326c53fcd63c6473c7357c28aa13fa0019d

validation/rules/MaxIntrospectionDepthRule.d.ts

10

execution/collectFields.d.ts

@@ -9,2 +9,6 @@ import type { ObjMap } from '../jsutils/ObjMap';

import type { GraphQLSchema } from '../type/schema';
export interface FieldDetails {
node: FieldNode;
fragmentVariableValues?: ObjMap<unknown> | undefined;
}
/**

@@ -27,3 +31,3 @@ * Given a selectionSet, collects all of the fields and returns them.

selectionSet: SelectionSetNode,
): Map<string, ReadonlyArray<FieldNode>>;
): Map<string, ReadonlyArray<FieldDetails>>;
/**

@@ -46,3 +50,3 @@ * Given an array of field nodes, collects all of the subfields of the passed

returnType: GraphQLObjectType,
fieldNodes: ReadonlyArray<FieldNode>,
): Map<string, ReadonlyArray<FieldNode>>;
fieldEntries: ReadonlyArray<FieldDetails>,
): Map<string, ReadonlyArray<FieldDetails>>;

@@ -44,2 +44,3 @@ 'use strict';

new Set(),
undefined,
);

@@ -64,9 +65,9 @@ return fields;

returnType,
fieldNodes,
fieldEntries,
) {
const subFieldNodes = new Map();
const subFieldEntries = new Map();
const visitedFragmentNames = new Set();
for (const node of fieldNodes) {
if (node.selectionSet) {
for (const entry of fieldEntries) {
if (entry.node.selectionSet) {
collectFieldsImpl(

@@ -77,4 +78,4 @@ schema,

returnType,
node.selectionSet,
subFieldNodes,
entry.node.selectionSet,
subFieldEntries,
visitedFragmentNames,

@@ -85,3 +86,3 @@ );

return subFieldNodes;
return subFieldEntries;
}

@@ -97,2 +98,3 @@

visitedFragmentNames,
localVariableValues,
) {

@@ -102,3 +104,8 @@ for (const selection of selectionSet.selections) {

case _kinds.Kind.FIELD: {
if (!shouldIncludeNode(variableValues, selection)) {
const vars =
localVariableValues !== null && localVariableValues !== void 0
? localVariableValues
: variableValues;
if (!shouldIncludeNode(vars, selection)) {
continue;

@@ -111,5 +118,19 @@ }

if (fieldList !== undefined) {
fieldList.push(selection);
fieldList.push({
node: selection,
fragmentVariableValues:
localVariableValues !== null && localVariableValues !== void 0
? localVariableValues
: undefined,
});
} else {
fields.set(name, [selection]);
fields.set(name, [
{
node: selection,
fragmentVariableValues:
localVariableValues !== null && localVariableValues !== void 0
? localVariableValues
: undefined,
},
]);
}

@@ -158,4 +179,21 @@

continue;
}
} // We need to introduce a concept of shadowing:
//
// - when a fragment defines a variable that is in the parent scope but not given
// in the fragment-spread we need to look at this variable as undefined and check
// whether the definition has a defaultValue, if not remove it from the variableValues.
// - when a fragment does not define a variable we need to copy it over from the parent
// scope as that variable can still get used in spreads later on in the selectionSet.
// - when a value is passed in through the fragment-spread we need to copy over the key-value
// into our variable-values.
const fragmentVariableValues = fragment.variableDefinitions
? (0, _values.getArgumentValuesFromSpread)(
selection,
schema,
fragment.variableDefinitions,
variableValues,
localVariableValues,
)
: undefined;
collectFieldsImpl(

@@ -169,2 +207,3 @@ schema,

visitedFragmentNames,
fragmentVariableValues,
);

@@ -171,0 +210,0 @@ break;

@@ -9,3 +9,2 @@ import type { Maybe } from '../jsutils/Maybe';

DocumentNode,
FieldNode,
FragmentDefinitionNode,

@@ -22,2 +21,3 @@ OperationDefinitionNode,

import type { GraphQLSchema } from '../type/schema';
import type { FieldDetails } from './collectFields';
/**

@@ -147,3 +147,3 @@ * Terminology

fieldDef: GraphQLField<unknown, unknown>,
fieldNodes: ReadonlyArray<FieldNode>,
fieldEntries: ReadonlyArray<FieldDetails>,
parentType: GraphQLObjectType,

@@ -187,3 +187,3 @@ path: Path,

parentType: GraphQLObjectType,
fieldNode: FieldNode,
entry: FieldDetails,
): Maybe<GraphQLField<unknown, unknown>>;

@@ -456,6 +456,6 @@ 'use strict';

function executeField(exeContext, parentType, source, fieldNodes, path) {
function executeField(exeContext, parentType, source, fieldEntries, path) {
var _fieldDef$resolve;
const fieldDef = getFieldDef(exeContext.schema, parentType, fieldNodes[0]);
const fieldDef = getFieldDef(exeContext.schema, parentType, fieldEntries[0]);

@@ -475,3 +475,3 @@ if (!fieldDef) {

fieldDef,
fieldNodes,
fieldEntries,
parentType,

@@ -486,5 +486,6 @@ path,

const args = (0, _values.getArgumentValues)(
fieldDef,
fieldNodes[0],
fieldEntries[0].node,
fieldDef.args,
exeContext.variableValues,
fieldEntries[0].fragmentVariableValues,
); // The resolve function's optional third argument is a context value that

@@ -500,3 +501,10 @@ // is provided to every resolve function within an execution. It is commonly

completed = result.then((resolved) =>
completeValue(exeContext, returnType, fieldNodes, info, path, resolved),
completeValue(
exeContext,
returnType,
fieldEntries,
info,
path,
resolved,
),
);

@@ -507,3 +515,3 @@ } else {

returnType,
fieldNodes,
fieldEntries,
info,

@@ -521,3 +529,3 @@ path,

rawError,
fieldNodes,
fieldEntries.map((entry) => entry.node),
(0, _Path.pathToArray)(path),

@@ -533,3 +541,3 @@ );

rawError,
fieldNodes,
fieldEntries.map((entry) => entry.node),
(0, _Path.pathToArray)(path),

@@ -544,3 +552,9 @@ );

function buildResolveInfo(exeContext, fieldDef, fieldNodes, parentType, path) {
function buildResolveInfo(
exeContext,
fieldDef,
fieldEntries,
parentType,
path,
) {
// The resolve function's optional fourth argument is a collection of

@@ -550,3 +564,3 @@ // information about the current execution state.

fieldName: fieldDef.name,
fieldNodes,
fieldNodes: fieldEntries.map((entry) => entry.node),
returnType: fieldDef.type,

@@ -682,3 +696,3 @@ parentType,

returnType,
fieldNodes,
fieldEntries,
info,

@@ -710,3 +724,3 @@ path,

itemType,
fieldNodes,
fieldEntries,
info,

@@ -721,3 +735,3 @@ itemPath,

itemType,
fieldNodes,
fieldEntries,
info,

@@ -736,3 +750,3 @@ itemPath,

rawError,
fieldNodes,
fieldEntries.map((entry) => entry.node),
(0, _Path.pathToArray)(itemPath),

@@ -748,3 +762,3 @@ );

rawError,
fieldNodes,
fieldEntries.map((entry) => entry.node),
(0, _Path.pathToArray)(itemPath),

@@ -785,3 +799,3 @@ );

returnType,
fieldNodes,
fieldEntries,
info,

@@ -800,2 +814,3 @@ path,

const runtimeType = resolveTypeFn(result, contextValue, info, returnType);
const fieldNodes = fieldEntries.map((entry) => entry.node);

@@ -814,3 +829,3 @@ if ((0, _isPromise.isPromise)(runtimeType)) {

),
fieldNodes,
fieldEntries,
info,

@@ -833,3 +848,3 @@ path,

),
fieldNodes,
fieldEntries,
info,

@@ -909,3 +924,3 @@ path,

returnType,
fieldNodes,
fieldEntries,
info,

@@ -916,3 +931,3 @@ path,

// Collect sub-fields to execute to complete this value.
const subFieldNodes = collectSubfields(exeContext, returnType, fieldNodes); // If there is an isTypeOf predicate function, call it with the
const subFieldNodes = collectSubfields(exeContext, returnType, fieldEntries); // If there is an isTypeOf predicate function, call it with the
// current result. If isTypeOf returns false, then raise an error rather

@@ -927,3 +942,7 @@ // than continuing execution.

if (!resolvedIsTypeOf) {
throw invalidReturnTypeError(returnType, result, fieldNodes);
throw invalidReturnTypeError(
returnType,
result,
fieldEntries.map((entry) => entry.node),
);
}

@@ -942,3 +961,7 @@

if (!isTypeOf) {
throw invalidReturnTypeError(returnType, result, fieldNodes);
throw invalidReturnTypeError(
returnType,
result,
fieldEntries.map((entry) => entry.node),
);
}

@@ -1041,4 +1064,4 @@ }

function getFieldDef(schema, parentType, fieldNode) {
const fieldName = fieldNode.name.value;
function getFieldDef(schema, parentType, entry) {
const fieldName = entry.node.name.value;

@@ -1045,0 +1068,0 @@ if (

@@ -185,11 +185,11 @@ 'use strict';

);
const [responseName, fieldNodes] = [...rootFields.entries()][0];
const fieldDef = (0, _execute.getFieldDef)(schema, rootType, fieldNodes[0]);
const [responseName, fieldEntries] = [...rootFields.entries()][0];
const fieldDef = (0, _execute.getFieldDef)(schema, rootType, fieldEntries[0]);
if (!fieldDef) {
const fieldName = fieldNodes[0].name.value;
const fieldName = fieldEntries[0].node.name.value;
throw new _GraphQLError.GraphQLError(
`The subscription field "${fieldName}" is not defined.`,
{
nodes: fieldNodes,
nodes: fieldEntries.map((entry) => entry.node),
},

@@ -203,3 +203,3 @@ );

fieldDef,
fieldNodes,
fieldEntries,
rootType,

@@ -217,4 +217,4 @@ path,

const args = (0, _values.getArgumentValues)(
fieldDef,
fieldNodes[0],
fieldEntries[0].node,
fieldDef.args,
variableValues,

@@ -243,3 +243,3 @@ ); // The resolve function's optional third argument is a context value that

error,
fieldNodes,
fieldEntries.map((entry) => entry.node),
(0, _Path.pathToArray)(path),

@@ -246,0 +246,0 @@ );

@@ -7,5 +7,6 @@ import type { Maybe } from '../jsutils/Maybe';

FieldNode,
FragmentSpreadNode,
VariableDefinitionNode,
} from '../language/ast';
import type { GraphQLField } from '../type/definition';
import type { GraphQLArgument } from '../type/definition';
import type { GraphQLDirective } from '../type/directives';

@@ -52,8 +53,19 @@ import type { GraphQLSchema } from '../type/schema';

export declare function getArgumentValues(
def: GraphQLField<unknown, unknown> | GraphQLDirective,
node: FieldNode | DirectiveNode,
argDefs: ReadonlyArray<GraphQLArgument>,
variableValues?: Maybe<ObjMap<unknown>>,
fragmentArgValues?: Maybe<ObjMap<unknown>>,
): {
[argument: string]: unknown;
};
export declare function getArgumentValuesFromSpread(
/** NOTE: For error annotations only */
node: FragmentSpreadNode,
schema: GraphQLSchema,
fragmentVarDefs: ReadonlyArray<VariableDefinitionNode>,
variableValues: Maybe<ObjMap<unknown>>,
fragmentArgValues?: Maybe<ObjMap<unknown>>,
): {
[argument: string]: unknown;
};
/**

@@ -60,0 +72,0 @@ * Prepares an object map of argument values given a directive definition

@@ -7,2 +7,3 @@ 'use strict';

exports.getArgumentValues = getArgumentValues;
exports.getArgumentValuesFromSpread = getArgumentValuesFromSpread;
exports.getDirectiveValues = getDirectiveValues;

@@ -31,2 +32,4 @@ exports.getVariableValues = getVariableValues;

var _valueFromASTUntyped = require('../utilities/valueFromASTUntyped.js');
/**

@@ -169,3 +172,3 @@ * Prepares an object map of variableValues of the correct type based on the

function getArgumentValues(def, node, variableValues) {
function getArgumentValues(node, argDefs, variableValues, fragmentArgValues) {
var _node$arguments;

@@ -186,3 +189,3 @@

for (const argDef of def.args) {
for (const argDef of argDefs) {
const name = argDef.name;

@@ -210,3 +213,3 @@ const argType = argDef.type;

const valueNode = argumentNode.value;
let isNull = valueNode.kind === _kinds.Kind.NULL;
let hasValue = valueNode.kind !== _kinds.Kind.NULL;

@@ -217,26 +220,35 @@ if (valueNode.kind === _kinds.Kind.VARIABLE) {

if (
variableValues == null ||
!hasOwnProperty(variableValues, variableName)
fragmentArgValues != null &&
hasOwnProperty(fragmentArgValues, variableName)
) {
if (argDef.defaultValue !== undefined) {
hasValue = fragmentArgValues[variableName] != null;
if (!hasValue && argDef.defaultValue !== undefined) {
coercedValues[name] = argDef.defaultValue;
} else if ((0, _definition.isNonNullType)(argType)) {
throw new _GraphQLError.GraphQLError(
`Argument "${name}" of required type "${(0, _inspect.inspect)(
argType,
)}" ` +
`was provided the variable "$${variableName}" which was not provided a runtime value.`,
{
nodes: valueNode,
},
);
continue;
}
} else if (
variableValues != null &&
hasOwnProperty(variableValues, variableName)
) {
hasValue = variableValues[variableName] != null;
} else if (argDef.defaultValue !== undefined) {
coercedValues[name] = argDef.defaultValue;
continue;
} else if ((0, _definition.isNonNullType)(argType)) {
throw new _GraphQLError.GraphQLError(
`Argument "${name}" of required type "${(0, _inspect.inspect)(
argType,
)}" ` +
`was provided the variable "$${variableName}" which was not provided a runtime value.`,
{
nodes: valueNode,
},
);
} else {
continue;
}
isNull = variableValues[variableName] == null;
}
if (isNull && (0, _definition.isNonNullType)(argType)) {
if (!hasValue && (0, _definition.isNonNullType)(argType)) {
throw new _GraphQLError.GraphQLError(

@@ -252,7 +264,6 @@ `Argument "${name}" of non-null type "${(0, _inspect.inspect)(

const coercedValue = (0, _valueFromAST.valueFromAST)(
valueNode,
argType,
variableValues,
);
const coercedValue = (0, _valueFromAST.valueFromAST)(valueNode, argType, {
...variableValues,
...fragmentArgValues,
});

@@ -278,2 +289,93 @@ if (coercedValue === undefined) {

}
function getArgumentValuesFromSpread(
/** NOTE: For error annotations only */
node,
schema,
fragmentVarDefs,
variableValues,
fragmentArgValues,
) {
var _node$arguments2;
const coercedValues = {};
const argNodeMap = (0, _keyMap.keyMap)(
(_node$arguments2 =
node === null || node === void 0 ? void 0 : node.arguments) !== null &&
_node$arguments2 !== void 0
? _node$arguments2
: [],
(arg) => arg.name.value,
);
for (const varDef of fragmentVarDefs) {
const name = varDef.variable.name.value;
const argType = (0, _typeFromAST.typeFromAST)(schema, varDef.type);
const argumentNode = argNodeMap[name];
if (argumentNode == null) {
if (varDef.defaultValue !== undefined) {
coercedValues[name] = (0, _valueFromASTUntyped.valueFromASTUntyped)(
varDef.defaultValue,
);
} else if ((0, _definition.isNonNullType)(argType)) {
throw new _GraphQLError.GraphQLError(
`Argument "${name}" of required type "${(0, _inspect.inspect)(
argType,
)}" ` + 'was not provided.',
{
nodes: node,
},
);
} else {
coercedValues[name] = undefined;
}
continue;
}
const valueNode = argumentNode.value;
let hasValue = valueNode.kind !== _kinds.Kind.NULL;
if (valueNode.kind === _kinds.Kind.VARIABLE) {
const variableName = valueNode.name.value;
if (
fragmentArgValues != null &&
hasOwnProperty(fragmentArgValues, variableName)
) {
hasValue = fragmentArgValues[variableName] != null;
} else if (
variableValues != null &&
hasOwnProperty(variableValues, variableName)
) {
hasValue = variableValues[variableName] != null;
}
}
if (!hasValue && (0, _definition.isNonNullType)(argType)) {
throw new _GraphQLError.GraphQLError(
`Argument "${name}" of non-null type "${(0, _inspect.inspect)(
argType,
)}" ` + 'must not be null.',
{
nodes: valueNode,
},
);
}
let coercedValue;
if (argType && (0, _definition.isInputType)(argType)) {
coercedValue = (0, _valueFromAST.valueFromAST)(valueNode, argType, {
...variableValues,
...fragmentArgValues,
});
}
coercedValues[name] = coercedValue;
}
return coercedValues;
}
/**

@@ -302,3 +404,3 @@ * Prepares an object map of argument values given a directive definition

if (directiveNode) {
return getArgumentValues(directiveDef, directiveNode, variableValues);
return getArgumentValues(directiveNode, directiveDef.args, variableValues);
}

@@ -305,0 +407,0 @@ }

@@ -57,2 +57,3 @@ /**

GraphQLSpecifiedByDirective,
GraphQLOneOfDirective,
TypeKind,

@@ -304,2 +305,3 @@ DEFAULT_DEPRECATION_REASON,

specifiedRules,
recommendedRules,
ExecutableDefinitionsRule,

@@ -331,2 +333,3 @@ FieldsOnCorrectTypeRule,

VariablesInAllowedPositionRule,
MaxIntrospectionDepthRule,
LoneSchemaDefinitionRule,

@@ -333,0 +336,0 @@ UniqueOperationTypesRule,

@@ -150,2 +150,8 @@ 'use strict';

});
Object.defineProperty(exports, 'GraphQLOneOfDirective', {
enumerable: true,
get: function () {
return _index.GraphQLOneOfDirective;
},
});
Object.defineProperty(exports, 'GraphQLScalarType', {

@@ -241,2 +247,8 @@ enumerable: true,

});
Object.defineProperty(exports, 'MaxIntrospectionDepthRule', {
enumerable: true,
get: function () {
return _index4.MaxIntrospectionDepthRule;
},
});
Object.defineProperty(exports, 'NoDeprecatedCustomRule', {

@@ -1136,2 +1148,8 @@ enumerable: true,

});
Object.defineProperty(exports, 'recommendedRules', {
enumerable: true,
get: function () {
return _index4.recommendedRules;
},
});
Object.defineProperty(exports, 'resolveObjMapThunk', {

@@ -1138,0 +1156,0 @@ enumerable: true,

@@ -236,2 +236,3 @@ import type { Kind } from './kinds';

readonly name: NameNode;
readonly arguments?: ReadonlyArray<ArgumentNode>;
readonly directives?: ReadonlyArray<DirectiveNode>;

@@ -250,3 +251,2 @@ }

readonly name: NameNode;
/** @deprecated variableDefinitions will be removed in v17.0.0 */
readonly variableDefinitions?: ReadonlyArray<VariableDefinitionNode>;

@@ -253,0 +253,0 @@ readonly typeCondition: NamedTypeNode;

@@ -144,6 +144,6 @@ 'use strict';

Argument: ['name', 'value'],
FragmentSpread: ['name', 'directives'],
FragmentSpread: ['name', 'arguments', 'directives'],
InlineFragment: ['typeCondition', 'directives', 'selectionSet'],
FragmentDefinition: [
'name', // Note: fragment variable definitions are deprecated and will removed in v17.0.0
'name',
'variableDefinitions',

@@ -150,0 +150,0 @@ 'typeCondition',

@@ -26,2 +26,3 @@ /**

INPUT_FIELD_DEFINITION = 'INPUT_FIELD_DEFINITION',
FRAGMENT_VARIABLE_DEFINITION = 'FRAGMENT_VARIABLE_DEFINITION',
}

@@ -28,0 +29,0 @@ export { DirectiveLocation };

@@ -34,2 +34,4 @@ 'use strict';

DirectiveLocation['INPUT_FIELD_DEFINITION'] = 'INPUT_FIELD_DEFINITION';
DirectiveLocation['FRAGMENT_VARIABLE_DEFINITION'] =
'FRAGMENT_VARIABLE_DEFINITION';
})(DirectiveLocation || (exports.DirectiveLocation = DirectiveLocation = {}));

@@ -36,0 +38,0 @@ /**

@@ -91,2 +91,22 @@ import type { Maybe } from '../jsutils/Maybe';

allowLegacyFragmentVariables?: boolean;
/**
* 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.
*
* For example:
*
* ```graphql
* {
* t { ...A(var: true) }
* }
* fragment A($var: Boolean = false) on T {
* ...B(x: $var)
* }
* ```
*/
experimentalFragmentArguments?: boolean | undefined;
}

@@ -240,3 +260,3 @@ /**

*
* FragmentSpread : ... FragmentName Directives?
* FragmentSpread : ... FragmentName Arguments? Directives?
*

@@ -248,3 +268,3 @@ * InlineFragment : ... TypeCondition? Directives? SelectionSet

* FragmentDefinition :
* - fragment FragmentName on TypeCondition Directives? SelectionSet
* - fragment FragmentName VariableDefinitions? on TypeCondition Directives? SelectionSet
*

@@ -251,0 +271,0 @@ * TypeCondition : NamedType

@@ -403,3 +403,3 @@ 'use strict';

*
* FragmentSpread : ... FragmentName Directives?
* FragmentSpread : ... FragmentName Arguments? Directives?
*

@@ -415,5 +415,19 @@ * InlineFragment : ... TypeCondition? Directives? SelectionSet

if (!hasTypeCondition && this.peek(_tokenKind.TokenKind.NAME)) {
const name = this.parseFragmentName();
if (
this.peek(_tokenKind.TokenKind.PAREN_L) &&
this._options.experimentalFragmentArguments
) {
return this.node(start, {
kind: _kinds.Kind.FRAGMENT_SPREAD,
name,
arguments: this.parseArguments(false),
directives: this.parseDirectives(false),
});
}
return this.node(start, {
kind: _kinds.Kind.FRAGMENT_SPREAD,
name: this.parseFragmentName(),
name,
directives: this.parseDirectives(false),

@@ -432,3 +446,3 @@ });

* FragmentDefinition :
* - fragment FragmentName on TypeCondition Directives? SelectionSet
* - fragment FragmentName VariableDefinitions? on TypeCondition Directives? SelectionSet
*

@@ -440,20 +454,11 @@ * TypeCondition : NamedType

const start = this._lexer.token;
this.expectKeyword('fragment'); // Legacy support for defining variables within fragments changes
// the grammar of FragmentDefinition:
// - fragment FragmentName VariableDefinitions? on TypeCondition Directives? SelectionSet
if (this._options.allowLegacyFragmentVariables === true) {
return this.node(start, {
kind: _kinds.Kind.FRAGMENT_DEFINITION,
name: this.parseFragmentName(),
variableDefinitions: this.parseVariableDefinitions(),
typeCondition: (this.expectKeyword('on'), this.parseNamedType()),
directives: this.parseDirectives(false),
selectionSet: this.parseSelectionSet(),
});
}
this.expectKeyword('fragment');
return this.node(start, {
kind: _kinds.Kind.FRAGMENT_DEFINITION,
name: this.parseFragmentName(),
variableDefinitions:
this._options.experimentalFragmentArguments === true ||
this._options.allowLegacyFragmentVariables === true
? this.parseVariableDefinitions()
: undefined,
typeCondition: (this.expectKeyword('on'), this.parseNamedType()),

@@ -460,0 +465,0 @@ directives: this.parseDirectives(false),

@@ -64,9 +64,6 @@ 'use strict';

const prefix = wrap('', alias, ': ') + name;
let argsLine = prefix + wrap('(', join(args, ', '), ')');
if (argsLine.length > MAX_LINE_LENGTH) {
argsLine = prefix + wrap('(\n', indent(join(args, '\n')), '\n)');
}
return join([argsLine, join(directives, ' '), selectionSet], ' ');
return join(
[wrappedLineAndArgs(prefix, args), join(directives, ' '), selectionSet],
' ',
);
},

@@ -79,4 +76,8 @@ },

FragmentSpread: {
leave: ({ name, directives }) =>
'...' + name + wrap(' ', join(directives, ' ')),
leave: ({ name, arguments: args, directives }) => {
const prefix = '...' + name;
return (
wrappedLineAndArgs(prefix, args) + wrap(' ', join(directives, ' '))
);
},
},

@@ -354,1 +355,11 @@ InlineFragment: {

}
function wrappedLineAndArgs(prefix, args) {
let argsLine = prefix + wrap('(', join(args, ', '), ')');
if (argsLine.length > MAX_LINE_LENGTH) {
argsLine = prefix + wrap('(\n', indent(join(args, '\n')), '\n)');
}
return argsLine;
}
{
"name": "graphql",
"version": "16.8.2",
"version": "16.9.0-canary.pr.4159.0fa29326c53fcd63c6473c7357c28aa13fa0019d",
"description": "A Query Language and Runtime which can target any service.",

@@ -37,4 +37,5 @@ "license": "MIT",

"publishConfig": {
"tag": "latest"
}
}
"tag": "canary-pr-4159"
},
"deprecated": "You are using canary version build from https://github.com/graphql/graphql-js/pull/4159, no gurantees provided so please use your own discretion."
}

@@ -0,1 +1,3 @@

[![GraphQLConf 2024 Banner: September 10-12, San Francisco. Hosted by the GraphQL Foundation](https://github.com/user-attachments/assets/2d048502-e5b2-4e9d-a02a-50b841824de6)](https://graphql.org/conf/2024/?utm_source=github&utm_medium=graphql_js&utm_campaign=readme)
# GraphQL.js

@@ -2,0 +4,0 @@

@@ -792,3 +792,3 @@ import type { Maybe } from '../jsutils/Maybe';

description?: Maybe<string>;
values: GraphQLEnumValueConfigMap;
values: ThunkObjMap<GraphQLEnumValueConfig>;
extensions?: Maybe<Readonly<GraphQLEnumTypeExtensions>>;

@@ -799,2 +799,3 @@ astNode?: Maybe<EnumTypeDefinitionNode>;

interface GraphQLEnumTypeNormalizedConfig extends GraphQLEnumTypeConfig {
values: ObjMap<GraphQLEnumValueConfig>;
extensions: Readonly<GraphQLEnumTypeExtensions>;

@@ -870,2 +871,3 @@ extensionASTNodes: ReadonlyArray<EnumTypeExtensionNode>;

extensionASTNodes: ReadonlyArray<InputObjectTypeExtensionNode>;
isOneOf: boolean;
private _fields;

@@ -886,2 +888,3 @@ constructor(config: Readonly<GraphQLInputObjectTypeConfig>);

extensionASTNodes?: Maybe<ReadonlyArray<InputObjectTypeExtensionNode>>;
isOneOf?: boolean;
}

@@ -888,0 +891,0 @@ interface GraphQLInputObjectTypeNormalizedConfig

@@ -1080,7 +1080,8 @@ 'use strict';

: [];
this._values = defineEnumValues(this.name, config.values);
this._valueLookup = new Map(
this._values.map((enumValue) => [enumValue.value, enumValue]),
);
this._nameLookup = (0, _keyMap.keyMap)(this._values, (value) => value.name);
this._values =
typeof config.values === 'function'
? config.values
: defineEnumValues(this.name, config.values);
this._valueLookup = null;
this._nameLookup = null;
}

@@ -1093,2 +1094,6 @@

getValues() {
if (typeof this._values === 'function') {
this._values = defineEnumValues(this.name, this._values());
}
return this._values;

@@ -1098,2 +1103,9 @@ }

getValue(name) {
if (this._nameLookup === null) {
this._nameLookup = (0, _keyMap.keyMap)(
this.getValues(),
(value) => value.name,
);
}
return this._nameLookup[name];

@@ -1103,2 +1115,8 @@ }

serialize(outputValue) {
if (this._valueLookup === null) {
this._valueLookup = new Map(
this.getValues().map((enumValue) => [enumValue.value, enumValue]),
);
}
const enumValue = this._valueLookup.get(outputValue);

@@ -1260,3 +1278,3 @@

constructor(config) {
var _config$extensionASTN6;
var _config$extensionASTN6, _config$isOneOf;

@@ -1272,2 +1290,6 @@ this.name = (0, _assertName.assertName)(config.name);

: [];
this.isOneOf =
(_config$isOneOf = config.isOneOf) !== null && _config$isOneOf !== void 0
? _config$isOneOf
: false;
this._fields = defineInputFieldMap.bind(undefined, config);

@@ -1304,2 +1326,3 @@ }

extensionASTNodes: this.extensionASTNodes,
isOneOf: this.isOneOf,
};

@@ -1306,0 +1329,0 @@ }

@@ -80,2 +80,6 @@ import type { Maybe } from '../jsutils/Maybe';

/**
* Used to indicate an Input Object is a OneOf Input Object.
*/
export declare const GraphQLOneOfDirective: GraphQLDirective;
/**
* The full list of specified directives.

@@ -82,0 +86,0 @@ */

@@ -8,2 +8,3 @@ 'use strict';

exports.GraphQLSkipDirective =
exports.GraphQLOneOfDirective =
exports.GraphQLIncludeDirective =

@@ -211,6 +212,18 @@ exports.GraphQLDirective =

/**
* Used to indicate an Input Object is a OneOf Input Object.
*/
exports.GraphQLSpecifiedByDirective = GraphQLSpecifiedByDirective;
const GraphQLOneOfDirective = new GraphQLDirective({
name: 'oneOf',
description:
'Indicates exactly one field must be supplied and this field must not be `null`.',
locations: [_directiveLocation.DirectiveLocation.INPUT_OBJECT],
args: {},
});
/**
* The full list of specified directives.
*/
exports.GraphQLSpecifiedByDirective = GraphQLSpecifiedByDirective;
exports.GraphQLOneOfDirective = GraphQLOneOfDirective;
const specifiedDirectives = Object.freeze([

@@ -221,2 +234,3 @@ GraphQLIncludeDirective,

GraphQLSpecifiedByDirective,
GraphQLOneOfDirective,
]);

@@ -223,0 +237,0 @@ exports.specifiedDirectives = specifiedDirectives;

@@ -116,2 +116,3 @@ export type { Path as ResponsePath } from '../jsutils/Path';

GraphQLSpecifiedByDirective,
GraphQLOneOfDirective,
DEFAULT_DEPRECATION_REASON,

@@ -118,0 +119,0 @@ } from './directives';

@@ -102,2 +102,8 @@ 'use strict';

});
Object.defineProperty(exports, 'GraphQLOneOfDirective', {
enumerable: true,
get: function () {
return _directives.GraphQLOneOfDirective;
},
});
Object.defineProperty(exports, 'GraphQLScalarType', {

@@ -104,0 +110,0 @@ enumerable: true,

@@ -170,4 +170,8 @@ 'use strict';

value: _directiveLocation.DirectiveLocation.VARIABLE_DEFINITION,
description: 'Location adjacent to a variable definition.',
description: 'Location adjacent to an operation variable definition.',
},
FRAGMENT_VARIABLE_DEFINITION: {
value: _directiveLocation.DirectiveLocation.FRAGMENT_VARIABLE_DEFINITION,
description: 'Location adjacent to a fragment variable definition.',
},
SCHEMA: {

@@ -377,2 +381,10 @@ value: _directiveLocation.DirectiveLocation.SCHEMA,

},
isOneOf: {
type: _scalars.GraphQLBoolean,
resolve: (type) => {
if ((0, _definition.isInputObjectType)(type)) {
return type.isOneOf;
}
},
},
}),

@@ -379,0 +391,0 @@ });

@@ -571,5 +571,29 @@ 'use strict';

}
if (inputObj.isOneOf) {
validateOneOfInputObjectField(inputObj, field, context);
}
}
}
function validateOneOfInputObjectField(type, field, context) {
if ((0, _definition.isNonNullType)(field.type)) {
var _field$astNode4;
context.reportError(
`OneOf input field ${type.name}.${field.name} must be nullable.`,
(_field$astNode4 = field.astNode) === null || _field$astNode4 === void 0
? void 0
: _field$astNode4.type,
);
}
if (field.defaultValue !== undefined) {
context.reportError(
`OneOf input field ${type.name}.${field.name} cannot have a default value.`,
field.astNode,
);
}
}
function createInputObjectCircularRefsValidator(context) {

@@ -576,0 +600,0 @@ // Modified copy of algorithm from 'src/validation/rules/NoFragmentCycles.js'.

@@ -108,2 +108,6 @@ 'use strict';

: options.allowLegacyFragmentVariables,
experimentalFragmentArguments:
options === null || options === void 0
? void 0
: options.experimentalFragmentArguments,
});

@@ -110,0 +114,0 @@ return buildASTSchema(document, {

@@ -282,2 +282,3 @@ 'use strict';

fields: () => buildInputValueDefMap(inputObjectIntrospection.inputFields),
isOneOf: inputObjectIntrospection.isOneOf,
});

@@ -284,0 +285,0 @@ }

@@ -142,2 +142,27 @@ 'use strict';

if (type.isOneOf) {
const keys = Object.keys(coercedValue);
if (keys.length !== 1) {
onError(
(0, _Path.pathToArray)(path),
inputValue,
new _GraphQLError.GraphQLError(
`Exactly one key must be specified for OneOf type "${type.name}".`,
),
);
}
const key = keys[0];
const value = coercedValue[key];
if (value === null) {
onError(
(0, _Path.pathToArray)(path).concat(key),
value,
new _GraphQLError.GraphQLError(`Field "${key}" must be non-null.`),
);
}
}
return coercedValue;

@@ -144,0 +169,0 @@ }

@@ -760,2 +760,3 @@ 'use strict';

extensionASTNodes,
isOneOf: isOneOf(astNode),
});

@@ -800,1 +801,10 @@ }

}
/**
* Given an input object node, returns if the node should be OneOf.
*/
function isOneOf(node) {
return Boolean(
(0, _values.getDirectiveValues)(_directives.GraphQLOneOfDirective, node),
);
}

@@ -29,2 +29,7 @@ import type { Maybe } from '../jsutils/Maybe';

inputValueDeprecation?: boolean;
/**
* Whether target GraphQL server supports `@oneOf` input objects.
* Default: false
*/
oneOf?: boolean;
}

@@ -116,2 +121,3 @@ /**

readonly inputFields: ReadonlyArray<IntrospectionInputValue>;
readonly isOneOf: boolean;
}

@@ -118,0 +124,0 @@ export interface IntrospectionListTypeRef<

@@ -19,2 +19,3 @@ 'use strict';

inputValueDeprecation: false,
oneOf: false,
...options,

@@ -37,2 +38,3 @@ };

const oneOf = optionsWithDefault.oneOf ? 'isOneOf' : '';
return `

@@ -65,2 +67,3 @@ query IntrospectionQuery {

${specifiedByUrl}
${oneOf}
fields(includeDeprecated: true) {

@@ -67,0 +70,0 @@ name

@@ -31,2 +31,3 @@ 'use strict';

inputValueDeprecation: true,
oneOf: true,
...options,

@@ -33,0 +34,0 @@ };

@@ -217,3 +217,8 @@ 'use strict';

);
return printDescription(type) + `input ${type.name}` + printBlock(fields);
return (
printDescription(type) +
`input ${type.name}` +
(type.isOneOf ? ' @oneOf' : '') +
printBlock(fields)
);
}

@@ -220,0 +225,0 @@

@@ -30,2 +30,4 @@ import type { Maybe } from '../jsutils/Maybe';

private _enumValue;
private _fragmentSpread;
private _fragmentDefinitions;
private _getFieldDef;

@@ -32,0 +34,0 @@ constructor(

@@ -21,2 +21,4 @@ 'use strict';

var _valueFromAST = require('./valueFromAST.js');
/**

@@ -47,2 +49,4 @@ * TypeInfo is a utility class which, given a GraphQL schema, can keep track

this._enumValue = null;
this._fragmentSpread = null;
this._fragmentDefinitions = {};
this._getFieldDef =

@@ -127,2 +131,15 @@ getFieldDefFn !== null && getFieldDefFn !== void 0

switch (node.kind) {
case _kinds.Kind.DOCUMENT: {
// A document's fragment definitions are type signatures
// referenced via fragment spreads. Ensure we can use definitions
// before visiting their call sites.
for (const astNode of node.definitions) {
if (astNode.kind === _kinds.Kind.FRAGMENT_DEFINITION) {
this._fragmentDefinitions[astNode.name.value] = astNode;
}
}
break;
}
case _kinds.Kind.SELECTION_SET: {

@@ -174,2 +191,7 @@ const namedType = (0, _definition.getNamedType)(this.getType());

case _kinds.Kind.FRAGMENT_SPREAD: {
this._fragmentSpread = node;
break;
}
case _kinds.Kind.INLINE_FRAGMENT:

@@ -200,22 +222,62 @@ case _kinds.Kind.FRAGMENT_DEFINITION: {

case _kinds.Kind.ARGUMENT: {
var _this$getDirective;
let argDef;
let argType;
const fieldOrDirective =
(_this$getDirective = this.getDirective()) !== null &&
_this$getDirective !== void 0
? _this$getDirective
: this.getFieldDef();
const directive = this.getDirective();
const fragmentSpread = this._fragmentSpread;
const fieldDef = this.getFieldDef();
if (fieldOrDirective) {
argDef = fieldOrDirective.args.find(
(arg) => arg.name === node.name.value,
);
if (directive) {
argDef = directive.args.find((arg) => arg.name === node.name.value);
} else if (fragmentSpread) {
var _fragmentDef$variable;
if (argDef) {
argType = argDef.type;
const fragmentDef =
this._fragmentDefinitions[fragmentSpread.name.value];
const fragVarDef =
fragmentDef === null || fragmentDef === void 0
? void 0
: (_fragmentDef$variable = fragmentDef.variableDefinitions) ===
null || _fragmentDef$variable === void 0
? void 0
: _fragmentDef$variable.find(
(varDef) => varDef.variable.name.value === node.name.value,
);
if (fragVarDef) {
const fragVarType = (0, _typeFromAST.typeFromAST)(
schema,
fragVarDef.type,
);
if ((0, _definition.isInputType)(fragVarType)) {
const fragVarDefault = fragVarDef.defaultValue
? (0, _valueFromAST.valueFromAST)(
fragVarDef.defaultValue,
fragVarType,
)
: undefined;
const schemaArgDef = {
name: fragVarDef.variable.name.value,
type: fragVarType,
defaultValue: fragVarDefault,
description: undefined,
deprecationReason: undefined,
extensions: {},
astNode: {
...fragVarDef,
kind: _kinds.Kind.INPUT_VALUE_DEFINITION,
name: fragVarDef.variable.name,
},
};
argDef = schemaArgDef;
}
}
} else if (fieldDef) {
argDef = fieldDef.args.find((arg) => arg.name === node.name.value);
}
if (argDef) {
argType = argDef.type;
}
this._argument = argDef;

@@ -291,2 +353,6 @@

switch (node.kind) {
case _kinds.Kind.DOCUMENT:
this._fragmentDefinitions = {};
break;
case _kinds.Kind.SELECTION_SET:

@@ -308,2 +374,6 @@ this._parentTypeStack.pop();

case _kinds.Kind.FRAGMENT_SPREAD:
this._fragmentSpread = null;
break;
case _kinds.Kind.OPERATION_DEFINITION:

@@ -310,0 +380,0 @@ case _kinds.Kind.INLINE_FRAGMENT:

@@ -148,2 +148,14 @@ 'use strict';

if (type.isOneOf) {
const keys = Object.keys(coercedObj);
if (keys.length !== 1) {
return; // Invalid: not exactly one key, intentionally return no value.
}
if (coercedObj[keys[0]] === null) {
return; // Invalid: value not non-null, intentionally return no value.
}
}
return coercedObj;

@@ -150,0 +162,0 @@ }

export { validate } from './validate';
export { ValidationContext } from './ValidationContext';
export type { ValidationRule } from './ValidationContext';
export { specifiedRules } from './specifiedRules';
export { specifiedRules, recommendedRules } from './specifiedRules';
export { ExecutableDefinitionsRule } from './rules/ExecutableDefinitionsRule';

@@ -20,2 +20,3 @@ export { FieldsOnCorrectTypeRule } from './rules/FieldsOnCorrectTypeRule';

export { ProvidedRequiredArgumentsRule } from './rules/ProvidedRequiredArgumentsRule';
export { NoUnusedFragmentVariablesRule } from './rules/NoUnusedFragmentVariablesRule';
export { ScalarLeafsRule } from './rules/ScalarLeafsRule';

@@ -32,2 +33,3 @@ export { SingleFieldSubscriptionsRule } from './rules/SingleFieldSubscriptionsRule';

export { VariablesInAllowedPositionRule } from './rules/VariablesInAllowedPositionRule';
export { MaxIntrospectionDepthRule } from './rules/MaxIntrospectionDepthRule';
export { LoneSchemaDefinitionRule } from './rules/LoneSchemaDefinitionRule';

@@ -34,0 +36,0 @@ export { UniqueOperationTypesRule } from './rules/UniqueOperationTypesRule';

@@ -60,2 +60,8 @@ 'use strict';

});
Object.defineProperty(exports, 'MaxIntrospectionDepthRule', {
enumerable: true,
get: function () {
return _MaxIntrospectionDepthRule.MaxIntrospectionDepthRule;
},
});
Object.defineProperty(exports, 'NoDeprecatedCustomRule', {

@@ -85,2 +91,8 @@ enumerable: true,

});
Object.defineProperty(exports, 'NoUnusedFragmentVariablesRule', {
enumerable: true,
get: function () {
return _NoUnusedFragmentVariablesRule.NoUnusedFragmentVariablesRule;
},
});
Object.defineProperty(exports, 'NoUnusedFragmentsRule', {

@@ -230,2 +242,8 @@ enumerable: true,

});
Object.defineProperty(exports, 'recommendedRules', {
enumerable: true,
get: function () {
return _specifiedRules.recommendedRules;
},
});
Object.defineProperty(exports, 'specifiedRules', {

@@ -280,2 +298,4 @@ enumerable: true,

var _NoUnusedFragmentVariablesRule = require('./rules/NoUnusedFragmentVariablesRule.js');
var _ScalarLeafsRule = require('./rules/ScalarLeafsRule.js');

@@ -303,2 +323,4 @@

var _MaxIntrospectionDepthRule = require('./rules/MaxIntrospectionDepthRule.js');
var _LoneSchemaDefinitionRule = require('./rules/LoneSchemaDefinitionRule.js');

@@ -305,0 +327,0 @@

@@ -99,4 +99,9 @@ 'use strict';

case _kinds.Kind.VARIABLE_DEFINITION:
return _directiveLocation.DirectiveLocation.VARIABLE_DEFINITION;
case _kinds.Kind.VARIABLE_DEFINITION: {
const parentNode = ancestors[ancestors.length - 3];
'kind' in parentNode || (0, _invariant.invariant)(false);
return parentNode.kind === _kinds.Kind.OPERATION_DEFINITION
? _directiveLocation.DirectiveLocation.VARIABLE_DEFINITION
: _directiveLocation.DirectiveLocation.FRAGMENT_VARIABLE_DEFINITION;
}

@@ -103,0 +108,0 @@ case _kinds.Kind.SCHEMA_DEFINITION:

@@ -29,3 +29,7 @@ 'use strict';

for (const { node } of usages) {
for (const { node, fragmentVarDef } of usages) {
if (fragmentVarDef) {
continue;
}
const varName = node.name.value;

@@ -32,0 +36,0 @@

@@ -9,3 +9,3 @@ import type { ASTVisitor } from '../../language/visitor';

*
* See https://spec.graphql.org/draft/#sec-All-Variables-Used
* See https://spec.graphql.org/draft/#sec-All-Operation-Variables-Used
*/

@@ -12,0 +12,0 @@ export declare function NoUnusedVariablesRule(

@@ -16,3 +16,3 @@ 'use strict';

*
* See https://spec.graphql.org/draft/#sec-All-Variables-Used
* See https://spec.graphql.org/draft/#sec-All-Operation-Variables-Used
*/

@@ -29,3 +29,3 @@ function NoUnusedVariablesRule(context) {

const variableNameUsed = Object.create(null);
const usages = context.getRecursiveVariableUsages(operation);
const usages = context.getOperationVariableUsages(operation);

@@ -32,0 +32,0 @@ for (const { node } of usages) {

@@ -16,2 +16,4 @@ 'use strict';

var _visitor = require('../../language/visitor.js');
var _definition = require('../../type/definition.js');

@@ -54,3 +56,3 @@

const cachedFieldsAndFragmentNames = new Map();
const cachedFieldsAndFragmentSpreads = new Map();
return {

@@ -60,3 +62,3 @@ SelectionSet(selectionSet) {

context,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,

@@ -82,2 +84,12 @@ context.getParentType(),

const printFragmentSpreadArguments = (fragmentSpread) => {
if (!fragmentSpread.arguments || fragmentSpread.arguments.length === 0) {
return fragmentSpread.name.value;
}
const printedArguments = fragmentSpread.arguments
.map(_printer.print)
.sort((a, b) => a.localeCompare(b));
return fragmentSpread.name.value + '(' + printedArguments.join(',') + ')';
};
/**

@@ -140,5 +152,6 @@ * Algorithm:

// GraphQL Document.
function findConflictsWithinSelectionSet(
context,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,

@@ -149,8 +162,8 @@ parentType,

const conflicts = [];
const [fieldMap, fragmentNames] = getFieldsAndFragmentNames(
const [fieldMap, fragmentSpreadMap] = getFieldsAndFragmentSpreads(
context,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
parentType,
selectionSet,
); // (A) Find find all conflicts "within" the fields of this selection set.
); // (A) First find all conflicts "within" the fields and fragment-spreads of this selection set.
// Note: this is the *only place* `collectConflictsWithin` is called.

@@ -161,19 +174,24 @@

conflicts,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,
fieldMap,
);
const allFragmentSpreads = [];
if (fragmentNames.length !== 0) {
for (const [, fragmentSpreads] of Object.entries(fragmentSpreadMap)) {
allFragmentSpreads.push(...fragmentSpreads);
}
if (allFragmentSpreads.length !== 0) {
// (B) Then collect conflicts between these fields and those represented by
// each spread fragment name found.
for (let i = 0; i < fragmentNames.length; i++) {
for (let i = 0; i < allFragmentSpreads.length; i++) {
collectConflictsBetweenFieldsAndFragment(
context,
conflicts,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,
false,
fieldMap,
fragmentNames[i],
allFragmentSpreads[i],
); // (C) Then compare this fragment with all other fragments found in this

@@ -184,11 +202,11 @@ // selection set to collect conflicts between fragments spread together.

for (let j = i + 1; j < fragmentNames.length; j++) {
for (let j = i + 1; j < allFragmentSpreads.length; j++) {
collectConflictsBetweenFragments(
context,
conflicts,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,
false,
fragmentNames[i],
fragmentNames[j],
allFragmentSpreads[i],
allFragmentSpreads[j],
);

@@ -206,8 +224,9 @@ }

conflicts,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,
areMutuallyExclusive,
fieldMap,
fragmentName,
fragmentSpread,
) {
const fragmentName = fragmentSpread.name.value;
const fragment = context.getFragment(fragmentName);

@@ -220,6 +239,7 @@

const [fieldMap2, referencedFragmentNames] =
getReferencedFieldsAndFragmentNames(
getReferencedFieldsAndFragmentSpreads(
context,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
fragment,
fragmentSpread,
); // Do not compare a fragment's fieldMap to itself.

@@ -235,3 +255,3 @@

conflicts,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,

@@ -244,3 +264,5 @@ areMutuallyExclusive,

for (const referencedFragmentName of referencedFragmentNames) {
for (const [referencedFragmentName, [spread]] of Object.entries(
referencedFragmentNames,
)) {
// Memoize so two fragments are not compared for conflicts more than once.

@@ -265,7 +287,7 @@ if (

conflicts,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,
areMutuallyExclusive,
fieldMap,
referencedFragmentName,
spread,
);

@@ -279,19 +301,33 @@ }

conflicts,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,
areMutuallyExclusive,
fragmentName1,
fragmentName2,
fragmentSpread1,
fragmentSpread2,
) {
// No need to compare a fragment to itself.
if (fragmentName1 === fragmentName2) {
const fragmentName1 = fragmentSpread1.name.value;
const fragmentName2 = fragmentSpread2.name.value;
if (
fragmentName1 === fragmentName2 &&
!sameArguments(fragmentSpread1, fragmentSpread2)
) {
context.reportError(
new _GraphQLError.GraphQLError(
`Spreads "${fragmentName1}" conflict because ${printFragmentSpreadArguments(
fragmentSpread1,
)} and ${printFragmentSpreadArguments(
fragmentSpread2,
)} have different fragment arguments.`,
{
nodes: [fragmentSpread1, fragmentSpread2],
},
),
);
return;
} // Memoize so two fragments are not compared for conflicts more than once.
} // No need to compare a fragment to itself.
if (
comparedFragmentPairs.has(
fragmentName1,
fragmentName2,
areMutuallyExclusive,
)
fragmentName1 === fragmentName2 &&
sameArguments(fragmentSpread1, fragmentSpread2)
) {

@@ -301,3 +337,10 @@ return;

comparedFragmentPairs.add(fragmentName1, fragmentName2, areMutuallyExclusive);
const fragKey1 = printFragmentSpreadArguments(fragmentSpread1);
const fragKey2 = printFragmentSpreadArguments(fragmentSpread2); // Memoize so two fragments are not compared for conflicts more than once.
if (comparedFragmentPairs.has(fragKey1, fragKey2, areMutuallyExclusive)) {
return;
}
comparedFragmentPairs.add(fragKey1, fragKey2, areMutuallyExclusive);
const fragment1 = context.getFragment(fragmentName1);

@@ -310,13 +353,15 @@ const fragment2 = context.getFragment(fragmentName2);

const [fieldMap1, referencedFragmentNames1] =
getReferencedFieldsAndFragmentNames(
const [fieldMap1, referencedFragmentSpreads1] =
getReferencedFieldsAndFragmentSpreads(
context,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
fragment1,
fragmentSpread1,
);
const [fieldMap2, referencedFragmentNames2] =
getReferencedFieldsAndFragmentNames(
const [fieldMap2, referencedFragmentSpreads2] =
getReferencedFieldsAndFragmentSpreads(
context,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
fragment2,
fragmentSpread2,
); // (F) First, collect all conflicts between these two collections of fields

@@ -328,3 +373,3 @@ // (not including any nested fragments).

conflicts,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,

@@ -337,11 +382,13 @@ areMutuallyExclusive,

for (const referencedFragmentName2 of referencedFragmentNames2) {
for (const [referencedFragmentSpread2] of Object.values(
referencedFragmentSpreads2,
)) {
collectConflictsBetweenFragments(
context,
conflicts,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,
areMutuallyExclusive,
fragmentName1,
referencedFragmentName2,
fragmentSpread1,
referencedFragmentSpread2,
);

@@ -351,11 +398,13 @@ } // (G) Then collect conflicts between the second fragment and any nested

for (const referencedFragmentName1 of referencedFragmentNames1) {
for (const [referencedFragmentSpread1] of Object.values(
referencedFragmentSpreads1,
)) {
collectConflictsBetweenFragments(
context,
conflicts,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,
areMutuallyExclusive,
referencedFragmentName1,
fragmentName2,
referencedFragmentSpread1,
fragmentSpread2,
);

@@ -369,3 +418,3 @@ }

context,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,

@@ -379,11 +428,11 @@ areMutuallyExclusive,

const conflicts = [];
const [fieldMap1, fragmentNames1] = getFieldsAndFragmentNames(
const [fieldMap1, fragmentSpreadsByName1] = getFieldsAndFragmentSpreads(
context,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
parentType1,
selectionSet1,
);
const [fieldMap2, fragmentNames2] = getFieldsAndFragmentNames(
const [fieldMap2, fragmentSpreadsByName2] = getFieldsAndFragmentSpreads(
context,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
parentType2,

@@ -396,3 +445,3 @@ selectionSet2,

conflicts,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,

@@ -405,11 +454,11 @@ areMutuallyExclusive,

for (const fragmentName2 of fragmentNames2) {
for (const [fragmentSpread2] of Object.values(fragmentSpreadsByName2)) {
collectConflictsBetweenFieldsAndFragment(
context,
conflicts,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,
areMutuallyExclusive,
fieldMap1,
fragmentName2,
fragmentSpread2,
);

@@ -419,11 +468,11 @@ } // (I) Then collect conflicts between the second collection of fields and

for (const fragmentName1 of fragmentNames1) {
for (const [fragmentSpread1] of Object.values(fragmentSpreadsByName1)) {
collectConflictsBetweenFieldsAndFragment(
context,
conflicts,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,
areMutuallyExclusive,
fieldMap2,
fragmentName1,
fragmentSpread1,
);

@@ -434,12 +483,12 @@ } // (J) Also collect conflicts between any fragment names by the first and

for (const fragmentName1 of fragmentNames1) {
for (const fragmentName2 of fragmentNames2) {
for (const [fragmentSpread1] of Object.values(fragmentSpreadsByName1)) {
for (const [fragmentSpread2] of Object.values(fragmentSpreadsByName2)) {
collectConflictsBetweenFragments(
context,
conflicts,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,
areMutuallyExclusive,
fragmentName1,
fragmentName2,
fragmentSpread1,
fragmentSpread2,
);

@@ -455,3 +504,3 @@ }

conflicts,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,

@@ -473,3 +522,3 @@ fieldMap,

context,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,

@@ -498,3 +547,3 @@ false, // within one collection is never mutually exclusive

conflicts,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,

@@ -518,3 +567,3 @@ parentFieldsAreMutuallyExclusive,

context,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,

@@ -539,3 +588,3 @@ parentFieldsAreMutuallyExclusive,

context,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,

@@ -609,3 +658,3 @@ parentFieldsAreMutuallyExclusive,

context,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
comparedFragmentPairs,

@@ -693,9 +742,9 @@ areMutuallyExclusive,

function getFieldsAndFragmentNames(
function getFieldsAndFragmentSpreads(
context,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
parentType,
selectionSet,
) {
const cached = cachedFieldsAndFragmentNames.get(selectionSet);
const cached = cachedFieldsAndFragmentSpreads.get(selectionSet);

@@ -707,3 +756,3 @@ if (cached) {

const nodeAndDefs = Object.create(null);
const fragmentNames = Object.create(null);
const fragmentSpreadsByName = Object.create(null);

@@ -715,7 +764,7 @@ _collectFieldsAndFragmentNames(

nodeAndDefs,
fragmentNames,
fragmentSpreadsByName,
);
const result = [nodeAndDefs, Object.keys(fragmentNames)];
cachedFieldsAndFragmentNames.set(selectionSet, result);
const result = [nodeAndDefs, fragmentSpreadsByName];
cachedFieldsAndFragmentSpreads.set(selectionSet, result);
return result;

@@ -725,10 +774,27 @@ } // Given a reference to a fragment, return the represented collection of fields

function getReferencedFieldsAndFragmentNames(
function getReferencedFieldsAndFragmentSpreads(
context,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
fragment,
fragmentSpread,
) {
// Short-circuit building a type from the node if possible.
const cached = cachedFieldsAndFragmentNames.get(fragment.selectionSet);
const args = fragmentSpread.arguments;
const fragmentSelectionSet = (0, _visitor.visit)(fragment.selectionSet, {
Variable: (node) => {
const name = node.name.value;
const argNode =
args === null || args === void 0
? void 0
: args.find((arg) => arg.name.value === name);
if (argNode) {
return argNode.value;
}
return node;
},
}); // Short-circuit building a type from the node if possible.
const cached = cachedFieldsAndFragmentSpreads.get(fragmentSelectionSet);
if (cached) {

@@ -742,7 +808,7 @@ return cached;

);
return getFieldsAndFragmentNames(
return getFieldsAndFragmentSpreads(
context,
cachedFieldsAndFragmentNames,
cachedFieldsAndFragmentSpreads,
fragmentType,
fragment.selectionSet,
fragmentSelectionSet,
);

@@ -756,3 +822,3 @@ }

nodeAndDefs,
fragmentNames,
fragmentSpreadsByName,
) {

@@ -784,5 +850,13 @@ for (const selection of selectionSet.selections) {

case _kinds.Kind.FRAGMENT_SPREAD:
fragmentNames[selection.name.value] = true;
case _kinds.Kind.FRAGMENT_SPREAD: {
const existing = fragmentSpreadsByName[selection.name.value];
if (existing) {
existing.push(selection);
} else {
fragmentSpreadsByName[selection.name.value] = [selection];
}
break;
}

@@ -800,3 +874,3 @@ case _kinds.Kind.INLINE_FRAGMENT: {

nodeAndDefs,
fragmentNames,
fragmentSpreadsByName,
);

@@ -803,0 +877,0 @@

@@ -71,2 +71,47 @@ 'use strict';

},
FragmentSpread: {
// Validate on leave to allow for directive errors to appear first.
leave(spreadNode) {
var _spreadNode$arguments;
const fragmentDef = context.getFragment(spreadNode.name.value);
if (!fragmentDef) {
return false;
}
const providedArgs = new Set( // FIXME: https://github.com/graphql/graphql-js/issues/2203
/* c8 ignore next */
(_spreadNode$arguments = spreadNode.arguments) === null ||
_spreadNode$arguments === void 0
? void 0
: _spreadNode$arguments.map((arg) => arg.name.value),
); // FIXME: https://github.com/graphql/graphql-js/issues/2203
/* c8 ignore next */
for (const varDef of (_fragmentDef$variable =
fragmentDef.variableDefinitions) !== null &&
_fragmentDef$variable !== void 0
? _fragmentDef$variable
: []) {
var _fragmentDef$variable;
if (
!providedArgs.has(varDef.variable.name.value) &&
isRequiredArgumentNode(varDef)
) {
const argTypeStr = (0, _inspect.inspect)(varDef.type);
context.reportError(
new _GraphQLError.GraphQLError(
`Fragment "${spreadNode.name.value}" argument "${varDef.variable.name.value}" of type "${argTypeStr}" is required, but it was not provided.`,
{
nodes: [spreadNode, varDef],
},
),
);
}
}
},
},
};

@@ -73,0 +118,0 @@ }

@@ -59,3 +59,3 @@ 'use strict';

{
nodes: extraFieldSelections,
nodes: extraFieldSelections.map((entry) => entry.node),
},

@@ -68,3 +68,3 @@ ),

const field = fieldNodes[0];
const fieldName = field.name.value;
const fieldName = field.node.name.value;

@@ -78,3 +78,3 @@ if (fieldName.startsWith('__')) {

{
nodes: fieldNodes,
nodes: fieldNodes.map((entry) => entry.node),
},

@@ -81,0 +81,0 @@ ),

@@ -18,2 +18,4 @@ 'use strict';

var _kinds = require('../../language/kinds.js');
var _printer = require('../../language/printer.js');

@@ -32,3 +34,14 @@

function ValuesOfCorrectTypeRule(context) {
let variableDefinitions = {};
return {
OperationDefinition: {
enter() {
variableDefinitions = {};
},
},
VariableDefinition(definition) {
variableDefinitions[definition.variable.name.value] = definition;
},
ListValue(node) {

@@ -75,2 +88,12 @@ // Note: TypeInfo will traverse into a list's item type, so look to the

}
if (type.isOneOf) {
validateOneOfInputObject(
context,
node,
type,
fieldNodeMap,
variableDefinitions,
);
}
},

@@ -196,1 +219,66 @@

}
function validateOneOfInputObject(
context,
node,
type,
fieldNodeMap,
variableDefinitions,
) {
var _fieldNodeMap$keys$;
const keys = Object.keys(fieldNodeMap);
const isNotExactlyOneField = keys.length !== 1;
if (isNotExactlyOneField) {
context.reportError(
new _GraphQLError.GraphQLError(
`OneOf Input Object "${type.name}" must specify exactly one key.`,
{
nodes: [node],
},
),
);
return;
}
const value =
(_fieldNodeMap$keys$ = fieldNodeMap[keys[0]]) === null ||
_fieldNodeMap$keys$ === void 0
? void 0
: _fieldNodeMap$keys$.value;
const isNullLiteral = !value || value.kind === _kinds.Kind.NULL;
const isVariable =
(value === null || value === void 0 ? void 0 : value.kind) ===
_kinds.Kind.VARIABLE;
if (isNullLiteral) {
context.reportError(
new _GraphQLError.GraphQLError(
`Field "${type.name}.${keys[0]}" must be non-null.`,
{
nodes: [node],
},
),
);
return;
}
if (isVariable) {
const variableName = value.name.value;
const definition = variableDefinitions[variableName];
const isNullableVariable =
definition.type.kind !== _kinds.Kind.NON_NULL_TYPE;
if (isNullableVariable) {
context.reportError(
new _GraphQLError.GraphQLError(
`Variable "${variableName}" must be non-nullable to be used for OneOf Input Object "${type.name}".`,
{
nodes: [node],
},
),
);
}
}
}

@@ -38,5 +38,8 @@ 'use strict';

for (const { node, type, defaultValue } of usages) {
for (const { node, type, defaultValue, fragmentVarDef } of usages) {
const varName = node.name.value;
const varDef = varDefMap[varName];
const varDef =
fragmentVarDef !== null && fragmentVarDef !== void 0
? fragmentVarDef
: varDefMap[varName];

@@ -43,0 +46,0 @@ if (varDef && type) {

@@ -0,3 +1,9 @@

import { MaxIntrospectionDepthRule } from './rules/MaxIntrospectionDepthRule';
import type { SDLValidationRule, ValidationRule } from './ValidationContext';
/**
* Technically these aren't part of the spec but they are strongly encouraged
* validation rules.
*/
export declare const recommendedRules: readonly typeof MaxIntrospectionDepthRule[];
/**
* This set includes all validation rules defined by the GraphQL spec.

@@ -4,0 +10,0 @@ *

@@ -6,3 +6,6 @@ 'use strict';

});
exports.specifiedSDLRules = exports.specifiedRules = void 0;
exports.specifiedSDLRules =
exports.specifiedRules =
exports.recommendedRules =
void 0;

@@ -27,2 +30,4 @@ var _ExecutableDefinitionsRule = require('./rules/ExecutableDefinitionsRule.js');

var _MaxIntrospectionDepthRule = require('./rules/MaxIntrospectionDepthRule.js');
var _NoFragmentCyclesRule = require('./rules/NoFragmentCyclesRule.js');

@@ -34,2 +39,4 @@

var _NoUnusedFragmentVariablesRule = require('./rules/NoUnusedFragmentVariablesRule.js');
var _NoUnusedVariablesRule = require('./rules/NoUnusedVariablesRule.js');

@@ -88,5 +95,7 @@

// SDL-specific validation rules
// TODO: Spec Section
// Spec Section: "Fragments must not form cycles"
// Spec Section: "All Variable Used Defined"
// Spec Section: "Fragments must be used"
// Spec Section: "All Fragment Variables Used"
// Spec Section: "All Variables Used"

@@ -109,2 +118,9 @@ // Spec Section: "Field Selection Merging"

/**
* Technically these aren't part of the spec but they are strongly encouraged
* validation rules.
*/
const recommendedRules = Object.freeze([
_MaxIntrospectionDepthRule.MaxIntrospectionDepthRule,
]);
/**
* This set includes all validation rules defined by the GraphQL spec.

@@ -115,2 +131,4 @@ *

*/
exports.recommendedRules = recommendedRules;
const specifiedRules = Object.freeze([

@@ -135,2 +153,3 @@ _ExecutableDefinitionsRule.ExecutableDefinitionsRule,

_KnownDirectivesRule.KnownDirectivesRule,
_NoUnusedFragmentVariablesRule.NoUnusedFragmentVariablesRule,
_UniqueDirectivesPerLocationRule.UniqueDirectivesPerLocationRule,

@@ -144,2 +163,3 @@ _KnownArgumentNamesRule.KnownArgumentNamesRule,

_UniqueInputFieldNamesRule.UniqueInputFieldNamesRule,
...recommendedRules,
]);

@@ -146,0 +166,0 @@ /**

@@ -9,2 +9,3 @@ import type { Maybe } from '../jsutils/Maybe';

SelectionSetNode,
VariableDefinitionNode,
VariableNode,

@@ -23,3 +24,3 @@ } from '../language/ast';

import type { GraphQLSchema } from '../type/schema';
import { TypeInfo } from '../utilities/TypeInfo';
import type { TypeInfo } from '../utilities/TypeInfo';
declare type NodeWithSelectionSet =

@@ -32,2 +33,3 @@ | OperationDefinitionNode

readonly defaultValue: Maybe<unknown>;
readonly fragmentVarDef: Maybe<VariableDefinitionNode>;
}

@@ -88,2 +90,5 @@ /**

): ReadonlyArray<VariableUsage>;
getOperationVariableUsages(
operation: OperationDefinitionNode,
): ReadonlyArray<VariableUsage>;
getType(): Maybe<GraphQLOutputType>;

@@ -90,0 +95,0 @@ getParentType(): Maybe<GraphQLCompositeType>;

@@ -160,3 +160,7 @@ 'use strict';

const newUsages = [];
const typeInfo = new _TypeInfo.TypeInfo(this._schema);
const typeInfo = this._typeInfo;
const fragmentVariableDefinitions =
node.kind === _kinds.Kind.FRAGMENT_DEFINITION
? node.variableDefinitions
: undefined;
(0, _visitor.visit)(

@@ -168,2 +172,10 @@ node,

Variable(variable) {
const fragmentVarDef =
fragmentVariableDefinitions === null ||
fragmentVariableDefinitions === void 0
? void 0
: fragmentVariableDefinitions.find(
(varDef) =>
varDef.variable.name.value === variable.name.value,
);
newUsages.push({

@@ -173,2 +185,3 @@ node: variable,

defaultValue: typeInfo.getDefaultValue(),
fragmentVarDef,
});

@@ -202,2 +215,18 @@ },

getOperationVariableUsages(operation) {
let usages = this._recursiveVariableUsages.get(operation);
if (!usages) {
usages = this.getVariableUsages(operation);
for (const frag of this.getRecursivelyReferencedFragments(operation)) {
usages = usages.concat(this.getVariableUsages(frag));
}
this._recursiveVariableUsages.set(operation, usages);
}
return usages.filter(({ fragmentVarDef }) => !fragmentVarDef);
}
getType() {

@@ -204,0 +233,0 @@ return this._typeInfo.getType();

@@ -13,3 +13,3 @@ 'use strict';

*/
const version = '16.8.2';
const version = '16.9.0';
/**

@@ -22,6 +22,6 @@ * An object containing the components of the GraphQL.js version string

major: 16,
minor: 8,
patch: 2,
minor: 9,
patch: 0,
preReleaseTag: null,
});
exports.versionInfo = versionInfo;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc