lexicographicSortSchema.js 4.6 KB

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