Skip to content

Commit 179e479

Browse files
Switch some of 'Object.keys' to more modern ES6 constructs (#3026)
1 parent 954913b commit 179e479

File tree

10 files changed

+40
-50
lines changed

10 files changed

+40
-50
lines changed

flow-typed/core.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ declare class Object {
128128
* Returns an array of key/values of the enumerable properties of an object
129129
* @param object Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
130130
*/
131-
static entries<T>(obj: { [key: string]: T, __proto__: null }): Array<[string, T]>; // graphql-js HACK
131+
static entries<T>(obj: { +[key: string]: T, __proto__: null }): Array<[string, T]>; // graphql-js HACK
132132
static entries(object: $NotNullOrVoid): Array<[string, mixed]>;
133133
/**
134134
* Prevents the modification of existing property attributes and values, and prevents the addition of new properties.
@@ -220,7 +220,7 @@ declare class Object {
220220
* Returns an array of values of the enumerable properties of an object
221221
* @param object Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
222222
*/
223-
static values<T>(obj: { [key: string]: T, __proto__: null }): Array<T>; // graphql-js HACK
223+
static values<T>(obj: { +[key: string]: T, __proto__: null }): Array<T>; // graphql-js HACK
224224
static values(object: $NotNullOrVoid): Array<mixed>;
225225
/**
226226
* Determines whether an object has a property with the specified name.

src/jsutils/inspect.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,18 @@ function formatObjectValue(
5454
}
5555

5656
function formatObject(object: Object, seenValues: Array<mixed>): string {
57-
const keys = Object.keys(object);
58-
if (keys.length === 0) {
57+
const entries = Object.entries(object);
58+
if (entries.length === 0) {
5959
return '{}';
6060
}
6161

6262
if (seenValues.length > MAX_RECURSIVE_DEPTH) {
6363
return '[' + getObjectTag(object) + ']';
6464
}
6565

66-
const properties = keys.map((key) => {
67-
const value = formatValue(object[key], seenValues);
68-
return key + ': ' + value;
69-
});
70-
66+
const properties = entries.map(
67+
([key, value]) => key + ': ' + formatValue(value, seenValues),
68+
);
7169
return '{ ' + properties.join(', ') + ' }';
7270
}
7371

src/jsutils/mapValue.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import type { ObjMap } from './ObjMap';
1+
import type { ObjMap, ReadOnlyObjMap } from './ObjMap';
22
/**
33
* Creates an object map with the same keys as `map` and values generated by
44
* running each value of `map` thru `fn`.
55
*/
66
export function mapValue<T, V>(
7-
map: ObjMap<T>,
7+
map: ReadOnlyObjMap<T>,
88
fn: (value: T, key: string) => V,
99
): ObjMap<V>;

src/jsutils/mapValue.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import type { ObjMap } from './ObjMap';
1+
import type { ObjMap, ReadOnlyObjMap } from './ObjMap';
22

33
/**
44
* Creates an object map with the same keys as `map` and values generated by
55
* running each value of `map` thru `fn`.
66
*/
77
export function mapValue<T, V>(
8-
map: ObjMap<T>,
8+
map: ReadOnlyObjMap<T>,
99
fn: (value: T, key: string) => V,
1010
): ObjMap<V> {
1111
const result = Object.create(null);

src/language/__tests__/toJSONDeep.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { mapValue } from '../../jsutils/mapValue';
12
import { isObjectLike } from '../../jsutils/isObjectLike';
23

34
/**
@@ -18,9 +19,5 @@ export function toJSONDeep(value: mixed): mixed {
1819
return value.map(toJSONDeep);
1920
}
2021

21-
const result = Object.create(null);
22-
for (const prop of Object.keys(value)) {
23-
result[prop] = toJSONDeep(value[prop]);
24-
}
25-
return result;
22+
return mapValue(value, toJSONDeep);
2623
}

src/utilities/lexicographicSortSchema.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ export function lexicographicSortSchema(schema: GraphQLSchema): GraphQLSchema {
139139
const config = type.toConfig();
140140
return new GraphQLEnumType({
141141
...config,
142-
values: sortObjMap(config.values),
142+
values: sortObjMap(config.values, (value) => value),
143143
});
144144
}
145145
// istanbul ignore else (See: 'https://github.com/graphql/graphql-js/issues/2618')
@@ -156,12 +156,11 @@ export function lexicographicSortSchema(schema: GraphQLSchema): GraphQLSchema {
156156
}
157157
}
158158

159-
function sortObjMap<T, R>(map: ObjMap<T>, sortValueFn?: (T) => R): ObjMap<R> {
159+
function sortObjMap<T, R>(map: ObjMap<T>, sortValueFn: (T) => R): ObjMap<R> {
160160
const sortedMap = Object.create(null);
161-
const sortedKeys = sortBy(Object.keys(map), (x) => x);
162-
for (const key of sortedKeys) {
163-
const value = map[key];
164-
sortedMap[key] = sortValueFn ? sortValueFn(value) : value;
161+
const sortedEntries = sortBy(Object.entries(map), ([key]) => key);
162+
for (const [key, value] of sortedEntries) {
163+
sortedMap[key] = sortValueFn(value);
165164
}
166165
return sortedMap;
167166
}

src/validation/rules/KnownTypeNamesRule.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@ export function KnownTypeNamesRule(
3838
}
3939
}
4040

41-
const typeNames = Object.keys(existingTypesMap).concat(
42-
Object.keys(definedTypes),
43-
);
41+
const typeNames = [
42+
...Object.keys(existingTypesMap),
43+
...Object.keys(definedTypes),
44+
];
4445

4546
return {
4647
NamedType(node, _1, parent, _2, ancestors) {

src/validation/rules/OverlappingFieldsCanBeMergedRule.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -505,10 +505,9 @@ function collectConflictsBetween(
505505
// response name. For any response name which appears in both provided field
506506
// maps, each field from the first field map must be compared to every field
507507
// in the second field map to find potential conflicts.
508-
for (const responseName of Object.keys(fieldMap1)) {
508+
for (const [responseName, fields1] of Object.entries(fieldMap1)) {
509509
const fields2 = fieldMap2[responseName];
510510
if (fields2) {
511-
const fields1 = fieldMap1[responseName];
512511
for (let i = 0; i < fields1.length; i++) {
513512
for (let j = 0; j < fields2.length; j++) {
514513
const conflict = findConflict(

src/validation/rules/PossibleTypeExtensionsRule.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@ export function PossibleTypeExtensionsRule(
7272
);
7373
}
7474
} else {
75-
let allTypeNames = Object.keys(definedTypes);
76-
if (schema) {
77-
allTypeNames = allTypeNames.concat(Object.keys(schema.getTypeMap()));
78-
}
75+
const allTypeNames = Object.keys({
76+
...definedTypes,
77+
...schema?.getTypeMap(),
78+
});
7979

8080
const suggestedTypes = suggestionList(typeName, allTypeNames);
8181
context.reportError(

src/validation/rules/ProvidedRequiredArgumentsRule.js

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ export function ProvidedRequiredArgumentsRule(
3636
return false;
3737
}
3838

39-
// istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
40-
const argNodes = fieldNode.arguments ?? [];
41-
const argNodeMap = keyMap(argNodes, (arg) => arg.name.value);
39+
const providedArgs = new Set(
40+
// istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
41+
fieldNode.arguments?.map((arg) => arg.name.value),
42+
);
4243
for (const argDef of fieldDef.args) {
43-
const argNode = argNodeMap[argDef.name];
44-
if (!argNode && isRequiredArgument(argDef)) {
44+
if (!providedArgs.has(argDef.name) && isRequiredArgument(argDef)) {
4545
const argTypeStr = inspect(argDef.type);
4646
context.reportError(
4747
new GraphQLError(
@@ -65,9 +65,7 @@ export function ProvidedRequiredArgumentsOnDirectivesRule(
6565
const requiredArgsMap = Object.create(null);
6666

6767
const schema = context.getSchema();
68-
const definedDirectives = schema
69-
? schema.getDirectives()
70-
: specifiedDirectives;
68+
const definedDirectives = schema?.getDirectives() ?? specifiedDirectives;
7169
for (const directive of definedDirectives) {
7270
requiredArgsMap[directive.name] = keyMap(
7371
directive.args.filter(isRequiredArgument),
@@ -97,17 +95,15 @@ export function ProvidedRequiredArgumentsOnDirectivesRule(
9795
if (requiredArgs) {
9896
// istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
9997
const argNodes = directiveNode.arguments ?? [];
100-
const argNodeMap = keyMap(argNodes, (arg) => arg.name.value);
101-
for (const argName of Object.keys(requiredArgs)) {
102-
if (!argNodeMap[argName]) {
103-
const argType = requiredArgs[argName].type;
104-
const argTypeStr = isType(argType)
105-
? inspect(argType)
106-
: print(argType);
107-
98+
const argNodeMap = new Set(argNodes.map((arg) => arg.name.value));
99+
for (const [argName, argDef] of Object.entries(requiredArgs)) {
100+
if (!argNodeMap.has(argName)) {
101+
const argType = isType(argDef.type)
102+
? inspect(argDef.type)
103+
: print(argDef.type);
108104
context.reportError(
109105
new GraphQLError(
110-
`Directive "@${directiveName}" argument "${argName}" of type "${argTypeStr}" is required, but it was not provided.`,
106+
`Directive "@${directiveName}" argument "${argName}" of type "${argType}" is required, but it was not provided.`,
111107
directiveNode,
112108
),
113109
);

0 commit comments

Comments
 (0)