New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

graphql

Package Overview
Dependencies
Maintainers
7
Versions
271
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 17.0.0-alpha.1.canary.pr.3601.9a812ce71ad05c9dc089b40129f8295ca733e108 to 17.0.0-alpha.1.canary.pr.3651.57364d3f9da445b2bba520d3b886e07dc2af10e2

1

execution/collectFields.js

@@ -72,2 +72,3 @@ import { AccumulatorMap } from '../jsutils/AccumulatorMap.js';

}
// eslint-disable-next-line max-params
function collectFieldsImpl(

@@ -74,0 +75,0 @@ schema,

82

execution/execute.d.ts

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

/**
* Essential assertions before executing to provide developer feedback for
* improper use of the GraphQL library.
*
* @internal
*/
export declare function assertValidExecutionArguments(
schema: GraphQLSchema,
document: DocumentNode,
rawVariableValues: Maybe<{
readonly [variable: string]: unknown;
}>,
): void;
/**
* Constructs a ExecutionContext object from the arguments passed to

@@ -135,2 +122,3 @@ * execute, which we will pass throughout the other execution methods.

*
* TODO: consider no longer exporting this function
* @internal

@@ -142,2 +130,3 @@ */

/**
* TODO: consider no longer exporting this function
* @internal

@@ -174,16 +163,57 @@ */

/**
* 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.
* Implements the "Subscribe" algorithm described in the GraphQL specification.
*
* @internal
* Returns a Promise which 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.
*
* Accepts either an object with named arguments, or individual arguments.
*/
export declare function getFieldDef(
schema: GraphQLSchema,
parentType: GraphQLObjectType,
fieldNode: FieldNode,
): Maybe<GraphQLField<unknown, unknown>>;
export declare function subscribe(
args: ExecutionArgs,
): PromiseOrValue<
AsyncGenerator<ExecutionResult, void, void> | ExecutionResult
>;
/**
* Implements the "CreateSourceEventStream" algorithm described in the
* GraphQL specification, resolving the subscription source event stream.
*
* Returns a Promise which resolves to either an AsyncIterable (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 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.
*/
export declare function createSourceEventStream(
args: ExecutionArgs,
): PromiseOrValue<AsyncIterable<unknown> | ExecutionResult>;

@@ -1,4 +0,4 @@

import { devAssert } from '../jsutils/devAssert.js';
import { inspect } from '../jsutils/inspect.js';
import { invariant } from '../jsutils/invariant.js';
import { isAsyncIterable } from '../jsutils/isAsyncIterable.js';
import { isIterableObject } from '../jsutils/isIterableObject.js';

@@ -22,7 +22,2 @@ import { isObjectLike } from '../jsutils/isObjectLike.js';

} from '../type/definition.js';
import {
SchemaMetaFieldDef,
TypeMetaFieldDef,
TypeNameMetaFieldDef,
} from '../type/introspection.js';
import { assertValidSchema } from '../type/validate.js';

@@ -33,3 +28,7 @@ import {

} from './collectFields.js';
import { mapAsyncIterator } from './mapAsyncIterator.js';
import { getArgumentValues, getVariableValues } from './values.js';
/* eslint-disable max-params */
// This file contains a lot of such errors but we plan to refactor it anyway
// so just disable it for entire file.
/**

@@ -60,5 +59,2 @@ * A memoized collection of relevant subfields with regard to the return

export function execute(args) {
const { schema, document, variableValues, rootValue } = args;
// If arguments are missing or incorrect, throw an error.
assertValidExecutionArguments(schema, document, variableValues);
// If a valid execution context cannot be created due to incorrect arguments,

@@ -71,2 +67,5 @@ // a "Response" with only errors is returned.

}
return executeImpl(exeContext);
}
function executeImpl(exeContext) {
// Return a Promise that will eventually resolve to the data described by

@@ -84,4 +83,3 @@ // The "Response" section of the GraphQL specification.

try {
const { operation } = exeContext;
const result = executeOperation(exeContext, operation, rootValue);
const result = executeOperation(exeContext);
if (isPromise(result)) {

@@ -123,24 +121,2 @@ return result.then(

/**
* Essential assertions before executing to provide developer feedback for
* improper use of the GraphQL library.
*
* @internal
*/
export function assertValidExecutionArguments(
schema,
document,
rawVariableValues,
) {
document != null || devAssert(false, 'Must provide document.');
// If the schema used for execution is invalid, throw an error.
assertValidSchema(schema);
// Variables, if provided, must be an object.
rawVariableValues == null ||
isObjectLike(rawVariableValues) ||
devAssert(
false,
'Variables must be provided as an Object where each property is a variable value. Perhaps look to see if an unparsed JSON string was provided.',
);
}
/**
* Constructs a ExecutionContext object from the arguments passed to

@@ -151,2 +127,3 @@ * execute, which we will pass throughout the other execution methods.

*
* TODO: consider no longer exporting this function
* @internal

@@ -166,2 +143,4 @@ */

} = args;
// If the schema used for execution is invalid, throw an error.
assertValidSchema(schema);
let operation;

