mapSchema.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.correctASTNodes = exports.mapSchema = void 0;
  4. const graphql_1 = require("graphql");
  5. const getObjectTypeFromTypeMap_js_1 = require("./getObjectTypeFromTypeMap.js");
  6. const Interfaces_js_1 = require("./Interfaces.js");
  7. const rewire_js_1 = require("./rewire.js");
  8. const transformInputValue_js_1 = require("./transformInputValue.js");
  9. function mapSchema(schema, schemaMapper = {}) {
  10. const newTypeMap = mapArguments(mapFields(mapTypes(mapDefaultValues(mapEnumValues(mapTypes(mapDefaultValues(schema.getTypeMap(), schema, transformInputValue_js_1.serializeInputValue), schema, schemaMapper, type => (0, graphql_1.isLeafType)(type)), schema, schemaMapper), schema, transformInputValue_js_1.parseInputValue), schema, schemaMapper, type => !(0, graphql_1.isLeafType)(type)), schema, schemaMapper), schema, schemaMapper);
  11. const originalDirectives = schema.getDirectives();
  12. const newDirectives = mapDirectives(originalDirectives, schema, schemaMapper);
  13. const { typeMap, directives } = (0, rewire_js_1.rewireTypes)(newTypeMap, newDirectives);
  14. return new graphql_1.GraphQLSchema({
  15. ...schema.toConfig(),
  16. query: (0, getObjectTypeFromTypeMap_js_1.getObjectTypeFromTypeMap)(typeMap, (0, getObjectTypeFromTypeMap_js_1.getObjectTypeFromTypeMap)(newTypeMap, schema.getQueryType())),
  17. mutation: (0, getObjectTypeFromTypeMap_js_1.getObjectTypeFromTypeMap)(typeMap, (0, getObjectTypeFromTypeMap_js_1.getObjectTypeFromTypeMap)(newTypeMap, schema.getMutationType())),
  18. subscription: (0, getObjectTypeFromTypeMap_js_1.getObjectTypeFromTypeMap)(typeMap, (0, getObjectTypeFromTypeMap_js_1.getObjectTypeFromTypeMap)(newTypeMap, schema.getSubscriptionType())),
  19. types: Object.values(typeMap),
  20. directives,
  21. });
  22. }
  23. exports.mapSchema = mapSchema;
  24. function mapTypes(originalTypeMap, schema, schemaMapper, testFn = () => true) {
  25. const newTypeMap = {};
  26. for (const typeName in originalTypeMap) {
  27. if (!typeName.startsWith('__')) {
  28. const originalType = originalTypeMap[typeName];
  29. if (originalType == null || !testFn(originalType)) {
  30. newTypeMap[typeName] = originalType;
  31. continue;
  32. }
  33. const typeMapper = getTypeMapper(schema, schemaMapper, typeName);
  34. if (typeMapper == null) {
  35. newTypeMap[typeName] = originalType;
  36. continue;
  37. }
  38. const maybeNewType = typeMapper(originalType, schema);
  39. if (maybeNewType === undefined) {
  40. newTypeMap[typeName] = originalType;
  41. continue;
  42. }
  43. newTypeMap[typeName] = maybeNewType;
  44. }
  45. }
  46. return newTypeMap;
  47. }
  48. function mapEnumValues(originalTypeMap, schema, schemaMapper) {
  49. const enumValueMapper = getEnumValueMapper(schemaMapper);
  50. if (!enumValueMapper) {
  51. return originalTypeMap;
  52. }
  53. return mapTypes(originalTypeMap, schema, {
  54. [Interfaces_js_1.MapperKind.ENUM_TYPE]: type => {
  55. const config = type.toConfig();
  56. const originalEnumValueConfigMap = config.values;
  57. const newEnumValueConfigMap = {};
  58. for (const externalValue in originalEnumValueConfigMap) {
  59. const originalEnumValueConfig = originalEnumValueConfigMap[externalValue];
  60. const mappedEnumValue = enumValueMapper(originalEnumValueConfig, type.name, schema, externalValue);
  61. if (mappedEnumValue === undefined) {
  62. newEnumValueConfigMap[externalValue] = originalEnumValueConfig;
  63. }
  64. else if (Array.isArray(mappedEnumValue)) {
  65. const [newExternalValue, newEnumValueConfig] = mappedEnumValue;
  66. newEnumValueConfigMap[newExternalValue] =
  67. newEnumValueConfig === undefined ? originalEnumValueConfig : newEnumValueConfig;
  68. }
  69. else if (mappedEnumValue !== null) {
  70. newEnumValueConfigMap[externalValue] = mappedEnumValue;
  71. }
  72. }
  73. return correctASTNodes(new graphql_1.GraphQLEnumType({
  74. ...config,
  75. values: newEnumValueConfigMap,
  76. }));
  77. },
  78. }, type => (0, graphql_1.isEnumType)(type));
  79. }
  80. function mapDefaultValues(originalTypeMap, schema, fn) {
  81. const newTypeMap = mapArguments(originalTypeMap, schema, {
  82. [Interfaces_js_1.MapperKind.ARGUMENT]: argumentConfig => {
  83. if (argumentConfig.defaultValue === undefined) {
  84. return argumentConfig;
  85. }
  86. const maybeNewType = getNewType(originalTypeMap, argumentConfig.type);
  87. if (maybeNewType != null) {
  88. return {
  89. ...argumentConfig,
  90. defaultValue: fn(maybeNewType, argumentConfig.defaultValue),
  91. };
  92. }
  93. },
  94. });
  95. return mapFields(newTypeMap, schema, {
  96. [Interfaces_js_1.MapperKind.INPUT_OBJECT_FIELD]: inputFieldConfig => {
  97. if (inputFieldConfig.defaultValue === undefined) {
  98. return inputFieldConfig;
  99. }
  100. const maybeNewType = getNewType(newTypeMap, inputFieldConfig.type);
  101. if (maybeNewType != null) {
  102. return {
  103. ...inputFieldConfig,
  104. defaultValue: fn(maybeNewType, inputFieldConfig.defaultValue),
  105. };
  106. }
  107. },
  108. });
  109. }
  110. function getNewType(newTypeMap, type) {
  111. if ((0, graphql_1.isListType)(type)) {
  112. const newType = getNewType(newTypeMap, type.ofType);
  113. return newType != null ? new graphql_1.GraphQLList(newType) : null;
  114. }
  115. else if ((0, graphql_1.isNonNullType)(type)) {
  116. const newType = getNewType(newTypeMap, type.ofType);
  117. return newType != null ? new graphql_1.GraphQLNonNull(newType) : null;
  118. }
  119. else if ((0, graphql_1.isNamedType)(type)) {
  120. const newType = newTypeMap[type.name];
  121. return newType != null ? newType : null;
  122. }
  123. return null;
  124. }
  125. function mapFields(originalTypeMap, schema, schemaMapper) {
  126. const newTypeMap = {};
  127. for (const typeName in originalTypeMap) {
  128. if (!typeName.startsWith('__')) {
  129. const originalType = originalTypeMap[typeName];
  130. if (!(0, graphql_1.isObjectType)(originalType) && !(0, graphql_1.isInterfaceType)(originalType) && !(0, graphql_1.isInputObjectType)(originalType)) {
  131. newTypeMap[typeName] = originalType;
  132. continue;
  133. }
  134. const fieldMapper = getFieldMapper(schema, schemaMapper, typeName);
  135. if (fieldMapper == null) {
  136. newTypeMap[typeName] = originalType;
  137. continue;
  138. }
  139. const config = originalType.toConfig();
  140. const originalFieldConfigMap = config.fields;
  141. const newFieldConfigMap = {};
  142. for (const fieldName in originalFieldConfigMap) {
  143. const originalFieldConfig = originalFieldConfigMap[fieldName];
  144. const mappedField = fieldMapper(originalFieldConfig, fieldName, typeName, schema);
  145. if (mappedField === undefined) {
  146. newFieldConfigMap[fieldName] = originalFieldConfig;
  147. }
  148. else if (Array.isArray(mappedField)) {
  149. const [newFieldName, newFieldConfig] = mappedField;
  150. if (newFieldConfig.astNode != null) {
  151. newFieldConfig.astNode = {
  152. ...newFieldConfig.astNode,
  153. name: {
  154. ...newFieldConfig.astNode.name,
  155. value: newFieldName,
  156. },
  157. };
  158. }
  159. newFieldConfigMap[newFieldName] = newFieldConfig === undefined ? originalFieldConfig : newFieldConfig;
  160. }
  161. else if (mappedField !== null) {
  162. newFieldConfigMap[fieldName] = mappedField;
  163. }
  164. }
  165. if ((0, graphql_1.isObjectType)(originalType)) {
  166. newTypeMap[typeName] = correctASTNodes(new graphql_1.GraphQLObjectType({
  167. ...config,
  168. fields: newFieldConfigMap,
  169. }));
  170. }
  171. else if ((0, graphql_1.isInterfaceType)(originalType)) {
  172. newTypeMap[typeName] = correctASTNodes(new graphql_1.GraphQLInterfaceType({
  173. ...config,
  174. fields: newFieldConfigMap,
  175. }));
  176. }
  177. else {
  178. newTypeMap[typeName] = correctASTNodes(new graphql_1.GraphQLInputObjectType({
  179. ...config,
  180. fields: newFieldConfigMap,
  181. }));
  182. }
  183. }
  184. }
  185. return newTypeMap;
  186. }
  187. function mapArguments(originalTypeMap, schema, schemaMapper) {
  188. const newTypeMap = {};
  189. for (const typeName in originalTypeMap) {
  190. if (!typeName.startsWith('__')) {
  191. const originalType = originalTypeMap[typeName];
  192. if (!(0, graphql_1.isObjectType)(originalType) && !(0, graphql_1.isInterfaceType)(originalType)) {
  193. newTypeMap[typeName] = originalType;
  194. continue;
  195. }
  196. const argumentMapper = getArgumentMapper(schemaMapper);
  197. if (argumentMapper == null) {
  198. newTypeMap[typeName] = originalType;
  199. continue;
  200. }
  201. const config = originalType.toConfig();
  202. const originalFieldConfigMap = config.fields;
  203. const newFieldConfigMap = {};
  204. for (const fieldName in originalFieldConfigMap) {
  205. const originalFieldConfig = originalFieldConfigMap[fieldName];
  206. const originalArgumentConfigMap = originalFieldConfig.args;
  207. if (originalArgumentConfigMap == null) {
  208. newFieldConfigMap[fieldName] = originalFieldConfig;
  209. continue;
  210. }
  211. const argumentNames = Object.keys(originalArgumentConfigMap);
  212. if (!argumentNames.length) {
  213. newFieldConfigMap[fieldName] = originalFieldConfig;
  214. continue;
  215. }
  216. const newArgumentConfigMap = {};
  217. for (const argumentName of argumentNames) {
  218. const originalArgumentConfig = originalArgumentConfigMap[argumentName];
  219. const mappedArgument = argumentMapper(originalArgumentConfig, fieldName, typeName, schema);
  220. if (mappedArgument === undefined) {
  221. newArgumentConfigMap[argumentName] = originalArgumentConfig;
  222. }
  223. else if (Array.isArray(mappedArgument)) {
  224. const [newArgumentName, newArgumentConfig] = mappedArgument;
  225. newArgumentConfigMap[newArgumentName] = newArgumentConfig;
  226. }
  227. else if (mappedArgument !== null) {
  228. newArgumentConfigMap[argumentName] = mappedArgument;
  229. }
  230. }
  231. newFieldConfigMap[fieldName] = {
  232. ...originalFieldConfig,
  233. args: newArgumentConfigMap,
  234. };
  235. }
  236. if ((0, graphql_1.isObjectType)(originalType)) {
  237. newTypeMap[typeName] = new graphql_1.GraphQLObjectType({
  238. ...config,
  239. fields: newFieldConfigMap,
  240. });
  241. }
  242. else if ((0, graphql_1.isInterfaceType)(originalType)) {
  243. newTypeMap[typeName] = new graphql_1.GraphQLInterfaceType({
  244. ...config,
  245. fields: newFieldConfigMap,
  246. });
  247. }
  248. else {
  249. newTypeMap[typeName] = new graphql_1.GraphQLInputObjectType({
  250. ...config,
  251. fields: newFieldConfigMap,
  252. });
  253. }
  254. }
  255. }
  256. return newTypeMap;
  257. }
  258. function mapDirectives(originalDirectives, schema, schemaMapper) {
  259. const directiveMapper = getDirectiveMapper(schemaMapper);
  260. if (directiveMapper == null) {
  261. return originalDirectives.slice();
  262. }
  263. const newDirectives = [];
  264. for (const directive of originalDirectives) {
  265. const mappedDirective = directiveMapper(directive, schema);
  266. if (mappedDirective === undefined) {
  267. newDirectives.push(directive);
  268. }
  269. else if (mappedDirective !== null) {
  270. newDirectives.push(mappedDirective);
  271. }
  272. }
  273. return newDirectives;
  274. }
  275. function getTypeSpecifiers(schema, typeName) {
  276. var _a, _b, _c;
  277. const type = schema.getType(typeName);
  278. const specifiers = [Interfaces_js_1.MapperKind.TYPE];
  279. if ((0, graphql_1.isObjectType)(type)) {
  280. specifiers.push(Interfaces_js_1.MapperKind.COMPOSITE_TYPE, Interfaces_js_1.MapperKind.OBJECT_TYPE);
  281. if (typeName === ((_a = schema.getQueryType()) === null || _a === void 0 ? void 0 : _a.name)) {
  282. specifiers.push(Interfaces_js_1.MapperKind.ROOT_OBJECT, Interfaces_js_1.MapperKind.QUERY);
  283. }
  284. else if (typeName === ((_b = schema.getMutationType()) === null || _b === void 0 ? void 0 : _b.name)) {
  285. specifiers.push(Interfaces_js_1.MapperKind.ROOT_OBJECT, Interfaces_js_1.MapperKind.MUTATION);
  286. }
  287. else if (typeName === ((_c = schema.getSubscriptionType()) === null || _c === void 0 ? void 0 : _c.name)) {
  288. specifiers.push(Interfaces_js_1.MapperKind.ROOT_OBJECT, Interfaces_js_1.MapperKind.SUBSCRIPTION);
  289. }
  290. }
  291. else if ((0, graphql_1.isInputObjectType)(type)) {
  292. specifiers.push(Interfaces_js_1.MapperKind.INPUT_OBJECT_TYPE);
  293. }
  294. else if ((0, graphql_1.isInterfaceType)(type)) {
  295. specifiers.push(Interfaces_js_1.MapperKind.COMPOSITE_TYPE, Interfaces_js_1.MapperKind.ABSTRACT_TYPE, Interfaces_js_1.MapperKind.INTERFACE_TYPE);
  296. }
  297. else if ((0, graphql_1.isUnionType)(type)) {
  298. specifiers.push(Interfaces_js_1.MapperKind.COMPOSITE_TYPE, Interfaces_js_1.MapperKind.ABSTRACT_TYPE, Interfaces_js_1.MapperKind.UNION_TYPE);
  299. }
  300. else if ((0, graphql_1.isEnumType)(type)) {
  301. specifiers.push(Interfaces_js_1.MapperKind.ENUM_TYPE);
  302. }
  303. else if ((0, graphql_1.isScalarType)(type)) {
  304. specifiers.push(Interfaces_js_1.MapperKind.SCALAR_TYPE);
  305. }
  306. return specifiers;
  307. }
  308. function getTypeMapper(schema, schemaMapper, typeName) {
  309. const specifiers = getTypeSpecifiers(schema, typeName);
  310. let typeMapper;
  311. const stack = [...specifiers];
  312. while (!typeMapper && stack.length > 0) {
  313. // It is safe to use the ! operator here as we check the length.
  314. const next = stack.pop();
  315. typeMapper = schemaMapper[next];
  316. }
  317. return typeMapper != null ? typeMapper : null;
  318. }
  319. function getFieldSpecifiers(schema, typeName) {
  320. var _a, _b, _c;
  321. const type = schema.getType(typeName);
  322. const specifiers = [Interfaces_js_1.MapperKind.FIELD];
  323. if ((0, graphql_1.isObjectType)(type)) {
  324. specifiers.push(Interfaces_js_1.MapperKind.COMPOSITE_FIELD, Interfaces_js_1.MapperKind.OBJECT_FIELD);
  325. if (typeName === ((_a = schema.getQueryType()) === null || _a === void 0 ? void 0 : _a.name)) {
  326. specifiers.push(Interfaces_js_1.MapperKind.ROOT_FIELD, Interfaces_js_1.MapperKind.QUERY_ROOT_FIELD);
  327. }
  328. else if (typeName === ((_b = schema.getMutationType()) === null || _b === void 0 ? void 0 : _b.name)) {
  329. specifiers.push(Interfaces_js_1.MapperKind.ROOT_FIELD, Interfaces_js_1.MapperKind.MUTATION_ROOT_FIELD);
  330. }
  331. else if (typeName === ((_c = schema.getSubscriptionType()) === null || _c === void 0 ? void 0 : _c.name)) {
  332. specifiers.push(Interfaces_js_1.MapperKind.ROOT_FIELD, Interfaces_js_1.MapperKind.SUBSCRIPTION_ROOT_FIELD);
  333. }
  334. }
  335. else if ((0, graphql_1.isInterfaceType)(type)) {
  336. specifiers.push(Interfaces_js_1.MapperKind.COMPOSITE_FIELD, Interfaces_js_1.MapperKind.INTERFACE_FIELD);
  337. }
  338. else if ((0, graphql_1.isInputObjectType)(type)) {
  339. specifiers.push(Interfaces_js_1.MapperKind.INPUT_OBJECT_FIELD);
  340. }
  341. return specifiers;
  342. }
  343. function getFieldMapper(schema, schemaMapper, typeName) {
  344. const specifiers = getFieldSpecifiers(schema, typeName);
  345. let fieldMapper;
  346. const stack = [...specifiers];
  347. while (!fieldMapper && stack.length > 0) {
  348. // It is safe to use the ! operator here as we check the length.
  349. const next = stack.pop();
  350. // TODO: fix this as unknown cast
  351. fieldMapper = schemaMapper[next];
  352. }
  353. return fieldMapper !== null && fieldMapper !== void 0 ? fieldMapper : null;
  354. }
  355. function getArgumentMapper(schemaMapper) {
  356. const argumentMapper = schemaMapper[Interfaces_js_1.MapperKind.ARGUMENT];
  357. return argumentMapper != null ? argumentMapper : null;
  358. }
  359. function getDirectiveMapper(schemaMapper) {
  360. const directiveMapper = schemaMapper[Interfaces_js_1.MapperKind.DIRECTIVE];
  361. return directiveMapper != null ? directiveMapper : null;
  362. }
  363. function getEnumValueMapper(schemaMapper) {
  364. const enumValueMapper = schemaMapper[Interfaces_js_1.MapperKind.ENUM_VALUE];
  365. return enumValueMapper != null ? enumValueMapper : null;
  366. }
  367. function correctASTNodes(type) {
  368. if ((0, graphql_1.isObjectType)(type)) {
  369. const config = type.toConfig();
  370. if (config.astNode != null) {
  371. const fields = [];
  372. for (const fieldName in config.fields) {
  373. const fieldConfig = config.fields[fieldName];
  374. if (fieldConfig.astNode != null) {
  375. fields.push(fieldConfig.astNode);
  376. }
  377. }
  378. config.astNode = {
  379. ...config.astNode,
  380. kind: graphql_1.Kind.OBJECT_TYPE_DEFINITION,
  381. fields,
  382. };
  383. }
  384. if (config.extensionASTNodes != null) {
  385. config.extensionASTNodes = config.extensionASTNodes.map(node => ({
  386. ...node,
  387. kind: graphql_1.Kind.OBJECT_TYPE_EXTENSION,
  388. fields: undefined,
  389. }));
  390. }
  391. return new graphql_1.GraphQLObjectType(config);
  392. }
  393. else if ((0, graphql_1.isInterfaceType)(type)) {
  394. const config = type.toConfig();
  395. if (config.astNode != null) {
  396. const fields = [];
  397. for (const fieldName in config.fields) {
  398. const fieldConfig = config.fields[fieldName];
  399. if (fieldConfig.astNode != null) {
  400. fields.push(fieldConfig.astNode);
  401. }
  402. }
  403. config.astNode = {
  404. ...config.astNode,
  405. kind: graphql_1.Kind.INTERFACE_TYPE_DEFINITION,
  406. fields,
  407. };
  408. }
  409. if (config.extensionASTNodes != null) {
  410. config.extensionASTNodes = config.extensionASTNodes.map(node => ({
  411. ...node,
  412. kind: graphql_1.Kind.INTERFACE_TYPE_EXTENSION,
  413. fields: undefined,
  414. }));
  415. }
  416. return new graphql_1.GraphQLInterfaceType(config);
  417. }
  418. else if ((0, graphql_1.isInputObjectType)(type)) {
  419. const config = type.toConfig();
  420. if (config.astNode != null) {
  421. const fields = [];
  422. for (const fieldName in config.fields) {
  423. const fieldConfig = config.fields[fieldName];
  424. if (fieldConfig.astNode != null) {
  425. fields.push(fieldConfig.astNode);
  426. }
  427. }
  428. config.astNode = {
  429. ...config.astNode,
  430. kind: graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION,
  431. fields,
  432. };
  433. }
  434. if (config.extensionASTNodes != null) {
  435. config.extensionASTNodes = config.extensionASTNodes.map(node => ({
  436. ...node,
  437. kind: graphql_1.Kind.INPUT_OBJECT_TYPE_EXTENSION,
  438. fields: undefined,
  439. }));
  440. }
  441. return new graphql_1.GraphQLInputObjectType(config);
  442. }
  443. else if ((0, graphql_1.isEnumType)(type)) {
  444. const config = type.toConfig();
  445. if (config.astNode != null) {
  446. const values = [];
  447. for (const enumKey in config.values) {
  448. const enumValueConfig = config.values[enumKey];
  449. if (enumValueConfig.astNode != null) {
  450. values.push(enumValueConfig.astNode);
  451. }
  452. }
  453. config.astNode = {
  454. ...config.astNode,
  455. values,
  456. };
  457. }
  458. if (config.extensionASTNodes != null) {
  459. config.extensionASTNodes = config.extensionASTNodes.map(node => ({
  460. ...node,
  461. values: undefined,
  462. }));
  463. }
  464. return new graphql_1.GraphQLEnumType(config);
  465. }
  466. else {
  467. return type;
  468. }
  469. }
  470. exports.correctASTNodes = correctASTNodes;