Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use nullish coalescing operator in all appropriate places #2423

Merged
merged 1 commit into from
Feb 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/__tests__/starWarsData.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export type Droid = {|
*/
function getCharacter(id) {
// Returning a promise just to illustrate that GraphQL.js supports it.
return Promise.resolve(humanData[id] || droidData[id]);
return Promise.resolve(humanData[id] ?? droidData[id]);
}

/**
Expand Down
12 changes: 6 additions & 6 deletions src/error/GraphQLError.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export class GraphQLError extends Error {
locations: {
// Coercing falsy values to undefined ensures they will not be included
// in JSON.stringify() when not provided.
value: _locations || undefined,
value: _locations ?? undefined,
// By being enumerable, JSON.stringify will include `locations` in the
// resulting output. This ensures that the simplest possible GraphQL
// service adheres to the spec.
Expand All @@ -157,28 +157,28 @@ export class GraphQLError extends Error {
path: {
// Coercing falsy values to undefined ensures they will not be included
// in JSON.stringify() when not provided.
value: path || undefined,
value: path ?? undefined,
// By being enumerable, JSON.stringify will include `path` in the
// resulting output. This ensures that the simplest possible GraphQL
// service adheres to the spec.
enumerable: path != null,
},
nodes: {
value: _nodes || undefined,
value: _nodes ?? undefined,
},
source: {
value: _source || undefined,
value: _source ?? undefined,
},
positions: {
value: _positions || undefined,
value: _positions ?? undefined,
},
originalError: {
value: originalError,
},
extensions: {
// Coercing falsy values to undefined ensures they will not be included
// in JSON.stringify() when not provided.
value: _extensions || undefined,
value: _extensions ?? undefined,
// By being enumerable, JSON.stringify will include `path` in the
// resulting output. This ensures that the simplest possible GraphQL
// service adheres to the spec.
Expand Down
2 changes: 1 addition & 1 deletion src/error/formatError.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { type GraphQLError } from './GraphQLError';
*/
export function formatError(error: GraphQLError): GraphQLFormattedError {
devAssert(error, 'Received null or undefined error.');
const message = error.message || 'An unknown error occurred.';
const message = error.message ?? 'An unknown error occurred.';
const locations = error.locations;
const path = error.path;
const extensions = error.extensions;
Expand Down
2 changes: 1 addition & 1 deletion src/error/locatedError.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function locatedError(

return new GraphQLError(
originalError.message,
(originalError: any).nodes || nodes,
(originalError: any).nodes ?? nodes,
(originalError: any).source,
(originalError: any).positions,
path,
Expand Down
12 changes: 6 additions & 6 deletions src/execution/execute.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,12 +314,12 @@ export function buildExecutionContext(
}

/* istanbul ignore next (See https://github.com/graphql/graphql-js/issues/2203) */
const variableDefinitions = operation.variableDefinitions || [];
const variableDefinitions = operation.variableDefinitions ?? [];

const coercedVariableValues = getVariableValues(
schema,
variableDefinitions,
rawVariableValues || {},
rawVariableValues ?? {},
{ maxErrors: 50 },
);

Expand All @@ -334,8 +334,8 @@ export function buildExecutionContext(
contextValue,
operation,
variableValues: coercedVariableValues.coerced,
fieldResolver: fieldResolver || defaultFieldResolver,
typeResolver: typeResolver || defaultTypeResolver,
fieldResolver: fieldResolver ?? defaultFieldResolver,
typeResolver: typeResolver ?? defaultTypeResolver,
errors: [],
};
}
Expand Down Expand Up @@ -619,7 +619,7 @@ function resolveField(
return;
}

const resolveFn = fieldDef.resolve || exeContext.fieldResolver;
const resolveFn = fieldDef.resolve ?? exeContext.fieldResolver;

const info = buildResolveInfo(
exeContext,
Expand Down Expand Up @@ -961,7 +961,7 @@ function completeAbstractValue(
path: Path,
result: mixed,
): PromiseOrValue<ObjMap<mixed>> {
const resolveTypeFn = returnType.resolveType || exeContext.typeResolver;
const resolveTypeFn = returnType.resolveType ?? exeContext.typeResolver;
const contextValue = exeContext.contextValue;
const runtimeType = resolveTypeFn(result, contextValue, info, returnType);

Expand Down
2 changes: 1 addition & 1 deletion src/execution/values.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export function getArgumentValues(
const coercedValues = {};

/* istanbul ignore next (See https://github.com/graphql/graphql-js/issues/2203) */
const argumentNodes = node.arguments || [];
const argumentNodes = node.arguments ?? [];
const argNodeMap = keyMap(argumentNodes, arg => arg.name.value);

for (const argDef of def.args) {
Expand Down
2 changes: 1 addition & 1 deletion src/language/lexer.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export class Lexer {
if (token.kind !== TokenKind.EOF) {
do {
// Note: next is only mutable during parsing, so we cast to allow this.
token = token.next || ((token: any).next = readToken(this, token));
token = token.next ?? ((token: any).next = readToken(this, token));
} while (token.kind === TokenKind.COMMENT);
}
return token;
Expand Down
2 changes: 1 addition & 1 deletion src/language/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -1482,7 +1482,7 @@ class Parser {
* is encountered.
*/
unexpected(atToken?: ?Token): GraphQLError {
const token = atToken || this._lexer.token;
const token = atToken ?? this._lexer.token;
return syntaxError(
this._lexer.source,
token.start,
Expand Down
2 changes: 1 addition & 1 deletion src/language/printer.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ function addDescription(cb) {
* print all items together separated by separator if provided
*/
function join(maybeArray: ?Array<string>, separator = '') {
return maybeArray?.filter(x => x).join(separator) || '';
return maybeArray?.filter(x => x).join(separator) ?? '';
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/language/visitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ export function visit(
} else {
stack = { inArray, index, keys, edits, prev: stack };
inArray = Array.isArray(node);
keys = inArray ? node : visitorKeys[node.kind] || [];
keys = inArray ? node : visitorKeys[node.kind] ?? [];
index = -1;
edits = [];
if (parent) {
Expand Down
2 changes: 1 addition & 1 deletion src/subscription/subscribe.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ export function createSourceEventStream(

// Call the `subscribe()` resolver or the default resolver to produce an
// AsyncIterable yielding raw payloads.
const resolveFn = fieldDef.subscribe || exeContext.fieldResolver;
const resolveFn = fieldDef.subscribe ?? exeContext.fieldResolver;

const path = addPath(undefined, responseName);

Expand Down
10 changes: 5 additions & 5 deletions src/type/definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -575,13 +575,13 @@ export class GraphQLScalarType {
extensionASTNodes: ?$ReadOnlyArray<ScalarTypeExtensionNode>;

constructor(config: $ReadOnly<GraphQLScalarTypeConfig<mixed, mixed>>): void {
const parseValue = config.parseValue || identityFunc;
const parseValue = config.parseValue ?? identityFunc;
this.name = config.name;
this.description = config.description;
this.serialize = config.serialize || identityFunc;
this.serialize = config.serialize ?? identityFunc;
this.parseValue = parseValue;
this.parseLiteral =
config.parseLiteral || (node => parseValue(valueFromASTUntyped(node)));
config.parseLiteral ?? (node => parseValue(valueFromASTUntyped(node)));
this.extensions = config.extensions && toObjMap(config.extensions);
this.astNode = config.astNode;
this.extensionASTNodes = undefineIfEmpty(config.extensionASTNodes);
Expand Down Expand Up @@ -777,7 +777,7 @@ function defineInterfaces(
| GraphQLInterfaceTypeConfig<mixed, mixed>,
>,
): Array<GraphQLInterfaceType> {
const interfaces = resolveThunk(config.interfaces) || [];
const interfaces = resolveThunk(config.interfaces) ?? [];
devAssert(
Array.isArray(interfaces),
`${config.name} interfaces must be an Array or a function which returns an Array.`,
Expand Down Expand Up @@ -812,7 +812,7 @@ function defineFieldMap<TSource, TContext>(
`provided, but got: ${inspect(fieldConfig.resolve)}.`,
);

const argsConfig = fieldConfig.args || {};
const argsConfig = fieldConfig.args ?? {};
devAssert(
isPlainObj(argsConfig),
`${config.name}.${fieldName} args must be an object with argument names as keys.`,
Expand Down
4 changes: 2 additions & 2 deletions src/type/directives.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export class GraphQLDirective {
this.name = config.name;
this.description = config.description;
this.locations = config.locations;
this.isRepeatable = config.isRepeatable || false;
this.isRepeatable = config.isRepeatable ?? false;
this.extensions = config.extensions && toObjMap(config.extensions);
this.astNode = config.astNode;

Expand All @@ -75,7 +75,7 @@ export class GraphQLDirective {
`@${config.name} locations must be an Array.`,
);

const args = config.args || {};
const args = config.args ?? {};
devAssert(
isObjectLike(args) && !Array.isArray(args),
`@${config.name} args must be an object with argument names as keys.`,
Expand Down
4 changes: 2 additions & 2 deletions src/type/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ export class GraphQLSchema {
this._mutationType = config.mutation;
this._subscriptionType = config.subscription;
// Provide specified directives (e.g. @include and @skip) by default.
this._directives = config.directives || specifiedDirectives;
this._directives = config.directives ?? specifiedDirectives;

// To preserve order of user-provided types, we add first to add them to
// the set of "collected" types, so `collectReferencedTypes` ignore them.
Expand Down Expand Up @@ -289,7 +289,7 @@ export class GraphQLSchema {
interfaces: /* $ReadOnly */ Array<GraphQLInterfaceType>,
|} {
const implementations = this._implementationsMap[interfaceType.name];
return implementations || { objects: [], interfaces: [] };
return implementations ?? { objects: [], interfaces: [] };
}

// @deprecated: use isSubType instead - will be removed in v16.
Expand Down
6 changes: 3 additions & 3 deletions src/type/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ function validateName(
node: { +name: string, +astNode: ?ASTNode, ... },
): void {
// Ensure names are valid, however introspection types opt out.
const error = isValidNameError(node.name, node.astNode || undefined);
const error = isValidNameError(node.name, node.astNode ?? undefined);
if (error) {
context.addError(error);
}
Expand Down Expand Up @@ -578,15 +578,15 @@ function getAllNodes<T: ASTNode, K: ASTNode>(
? extensionASTNodes
? [astNode].concat(extensionASTNodes)
: [astNode]
: extensionASTNodes || [];
: extensionASTNodes ?? [];
}

function getAllSubNodes<T: ASTNode, K: ASTNode, L: ASTNode>(
object: SDLDefinedObject<T, K>,
getter: (T | K) => ?(L | $ReadOnlyArray<L>),
): $ReadOnlyArray<L> {
/* istanbul ignore next (See https://github.com/graphql/graphql-js/issues/2203) */
return flatMap(getAllNodes(object), item => getter(item) || []);
return flatMap(getAllNodes(object), item => getter(item) ?? []);
}

function getAllImplementsInterfaceNodes(
Expand Down
4 changes: 2 additions & 2 deletions src/utilities/TypeInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class TypeInfo {
this._directive = null;
this._argument = null;
this._enumValue = null;
this._getFieldDef = getFieldDefFn || getFieldDef;
this._getFieldDef = getFieldDefFn ?? getFieldDef;
if (initialType) {
if (isInputType(initialType)) {
this._inputTypeStack.push(initialType);
Expand Down Expand Up @@ -205,7 +205,7 @@ export class TypeInfo {
case Kind.ARGUMENT: {
let argDef;
let argType: mixed;
const fieldOrDirective = this.getDirective() || this.getFieldDef();
const fieldOrDirective = this.getDirective() ?? this.getFieldDef();
if (fieldOrDirective) {
argDef = find(
fieldOrDirective.args,
Expand Down
20 changes: 18 additions & 2 deletions src/utilities/__tests__/buildASTSchema-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { parse } from '../../language/parser';
import { print } from '../../language/printer';

import { validateSchema } from '../../type/validate';
import { __Schema } from '../../type/introspection';
import {
assertDirective,
GraphQLSkipDirective,
Expand Down Expand Up @@ -43,10 +44,11 @@ import { buildASTSchema, buildSchema } from '../buildASTSchema';
* the SDL, parsed in a schema AST, materializing that schema AST into an
* in-memory GraphQLSchema, and then finally printing that object into the SDL
*/
function cycleSDL(sdl, options = {}) {
const commentDescriptions = options.commentDescriptions || false;
function cycleSDL(sdl, options) {
const ast = parse(sdl);
const schema = buildASTSchema(ast, options);

const commentDescriptions = options?.commentDescriptions;
return printSchema(schema, { commentDescriptions });
}

Expand Down Expand Up @@ -1046,6 +1048,20 @@ describe('Schema Builder', () => {
expect(errors).to.have.lengthOf.above(0);
});

it('Do not override standard types', () => {
// NOTE: not sure it's desired behaviour to just silently ignore override
// attempts so just documenting it here.

const schema = buildSchema(`
scalar ID

scalar __Schema
`);

expect(schema.getType('ID')).to.equal(GraphQLID);
expect(schema.getType('__Schema')).to.equal(__Schema);
});

it('Rejects invalid SDL', () => {
const sdl = `
type Query {
Expand Down
2 changes: 1 addition & 1 deletion src/utilities/__tests__/stripIgnoredCharacters-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ function lexValue(str) {
// Called only to make error messages for failing tests
/* istanbul ignore next */
function inspectStr(str) {
return (JSON.stringify(str) || '')
return (JSON.stringify(str) ?? '')
.replace(/^"|"$/g, '`')
.replace(/\\"/g, '"');
}
Expand Down
15 changes: 7 additions & 8 deletions src/utilities/buildASTSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,17 +123,16 @@ export function buildSchema(
options?: {| ...BuildSchemaOptions, ...ParseOptions |},
): GraphQLSchema {
const document = parse(source, {
noLocation: options?.noLocation || false,
allowLegacySDLEmptyFields: options?.allowLegacySDLEmptyFields || false,
noLocation: options?.noLocation,
allowLegacySDLEmptyFields: options?.allowLegacySDLEmptyFields,
allowLegacySDLImplementsInterfaces:
options?.allowLegacySDLImplementsInterfaces || false,
experimentalFragmentVariables:
options?.experimentalFragmentVariables || false,
options?.allowLegacySDLImplementsInterfaces,
experimentalFragmentVariables: options?.experimentalFragmentVariables,
});

return buildASTSchema(document, {
commentDescriptions: options?.commentDescriptions || false,
assumeValidSDL: options?.assumeValidSDL || false,
assumeValid: options?.assumeValid || false,
commentDescriptions: options?.commentDescriptions,
assumeValidSDL: options?.assumeValidSDL,
assumeValid: options?.assumeValid,
});
}
Loading