Spaces:
Running
Running
File size: 4,513 Bytes
d4b85c0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
import { inspect } from '../jsutils/inspect.mjs';
import { invariant } from '../jsutils/invariant.mjs';
import { keyValMap } from '../jsutils/keyValMap.mjs';
import { naturalCompare } from '../jsutils/naturalCompare.mjs';
import {
GraphQLEnumType,
GraphQLInputObjectType,
GraphQLInterfaceType,
GraphQLList,
GraphQLNonNull,
GraphQLObjectType,
GraphQLUnionType,
isEnumType,
isInputObjectType,
isInterfaceType,
isListType,
isNonNullType,
isObjectType,
isScalarType,
isUnionType,
} from '../type/definition.mjs';
import { GraphQLDirective } from '../type/directives.mjs';
import { isIntrospectionType } from '../type/introspection.mjs';
import { GraphQLSchema } from '../type/schema.mjs';
/**
* Sort GraphQLSchema.
*
* This function returns a sorted copy of the given GraphQLSchema.
*/
export function lexicographicSortSchema(schema) {
const schemaConfig = schema.toConfig();
const typeMap = keyValMap(
sortByName(schemaConfig.types),
(type) => type.name,
sortNamedType,
);
return new GraphQLSchema({
...schemaConfig,
types: Object.values(typeMap),
directives: sortByName(schemaConfig.directives).map(sortDirective),
query: replaceMaybeType(schemaConfig.query),
mutation: replaceMaybeType(schemaConfig.mutation),
subscription: replaceMaybeType(schemaConfig.subscription),
});
function replaceType(type) {
if (isListType(type)) {
// @ts-expect-error
return new GraphQLList(replaceType(type.ofType));
} else if (isNonNullType(type)) {
// @ts-expect-error
return new GraphQLNonNull(replaceType(type.ofType));
} // @ts-expect-error FIXME: TS Conversion
return replaceNamedType(type);
}
function replaceNamedType(type) {
return typeMap[type.name];
}
function replaceMaybeType(maybeType) {
return maybeType && replaceNamedType(maybeType);
}
function sortDirective(directive) {
const config = directive.toConfig();
return new GraphQLDirective({
...config,
locations: sortBy(config.locations, (x) => x),
args: sortArgs(config.args),
});
}
function sortArgs(args) {
return sortObjMap(args, (arg) => ({ ...arg, type: replaceType(arg.type) }));
}
function sortFields(fieldsMap) {
return sortObjMap(fieldsMap, (field) => ({
...field,
type: replaceType(field.type),
args: field.args && sortArgs(field.args),
}));
}
function sortInputFields(fieldsMap) {
return sortObjMap(fieldsMap, (field) => ({
...field,
type: replaceType(field.type),
}));
}
function sortTypes(array) {
return sortByName(array).map(replaceNamedType);
}
function sortNamedType(type) {
if (isScalarType(type) || isIntrospectionType(type)) {
return type;
}
if (isObjectType(type)) {
const config = type.toConfig();
return new GraphQLObjectType({
...config,
interfaces: () => sortTypes(config.interfaces),
fields: () => sortFields(config.fields),
});
}
if (isInterfaceType(type)) {
const config = type.toConfig();
return new GraphQLInterfaceType({
...config,
interfaces: () => sortTypes(config.interfaces),
fields: () => sortFields(config.fields),
});
}
if (isUnionType(type)) {
const config = type.toConfig();
return new GraphQLUnionType({
...config,
types: () => sortTypes(config.types),
});
}
if (isEnumType(type)) {
const config = type.toConfig();
return new GraphQLEnumType({
...config,
values: sortObjMap(config.values, (value) => value),
});
}
if (isInputObjectType(type)) {
const config = type.toConfig();
return new GraphQLInputObjectType({
...config,
fields: () => sortInputFields(config.fields),
});
}
/* c8 ignore next 3 */
// Not reachable, all possible types have been considered.
false || invariant(false, 'Unexpected type: ' + inspect(type));
}
}
function sortObjMap(map, sortValueFn) {
const sortedMap = Object.create(null);
for (const key of Object.keys(map).sort(naturalCompare)) {
sortedMap[key] = sortValueFn(map[key]);
}
return sortedMap;
}
function sortByName(array) {
return sortBy(array, (obj) => obj.name);
}
function sortBy(array, mapToKey) {
return array.slice().sort((obj1, obj2) => {
const key1 = mapToKey(obj1);
const key2 = mapToKey(obj2);
return naturalCompare(key1, key2);
});
}
|