@@ -223,7 +202,16 @@ const fragments = Object.create(null);

}
function buildPerEventExecutionContext(exeContext, payload) {
return {
...exeContext,
rootValue: payload,
errors: [],
};
}
/**
* Implements the "Executing operations" section of the spec.
*/
function executeOperation(exeContext, operation, rootValue) {
const rootType = exeContext.schema.getRootType(operation.operation);
function executeOperation(exeContext) {
const { operation, schema, fragments, variableValues, rootValue } =
exeContext;
const rootType = schema.getRootType(operation.operation);
if (rootType == null) {

@@ -236,5 +224,5 @@ throw new GraphQLError(

const rootFields = collectFields(
exeContext.schema,
exeContext.fragments,
exeContext.variableValues,
schema,
fragments,
variableValues,
rootType,

@@ -305,17 +293,27 @@ operation.selectionSet,

let containsPromise = false;
for (const [responseName, fieldNodes] of fields.entries()) {
const fieldPath = addPath(path, responseName, parentType.name);
const result = executeField(
exeContext,
parentType,
sourceValue,
fieldNodes,
fieldPath,
);
if (result !== undefined) {
results[responseName] = result;
if (isPromise(result)) {
containsPromise = true;
try {
for (const [responseName, fieldNodes] of fields.entries()) {
const fieldPath = addPath(path, responseName, parentType.name);
const result = executeField(
exeContext,
parentType,
sourceValue,
fieldNodes,
fieldPath,
);
if (result !== undefined) {
results[responseName] = result;
if (isPromise(result)) {
containsPromise = true;
}
}
}
} catch (error) {
if (containsPromise) {
// Ensure that any promises returned by other fields are handled, as they may also reject.
return promiseForObject(results).finally(() => {
throw error;
});
}
throw error;
}

@@ -338,3 +336,4 @@ // If there are no promises, we can just return the object

function executeField(exeContext, parentType, source, fieldNodes, path) {
const fieldDef = getFieldDef(exeContext.schema, parentType, fieldNodes[0]);
const fieldName = fieldNodes[0].name.value;
const fieldDef = exeContext.schema.getField(parentType, fieldName);
if (!fieldDef) {

@@ -397,2 +396,3 @@ return;

/**
* TODO: consider no longer exporting this function
* @internal

@@ -529,2 +529,59 @@ */

/**
* Complete a async iterator value by completing the result and calling
* recursively until all the results are completed.
*/
async function completeAsyncIteratorValue(
exeContext,
itemType,
fieldNodes,
info,
path,
iterator,
) {
let containsPromise = false;
const completedResults = [];
let index = 0;
// eslint-disable-next-line no-constant-condition
while (true) {
const fieldPath = addPath(path, index, undefined);
try {
// eslint-disable-next-line no-await-in-loop
const { value, done } = await iterator.next();
if (done) {
break;
}
try {
// TODO can the error checking logic be consolidated with completeListValue?
const completedItem = completeValue(
exeContext,
itemType,
fieldNodes,
info,
fieldPath,
value,
);
if (isPromise(completedItem)) {
containsPromise = true;
}
completedResults.push(completedItem);
} catch (rawError) {
completedResults.push(null);
const error = locatedError(
rawError,
fieldNodes,
pathToArray(fieldPath),
);
handleFieldError(error, itemType, exeContext);
}
} catch (rawError) {
completedResults.push(null);
const error = locatedError(rawError, fieldNodes, pathToArray(fieldPath));
handleFieldError(error, itemType, exeContext);
break;
}
index += 1;
}
return containsPromise ? Promise.all(completedResults) : completedResults;
}
/**
* Complete a list value by completing each item in the list with the

@@ -541,2 +598,14 @@ * inner type

) {
const itemType = returnType.ofType;
if (isAsyncIterable(result)) {
const iterator = result[Symbol.asyncIterator]();
return completeAsyncIteratorValue(
exeContext,
itemType,
fieldNodes,
info,
path,
iterator,
);
}
if (!isIterableObject(result)) {

@@ -549,3 +618,2 @@ throw new GraphQLError(

// where the list contains no Promises by avoiding creating another Promise.
const itemType = returnType.ofType;
let containsPromise = false;

@@ -822,28 +890,171 @@ const completedResults = Array.from(result, (item, index) => {

/**
* 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.
* Implements the "Subscribe" algorithm described in the GraphQL specification.
*
* @internal
* Returns a Promise which 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.
*
* Accepts either an object with named arguments, or individual arguments.
*/
export function getFieldDef(schema, parentType, fieldNode) {
const fieldName = fieldNode.name.value;
if (
fieldName === SchemaMetaFieldDef.name &&
schema.getQueryType() === parentType
) {
return SchemaMetaFieldDef;
} else if (
fieldName === TypeMetaFieldDef.name &&
schema.getQueryType() === parentType
) {
return TypeMetaFieldDef;
} else if (fieldName === TypeNameMetaFieldDef.name) {
return TypeNameMetaFieldDef;
export function subscribe(args) {
// If a valid execution context cannot be created due to incorrect arguments,
// a "Response" with only errors is returned.
const exeContext = buildExecutionContext(args);
// Return early errors if execution context failed.
if (!('schema' in exeContext)) {
return { errors: exeContext };
}
return parentType.getFields()[fieldName];
const resultOrStream = createSourceEventStreamImpl(exeContext);
if (isPromise(resultOrStream)) {
return resultOrStream.then((resolvedResultOrStream) =>
mapSourceToResponse(exeContext, resolvedResultOrStream),
);
}
return mapSourceToResponse(exeContext, resultOrStream);
}
function mapSourceToResponse(exeContext, resultOrStream) {
if (!isAsyncIterable(resultOrStream)) {
return resultOrStream;
}
// For each payload yielded from a subscription, map it over the normal
// GraphQL `execute` function, with `payload` as the rootValue.
// This implements the "MapSourceToResponseEvent" algorithm described in
// the GraphQL specification. The `execute` function provides the
// "ExecuteSubscriptionEvent" algorithm, as it is nearly identical to the
// "ExecuteQuery" algorithm, for which `execute` is also used.
return mapAsyncIterator(resultOrStream, (payload) =>
executeImpl(buildPerEventExecutionContext(exeContext, payload)),
);
}
/**
* Implements the "CreateSourceEventStream" algorithm described in the
* GraphQL specification, resolving the subscription source event stream.
*
* Returns a Promise which resolves to either an AsyncIterable (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 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.
*/
export function createSourceEventStream(args) {
// If a valid execution context cannot be created due to incorrect arguments,
// a "Response" with only errors is returned.
const exeContext = buildExecutionContext(args);
// Return early errors if execution context failed.
if (!('schema' in exeContext)) {
return { errors: exeContext };
}
return createSourceEventStreamImpl(exeContext);
}
function createSourceEventStreamImpl(exeContext) {
try {
const eventStream = executeSubscription(exeContext);
if (isPromise(eventStream)) {
return eventStream.then(undefined, (error) => ({ errors: [error] }));
}
return eventStream;
} catch (error) {
return { errors: [error] };
}
}
function executeSubscription(exeContext) {
const { schema, fragments, operation, variableValues, rootValue } =
exeContext;
const rootType = schema.getSubscriptionType();
if (rootType == null) {
throw new GraphQLError(
'Schema is not configured to execute subscription operation.',
{ nodes: operation },
);
}
const rootFields = collectFields(
schema,
fragments,
variableValues,
rootType,
operation.selectionSet,
);
const [responseName, fieldNodes] = [...rootFields.entries()][0];
const fieldName = fieldNodes[0].name.value;
const fieldDef = schema.getField(rootType, fieldName);
if (!fieldDef) {
throw new GraphQLError(
`The subscription field "${fieldName}" is not defined.`,
{ nodes: fieldNodes },
);
}
const path = addPath(undefined, responseName, rootType.name);
const info = buildResolveInfo(
exeContext,
fieldDef,
fieldNodes,
rootType,
path,
);
try {
// Implements the "ResolveFieldEventStream" algorithm from GraphQL specification.
// It differs from "ResolveFieldValue" due to providing a different `resolveFn`.
// Build a JS object of arguments from the field.arguments AST, using the
// variables scope to fulfill any variable references.
const args = getArgumentValues(fieldDef, fieldNodes[0], variableValues);
// The resolve function's optional third argument is a context value that
// is provided to every resolve function within an execution. It is commonly
// used to represent an authenticated user, or request-specific caches.
const contextValue = exeContext.contextValue;
// Call the `subscribe()` resolver or the default resolver to produce an
// AsyncIterable yielding raw payloads.
const resolveFn = fieldDef.subscribe ?? exeContext.subscribeFieldResolver;
const result = resolveFn(rootValue, args, contextValue, info);
if (isPromise(result)) {
return result.then(assertEventStream).then(undefined, (error) => {
throw locatedError(error, fieldNodes, pathToArray(path));
});
}
return assertEventStream(result);
} catch (error) {
throw locatedError(error, fieldNodes, pathToArray(path));
}
}
function assertEventStream(result) {
if (result instanceof Error) {
throw result;
}
// Assert field returned an event stream, otherwise yield an error.
if (!isAsyncIterable(result)) {
throw new GraphQLError(
'Subscription field must return Async Iterable. ' +
`Received: ${inspect(result)}.`,
);
}
return result;
}
export { pathToArray as responsePathAsArray } from '../jsutils/Path';
export {
createSourceEventStream,
execute,

@@ -7,2 +8,3 @@ executeSync,

defaultTypeResolver,
subscribe,
} from './execute';

@@ -14,3 +16,2 @@ export type {

} from './execute';
export { subscribe, createSourceEventStream } from './subscribe';
export {

@@ -17,0 +18,0 @@ getArgumentValues,

export { pathToArray as responsePathAsArray } from '../jsutils/Path.js';
export {
createSourceEventStream,
execute,

@@ -7,4 +8,4 @@ executeSync,

defaultTypeResolver,
subscribe,
} from './execute.js';
export { subscribe, createSourceEventStream } from './subscribe.js';
export {

@@ -11,0 +12,0 @@ getArgumentValues,

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

isSelectionNode,
isNullabilityAssertionNode,
isValueNode,

@@ -232,2 +233,6 @@ isConstValueNode,

ArgumentNode,
NullabilityAssertionNode,
NonNullAssertionNode,
ErrorBoundaryNode,
ListNullabilityOperatorNode,
ConstArgumentNode,

@@ -234,0 +239,0 @@ FragmentSpreadNode,

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

isSelectionNode,
isNullabilityAssertionNode,
isValueNode,

@@ -168,0 +169,0 @@ isConstValueNode,

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

| EnumTypeExtensionNode
| InputObjectTypeExtensionNode;
| InputObjectTypeExtensionNode
| NonNullAssertionNode
| ErrorBoundaryNode
| ListNullabilityOperatorNode;
/**

@@ -216,5 +219,25 @@ * Utility type listing all nodes indexed by their kind.

readonly arguments?: ReadonlyArray<ArgumentNode>;
readonly nullabilityAssertion?: NullabilityAssertionNode;
readonly directives?: ReadonlyArray<DirectiveNode>;
readonly selectionSet?: SelectionSetNode;
}
export declare type NullabilityAssertionNode =
| NonNullAssertionNode
| ErrorBoundaryNode
| ListNullabilityOperatorNode;
export interface ListNullabilityOperatorNode {
readonly kind: Kind.LIST_NULLABILITY_OPERATOR;
readonly loc?: Location;
readonly nullabilityAssertion?: NullabilityAssertionNode;
}
export interface NonNullAssertionNode {
readonly kind: Kind.NON_NULL_ASSERTION;
readonly loc?: Location;
readonly nullabilityAssertion?: ListNullabilityOperatorNode;
}
export interface ErrorBoundaryNode {
readonly kind: Kind.ERROR_BOUNDARY;
readonly loc?: Location;
readonly nullabilityAssertion?: ListNullabilityOperatorNode;
}
export interface ArgumentNode {

@@ -221,0 +244,0 @@ readonly kind: Kind.ARGUMENT;

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

export class Token {
// eslint-disable-next-line max-params
constructor(kind, start, end, line, column, value) {

@@ -64,4 +65,18 @@ this.kind = kind;

SelectionSet: ['selections'],
Field: ['alias', 'name', 'arguments', 'directives', 'selectionSet'],
Field: [
'alias',
'name',
'arguments',
'directives',
'selectionSet',
// Note: Client Controlled Nullability is experimental and may be changed
// or removed in the future.
'nullabilityAssertion',
],
Argument: ['name', 'value'],
// Note: Client Controlled Nullability is experimental and may be changed
// or removed in the future.
ListNullabilityOperator: ['nullabilityAssertion'],
NonNullAssertion: ['nullabilityAssertion'],
ErrorBoundary: ['nullabilityAssertion'],
FragmentSpread: ['name', 'directives'],

@@ -68,0 +83,0 @@ InlineFragment: ['typeCondition', 'directives', 'selectionSet'],

@@ -27,2 +27,6 @@ export { Source } from './source';

FieldNode,
NullabilityAssertionNode,
NonNullAssertionNode,
ErrorBoundaryNode,
ListNullabilityOperatorNode,
ArgumentNode,

@@ -81,2 +85,3 @@ ConstArgumentNode,

isSelectionNode,
isNullabilityAssertionNode,
isValueNode,

@@ -83,0 +88,0 @@ isConstValueNode,

@@ -20,2 +20,3 @@ export { Source } from './source.js';

isSelectionNode,
isNullabilityAssertionNode,
isValueNode,

@@ -22,0 +23,0 @@ isConstValueNode,

@@ -14,2 +14,6 @@ /**

ARGUMENT = 'Argument',
/** Nullability Modifiers */
LIST_NULLABILITY_OPERATOR = 'ListNullabilityOperator',
NON_NULL_ASSERTION = 'NonNullAssertion',
ERROR_BOUNDARY = 'ErrorBoundary',
/** Fragments */

@@ -16,0 +20,0 @@ FRAGMENT_SPREAD = 'FragmentSpread',

@@ -15,2 +15,6 @@ /**

Kind['ARGUMENT'] = 'Argument';
/** Nullability Modifiers */
Kind['LIST_NULLABILITY_OPERATOR'] = 'ListNullabilityOperator';
Kind['NON_NULL_ASSERTION'] = 'NonNullAssertion';
Kind['ERROR_BOUNDARY'] = 'ErrorBoundary';
/** Fragments */

@@ -17,0 +21,0 @@ Kind['FRAGMENT_SPREAD'] = 'FragmentSpread';

@@ -64,2 +64,3 @@ import { syntaxError } from '../error/syntaxError.js';

kind === TokenKind.BANG ||
kind === TokenKind.QUESTION_MARK ||
kind === TokenKind.DOLLAR ||

@@ -238,2 +239,9 @@ kind === TokenKind.AMP ||

return createToken(lexer, TokenKind.BRACE_R, position, position + 1);
case 0x003f: // ?
return createToken(
lexer,
TokenKind.QUESTION_MARK,
position,
position + 1,
);
// StringValue

@@ -240,0 +248,0 @@ case 0x0022: // "

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

NameNode,
NullabilityAssertionNode,
ObjectFieldNode,

@@ -84,2 +85,24 @@ ObjectTypeDefinitionNode,

allowLegacyFragmentVariables?: boolean;
/**
* EXPERIMENTAL:
*
* If enabled, the parser will understand and parse Client Controlled Nullability
* Designators contained in Fields. They'll be represented in the
* `nullabilityAssertion` field of the FieldNode.
*
* The syntax looks like the following:
*
* ```graphql
* {
* nullableField!
* nonNullableField?
* nonNullableSelectionSet? {
* childField!
* }
* }
* ```
* Note: this feature is experimental and may change or be removed in the
* future.
*/
experimentalClientControlledNullability?: boolean;
}

@@ -218,2 +241,3 @@ /**

parseField(): FieldNode;
parseNullabilityAssertion(): NullabilityAssertionNode | undefined;
/**

@@ -220,0 +244,0 @@ * Arguments[Const] : ( Argument[?Const]+ )

@@ -302,2 +302,5 @@ import { syntaxError } from '../error/syntaxError.js';

arguments: this.parseArguments(false),
// Experimental support for Client Controlled Nullability changes
// the grammar of Field:
nullabilityAssertion: this.parseNullabilityAssertion(),
directives: this.parseDirectives(false),

@@ -309,2 +312,32 @@ selectionSet: this.peek(TokenKind.BRACE_L)

}
// TODO: add grammar comment after it finalizes
parseNullabilityAssertion() {
// Note: Client Controlled Nullability is experimental and may be changed or
// removed in the future.
if (this._options?.experimentalClientControlledNullability !== true) {
return undefined;
}
const start = this._lexer.token;
let nullabilityAssertion;
if (this.expectOptionalToken(TokenKind.BRACKET_L)) {
const innerModifier = this.parseNullabilityAssertion();
this.expectToken(TokenKind.BRACKET_R);
nullabilityAssertion = this.node(start, {
kind: Kind.LIST_NULLABILITY_OPERATOR,
nullabilityAssertion: innerModifier,
});
}
if (this.expectOptionalToken(TokenKind.BANG)) {
nullabilityAssertion = this.node(start, {
kind: Kind.NON_NULL_ASSERTION,
nullabilityAssertion,
});
} else if (this.expectOptionalToken(TokenKind.QUESTION_MARK)) {
nullabilityAssertion = this.node(start, {
kind: Kind.ERROR_BOUNDARY,
nullabilityAssertion,
});
}
return nullabilityAssertion;
}
parseArguments(isConst) {

@@ -311,0 +344,0 @@ const item = isConst ? this.parseConstArgument : this.parseArgument;

@@ -6,2 +6,3 @@ import type {

ExecutableDefinitionNode,
NullabilityAssertionNode,
SelectionNode,

@@ -20,2 +21,5 @@ TypeDefinitionNode,

export declare function isSelectionNode(node: ASTNode): node is SelectionNode;
export declare function isNullabilityAssertionNode(
node: ASTNode,
): node is NullabilityAssertionNode;
export declare function isValueNode(node: ASTNode): node is ValueNode;

@@ -22,0 +26,0 @@ export declare function isConstValueNode(node: ASTNode): node is ConstValueNode;

@@ -22,2 +22,9 @@ import { Kind } from './kinds.js';

}
export function isNullabilityAssertionNode(node) {
return (
node.kind === Kind.LIST_NULLABILITY_OPERATOR ||
node.kind === Kind.NON_NULL_ASSERTION ||
node.kind === Kind.ERROR_BOUNDARY
);
}
export function isValueNode(node) {

@@ -24,0 +31,0 @@ return (

@@ -45,4 +45,11 @@ import { printBlockString } from './blockString.js';

Field: {
leave({ alias, name, arguments: args, directives, selectionSet }) {
const prefix = wrap('', alias, ': ') + name;
leave({
alias,
name,
arguments: args,
nullabilityAssertion,
directives,
selectionSet,
}) {
const prefix = join([wrap('', alias, ': '), name], '');
let argsLine = prefix + wrap('(', join(args, ', '), ')');

@@ -52,6 +59,29 @@ if (argsLine.length > MAX_LINE_LENGTH) {

}
return join([argsLine, join(directives, ' '), selectionSet], ' ');
return join([
argsLine,
// Note: Client Controlled Nullability is experimental and may be
// changed or removed in the future.
nullabilityAssertion,
wrap(' ', join(directives, ' ')),
wrap(' ', selectionSet),
]);
},
},
Argument: { leave: ({ name, value }) => name + ': ' + value },
// Nullability Modifiers
ListNullabilityOperator: {
leave({ nullabilityAssertion }) {
return join(['[', nullabilityAssertion, ']']);
},
},
NonNullAssertion: {
leave({ nullabilityAssertion }) {
return join([nullabilityAssertion, '!']);
},
},
ErrorBoundary: {
leave({ nullabilityAssertion }) {
return join([nullabilityAssertion, '?']);
},
},
// Fragments

@@ -58,0 +88,0 @@ FragmentSpread: {

import { devAssert } from '../jsutils/devAssert.js';
import { inspect } from '../jsutils/inspect.js';
import { instanceOf } from '../jsutils/instanceOf.js';

@@ -17,4 +16,2 @@ /**

) {
typeof body === 'string' ||
devAssert(false, `Body must be a string. Received: ${inspect(body)}.`);
this.body = body;

@@ -21,0 +18,0 @@ this.name = name;

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

BANG = '!',
QUESTION_MARK = '?',
DOLLAR = '$',

@@ -11,0 +12,0 @@ AMP = '&',

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

TokenKind['BANG'] = '!';
TokenKind['QUESTION_MARK'] = '?';
TokenKind['DOLLAR'] = '$';

@@ -12,0 +13,0 @@ TokenKind['AMP'] = '&';

{
"name": "graphql",
"version": "17.0.0-alpha.1.canary.pr.3601.9a812ce71ad05c9dc089b40129f8295ca733e108",
"version": "17.0.0-alpha.1.canary.pr.3651.57364d3f9da445b2bba520d3b886e07dc2af10e2",
"description": "A Query Language and Runtime which can target any service.",

@@ -35,3 +35,3 @@ "license": "MIT",

"publishConfig": {
"tag": "canary-pr-3601"
"tag": "canary-pr-3651"
},

@@ -50,3 +50,3 @@ "type": "module",

},
"deprecated": "You are using canary version build from https://github.com/graphql/graphql-js/pull/3601, no gurantees provided so please use your own discretion."
"deprecated": "You are using canary version build from https://github.com/graphql/graphql-js/pull/3651, no gurantees provided so please use your own discretion."
}

@@ -1,2 +0,1 @@

import { devAssert } from '../jsutils/devAssert.js';
import { GraphQLError } from '../error/GraphQLError.js';

@@ -8,4 +7,2 @@ import { isNameContinue, isNameStart } from '../language/characterClasses.js';

export function assertName(name) {
name != null || devAssert(false, 'Must provide name.');
typeof name === 'string' || devAssert(false, 'Expected name to be a string.');
if (name.length === 0) {

@@ -12,0 +9,0 @@ throw new GraphQLError('Expected name to be a non-empty string.');

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

*/
export declare type GraphQLType =
| GraphQLNamedType
| GraphQLList<GraphQLType>
| GraphQLNonNull<GraphQLNullableType>;
export declare type GraphQLType = GraphQLNamedType | GraphQLWrappingType;
export declare function isType(type: unknown): type is GraphQLType;

@@ -81,3 +78,3 @@ export declare function assertType(type: unknown): GraphQLType;

type: unknown,
): GraphQLNonNull<GraphQLType>;
): GraphQLNonNull<GraphQLNullableType>;
/**

@@ -193,3 +190,3 @@ * These types may be used as input types for arguments and directives.

| GraphQLList<GraphQLType>
| GraphQLNonNull<GraphQLType>;
| GraphQLNonNull<GraphQLNullableType>;
export declare function isWrappingType(

@@ -196,0 +193,0 @@ type: unknown,

@@ -6,3 +6,2 @@ import { devAssert } from '../jsutils/devAssert.js';

import { instanceOf } from '../jsutils/instanceOf.js';
import { isObjectLike } from '../jsutils/isObjectLike.js';
import { keyMap } from '../jsutils/keyMap.js';

@@ -195,4 +194,2 @@ import { keyValMap } from '../jsutils/keyValMap.js';

constructor(ofType) {
isType(ofType) ||
devAssert(false, `Expected ${inspect(ofType)} to be a GraphQL type.`);
this.ofType = ofType;

@@ -233,7 +230,2 @@ }

constructor(ofType) {
isNullableType(ofType) ||
devAssert(
false,
`Expected ${inspect(ofType)} to be a GraphQL nullable type.`,
);
this.ofType = ofType;

@@ -350,15 +342,2 @@ }

this.extensionASTNodes = config.extensionASTNodes ?? [];
config.specifiedByURL == null ||
typeof config.specifiedByURL === 'string' ||
devAssert(
false,
`${this.name} must provide "specifiedByURL" as a string, ` +
`but got: ${inspect(config.specifiedByURL)}.`,
);
config.serialize == null ||
typeof config.serialize === 'function' ||
devAssert(
false,
`${this.name} must provide "serialize" function. If this custom Scalar is also used as an input type, ensure "parseValue" and "parseLiteral" functions are also provided.`,
);
if (config.parseLiteral) {

@@ -446,9 +425,2 @@ (typeof config.parseValue === 'function' &&

this._interfaces = () => defineInterfaces(config);
config.isTypeOf == null ||
typeof config.isTypeOf === 'function' ||
devAssert(
false,
`${this.name} must provide "isTypeOf" as a function, ` +
`but got: ${inspect(config.isTypeOf)}.`,
);
}

@@ -490,36 +462,8 @@ get [Symbol.toStringTag]() {

function defineInterfaces(config) {
const interfaces = resolveReadonlyArrayThunk(config.interfaces ?? []);
Array.isArray(interfaces) ||
devAssert(
false,
`${config.name} interfaces must be an Array or a function which returns an Array.`,
);
return interfaces;
return resolveReadonlyArrayThunk(config.interfaces ?? []);
}
function defineFieldMap(config) {
const fieldMap = resolveObjMapThunk(config.fields);
isPlainObj(fieldMap) ||
devAssert(
false,
`${config.name} fields must be an object with field names as keys or a function which returns such an object.`,
);
return mapValue(fieldMap, (fieldConfig, fieldName) => {
isPlainObj(fieldConfig) ||
devAssert(
false,
`${config.name}.${fieldName} field config must be an object.`,
);
fieldConfig.resolve == null ||
typeof fieldConfig.resolve === 'function' ||
devAssert(
false,
`${config.name}.${fieldName} field resolver must be a function if ` +
`provided, but got: ${inspect(fieldConfig.resolve)}.`,
);
const argsConfig = fieldConfig.args ?? {};
isPlainObj(argsConfig) ||
devAssert(
false,
`${config.name}.${fieldName} args must be an object with argument names as keys.`,
);
return {

@@ -549,5 +493,2 @@ name: assertName(fieldName),

}
function isPlainObj(obj) {
return isObjectLike(obj) && !Array.isArray(obj);
}
function fieldsToFieldsConfig(fields) {

@@ -614,9 +555,2 @@ return mapValue(fields, (field) => ({

this._interfaces = defineInterfaces.bind(undefined, config);
config.resolveType == null ||
typeof config.resolveType === 'function' ||
devAssert(
false,
`${this.name} must provide "resolveType" as a function, ` +
`but got: ${inspect(config.resolveType)}.`,
);
}

@@ -690,9 +624,2 @@ get [Symbol.toStringTag]() {

this._types = defineTypes.bind(undefined, config);
config.resolveType == null ||
typeof config.resolveType === 'function' ||
devAssert(
false,
`${this.name} must provide "resolveType" as a function, ` +
`but got: ${inspect(config.resolveType)}.`,
);
}

@@ -727,9 +654,3 @@ get [Symbol.toStringTag]() {

function defineTypes(config) {
const types = resolveReadonlyArrayThunk(config.types);
Array.isArray(types) ||
devAssert(
false,
`Must provide Array of types or a function which returns such an array for Union ${config.name}.`,
);
return types;
return resolveReadonlyArrayThunk(config.types);
}

@@ -766,3 +687,12 @@ /**

this.extensionASTNodes = config.extensionASTNodes ?? [];
this._values = defineEnumValues(this.name, config.values);
this._values = Object.entries(config.values).map(
([valueName, valueConfig]) => ({
name: assertEnumValueName(valueName),
description: valueConfig.description,
value: valueConfig.value !== undefined ? valueConfig.value : valueName,
deprecationReason: valueConfig.deprecationReason,
extensions: toObjMap(valueConfig.extensions),
astNode: valueConfig.astNode,
}),
);
this._valueLookup = new Map(

@@ -862,25 +792,2 @@ this._values.map((enumValue) => [enumValue.value, enumValue]),

}
function defineEnumValues(typeName, valueMap /* <T> */) {
isPlainObj(valueMap) ||
devAssert(
false,
`${typeName} values must be an object with value names as keys.`,
);
return Object.entries(valueMap).map(([valueName, valueConfig]) => {
isPlainObj(valueConfig) ||
devAssert(
false,
`${typeName}.${valueName} must refer to an object with a "value" key ` +
`representing an internal value but got: ${inspect(valueConfig)}.`,
);
return {
name: assertEnumValueName(valueName),
description: valueConfig.description,
value: valueConfig.value !== undefined ? valueConfig.value : valueName,
deprecationReason: valueConfig.deprecationReason,
extensions: toObjMap(valueConfig.extensions),
astNode: valueConfig.astNode,
};
});
}
/**

@@ -952,7 +859,2 @@ * Input Object Type Definition

const fieldMap = resolveObjMapThunk(config.fields);
isPlainObj(fieldMap) ||
devAssert(
false,
`${config.name} fields must be an object with field names as keys or a function which returns such an object.`,
);
return mapValue(fieldMap, (fieldConfig, fieldName) => {

@@ -959,0 +861,0 @@ !('resolve' in fieldConfig) ||

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

import { devAssert } from '../jsutils/devAssert.js';
import { inspect } from '../jsutils/inspect.js';
import { instanceOf } from '../jsutils/instanceOf.js';
import { isObjectLike } from '../jsutils/isObjectLike.js';
import { toObjMap } from '../jsutils/toObjMap.js';

@@ -40,10 +38,3 @@ import { DirectiveLocation } from '../language/directiveLocation.js';

this.astNode = config.astNode;
Array.isArray(config.locations) ||
devAssert(false, `@${config.name} locations must be an Array.`);
const args = config.args ?? {};
(isObjectLike(args) && !Array.isArray(args)) ||
devAssert(
false,
`@${config.name} args must be an object with argument names as keys.`,
);
this.args = defineArguments(args);

@@ -50,0 +41,0 @@ }

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

GraphQLAbstractType,
GraphQLCompositeType,
GraphQLField,
GraphQLInterfaceType,

@@ -136,2 +138,17 @@ GraphQLNamedType,

getDirective(name: string): Maybe<GraphQLDirective>;
/**
* 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.
*/
getField(
parentType: GraphQLCompositeType,
fieldName: string,
): GraphQLField<unknown, unknown> | undefined;
toConfig(): GraphQLSchemaNormalizedConfig;

@@ -138,0 +155,0 @@ }

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

import { devAssert } from '../jsutils/devAssert.js';
import { inspect } from '../jsutils/inspect.js';
import { instanceOf } from '../jsutils/instanceOf.js';
import { isObjectLike } from '../jsutils/isObjectLike.js';
import { toObjMap } from '../jsutils/toObjMap.js';

@@ -15,3 +13,8 @@ import { OperationTypeNode } from '../language/ast.js';

import { isDirective, specifiedDirectives } from './directives.js';
import { __Schema } from './introspection.js';
import {
__Schema,
SchemaMetaFieldDef,
TypeMetaFieldDef,
TypeNameMetaFieldDef,
} from './introspection.js';
/**

@@ -102,18 +105,2 @@ * Test if the given value is a GraphQL schema.

this.__validationErrors = config.assumeValid === true ? [] : undefined;
// Check for common mistakes during construction to produce early errors.
isObjectLike(config) ||
devAssert(false, 'Must provide configuration object.');
!config.types ||
Array.isArray(config.types) ||
devAssert(
false,
`"types" must be Array if provided but got: ${inspect(config.types)}.`,
);
!config.directives ||
Array.isArray(config.directives) ||
devAssert(
false,
'"directives" must be Array if provided but got: ' +
`${inspect(config.directives)}.`,
);
this.description = config.description;

@@ -167,7 +154,2 @@ this.extensions = toObjMap(config.extensions);

const typeName = namedType.name;
typeName != null ||
devAssert(
false,
'One of the provided types for building the Schema is missing a name.',
);
if (this._typeMap[typeName] !== undefined) {

@@ -274,2 +256,33 @@ throw new Error(

}
/**
* 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.
*/
getField(parentType, fieldName) {
switch (fieldName) {
case SchemaMetaFieldDef.name:
return this.getQueryType() === parentType
? SchemaMetaFieldDef
: undefined;
case TypeMetaFieldDef.name:
return this.getQueryType() === parentType
? TypeMetaFieldDef
: undefined;
case TypeNameMetaFieldDef.name:
return TypeNameMetaFieldDef;
}
// this function is part "hot" path inside executor and check presence
// of 'getFields' is faster than to use `!isUnionType`
if ('getFields' in parentType) {
return parentType.getFields()[fieldName];
}
return undefined;
}
toConfig() {

@@ -276,0 +289,0 @@ return {

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

import { devAssert } from '../jsutils/devAssert.js';
import { Kind } from '../language/kinds.js';
import { parse } from '../language/parser.js';

@@ -19,4 +17,2 @@ import { specifiedDirectives } from '../type/directives.js';

export function buildASTSchema(documentAST, options) {
(documentAST != null && documentAST.kind === Kind.DOCUMENT) ||
devAssert(false, 'Must provide valid Document AST.');
if (options?.assumeValid !== true && options?.assumeValidSDL !== true) {

@@ -23,0 +19,0 @@ assertValidSDL(documentAST);

@@ -39,2 +39,4 @@ import { devAssert } from '../jsutils/devAssert.js';

export function buildClientSchema(introspection, options) {
// Even even though `introspection` argument is typed in most cases it's received
// as untyped value from server, so we will do an additional check here.
(isObjectLike(introspection) && isObjectLike(introspection.__schema)) ||

@@ -41,0 +43,0 @@ devAssert(

@@ -1,2 +0,1 @@

import { devAssert } from '../jsutils/devAssert.js';
import { inspect } from '../jsutils/inspect.js';

@@ -33,2 +32,3 @@ import { invariant } from '../jsutils/invariant.js';

GraphQLSpecifiedByDirective,
isSpecifiedDirective,
} from '../type/directives.js';

@@ -61,4 +61,2 @@ import {

assertSchema(schema);
(documentAST != null && documentAST.kind === Kind.DOCUMENT) ||
devAssert(false, 'Must provide valid Document AST.');
if (options?.assumeValid !== true && options?.assumeValidSDL !== true) {

@@ -167,2 +165,6 @@ assertValidSDLExtension(documentAST, schema);

function replaceDirective(directive) {
if (isSpecifiedDirective(directive)) {
// Builtin directives are not extended.
return directive;
}
const config = directive.toConfig();

@@ -169,0 +171,0 @@ return new GraphQLDirective({

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

schema: GraphQLSchema,
parentType: GraphQLType,
parentType: GraphQLCompositeType,
fieldNode: FieldNode,

@@ -59,0 +59,0 @@ ) => Maybe<GraphQLField<unknown, unknown>>;

@@ -11,3 +11,2 @@ import { isNode } from '../language/ast.js';

isInputType,
isInterfaceType,
isListType,

@@ -17,7 +16,2 @@ isObjectType,

} from '../type/definition.js';
import {
SchemaMetaFieldDef,
TypeMetaFieldDef,
TypeNameMetaFieldDef,
} from '../type/introspection.js';
import { typeFromAST } from './typeFromAST.js';

@@ -250,24 +244,4 @@ /**

}
/**
* Not exactly the same as the executor's definition of getFieldDef, in this
* statically evaluated environment we do not always have an Object type,
* and need to handle Interface and Union types.
*/
function getFieldDef(schema, parentType, fieldNode) {
const name = fieldNode.name.value;
if (
name === SchemaMetaFieldDef.name &&
schema.getQueryType() === parentType
) {
return SchemaMetaFieldDef;
}
if (name === TypeMetaFieldDef.name && schema.getQueryType() === parentType) {
return TypeMetaFieldDef;
}
if (name === TypeNameMetaFieldDef.name && isCompositeType(parentType)) {
return TypeNameMetaFieldDef;
}
if (isObjectType(parentType) || isInterfaceType(parentType)) {
return parentType.getFields()[name];
}
return schema.getField(parentType, fieldNode.name.value);
}

@@ -274,0 +248,0 @@ /**

@@ -11,3 +11,2 @@ export { validate } from './validate';

export { KnownFragmentNamesRule } from './rules/KnownFragmentNamesRule';
export { KnownOperationTypesRule } from './rules/KnownOperationTypesRule';
export { KnownTypeNamesRule } from './rules/KnownTypeNamesRule';

@@ -14,0 +13,0 @@ export { LoneAnonymousOperationRule } from './rules/LoneAnonymousOperationRule';

@@ -17,4 +17,2 @@ export { validate } from './validate.js';

export { KnownFragmentNamesRule } from './rules/KnownFragmentNamesRule.js';
// Spec Section: "Operation Type Existence"
export { KnownOperationTypesRule } from './rules/KnownOperationTypesRule.js';
// Spec Section: "Fragment Spread Type Existence"

@@ -21,0 +19,0 @@ export { KnownTypeNamesRule } from './rules/KnownTypeNamesRule.js';

@@ -15,2 +15,5 @@ import { inspect } from '../../jsutils/inspect.js';

import { typeFromAST } from '../../utilities/typeFromAST.js';
/* eslint-disable max-params */
// This file contains a lot of such errors but we plan to refactor it anyway
// so just disable it for entire file.
function reasonMessage(reason) {

@@ -17,0 +20,0 @@ if (Array.isArray(reason)) {

@@ -16,4 +16,2 @@ // Spec Section: "Executable Definitions"

import { KnownFragmentNamesRule } from './rules/KnownFragmentNamesRule.js';
// Spec Section: "Operation Type Existence"
import { KnownOperationTypesRule } from './rules/KnownOperationTypesRule.js';
// Spec Section: "Fragment Spread Type Existence"

@@ -79,3 +77,2 @@ import { KnownTypeNamesRule } from './rules/KnownTypeNamesRule.js';

ExecutableDefinitionsRule,
KnownOperationTypesRule,
UniqueOperationNamesRule,

@@ -82,0 +79,0 @@ LoneAnonymousOperationRule,

@@ -1,2 +0,1 @@

import { devAssert } from '../jsutils/devAssert.js';
import { GraphQLError } from '../error/GraphQLError.js';

@@ -40,3 +39,2 @@ import { visit, visitInParallel } from '../language/visitor.js';

const maxErrors = options?.maxErrors ?? 100;
documentAST != null || devAssert(false, 'Must provide document.');
// If the schema used for validation is invalid, throw an error.

@@ -43,0 +41,0 @@ assertValidSchema(schema);

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