index.js 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. function getBooleanArgumentValue(info, ast) {
  2. const argument = ast.arguments[0].value;
  3. switch (argument.kind) {
  4. case 'BooleanValue':
  5. return argument.value;
  6. case 'Variable':
  7. return info.variableValues[argument.name.value];
  8. }
  9. }
  10. function isExcludedByDirective(info, ast) {
  11. const directives = ast.directives || [];
  12. let isExcluded = false;
  13. directives.forEach((directive) => {
  14. switch (directive.name.value) {
  15. case 'include':
  16. isExcluded = isExcluded || !getBooleanArgumentValue(info, directive);
  17. break;
  18. case 'skip':
  19. isExcluded = isExcluded || getBooleanArgumentValue(info, directive);
  20. break;
  21. }
  22. });
  23. return isExcluded;
  24. }
  25. function dotConcat(a, b) {
  26. return a ? `${a}.${b}` : b;
  27. }
  28. function getFieldSet(info, asts = info.fieldASTs || info.fieldNodes, prefix = '', maxDepth) {
  29. // for recursion: fragments doesn't have many sets
  30. if (!Array.isArray(asts)) {
  31. asts = [asts];
  32. }
  33. const selections = asts.reduce((selections, source) => {
  34. if (source && source.selectionSet && source.selectionSet.selections) {
  35. selections.push(...source.selectionSet.selections);
  36. }
  37. return selections;
  38. }, []);
  39. return selections.reduce((set, ast) => {
  40. if (isExcludedByDirective(info, ast)) {
  41. return set;
  42. }
  43. switch (ast.kind) {
  44. case 'Field':
  45. const newPrefix = dotConcat(prefix, ast.name.value);
  46. if (ast.selectionSet && maxDepth > 1) {
  47. return Object.assign({}, set, getFieldSet(info, ast, newPrefix, maxDepth - 1));
  48. } else {
  49. set[newPrefix] = true;
  50. return set;
  51. }
  52. case 'InlineFragment':
  53. return Object.assign({}, set, getFieldSet(info, ast, prefix, maxDepth));
  54. case 'FragmentSpread':
  55. return Object.assign({}, set, getFieldSet(info, info.fragments[ast.name.value], prefix, maxDepth));
  56. }
  57. }, {});
  58. }
  59. module.exports = function getFieldList(info, maxDepth = Number.MAX_SAFE_INTEGER) {
  60. return Object.keys(getFieldSet(info, undefined, undefined, maxDepth));
  61. };