stripIgnoredCharacters.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.stripIgnoredCharacters = stripIgnoredCharacters;
  6. var _inspect = _interopRequireDefault(require("../jsutils/inspect"));
  7. var _source = require("../language/source");
  8. var _tokenKind = require("../language/tokenKind");
  9. var _lexer = require("../language/lexer");
  10. var _blockString = require("../language/blockString");
  11. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  12. /**
  13. * Strips characters that are not significant to the validity or execution
  14. * of a GraphQL document:
  15. * - UnicodeBOM
  16. * - WhiteSpace
  17. * - LineTerminator
  18. * - Comment
  19. * - Comma
  20. * - BlockString indentation
  21. *
  22. * Note: It is required to have a delimiter character between neighboring
  23. * non-punctuator tokens and this function always uses single space as delimiter.
  24. *
  25. * It is guaranteed that both input and output documents if parsed would result
  26. * in the exact same AST except for nodes location.
  27. *
  28. * Warning: It is guaranteed that this function will always produce stable results.
  29. * However, it's not guaranteed that it will stay the same between different
  30. * releases due to bugfixes or changes in the GraphQL specification.
  31. *
  32. * Query example:
  33. *
  34. * query SomeQuery($foo: String!, $bar: String) {
  35. * someField(foo: $foo, bar: $bar) {
  36. * a
  37. * b {
  38. * c
  39. * d
  40. * }
  41. * }
  42. * }
  43. *
  44. * Becomes:
  45. *
  46. * query SomeQuery($foo:String!$bar:String){someField(foo:$foo bar:$bar){a b{c d}}}
  47. *
  48. * SDL example:
  49. *
  50. * """
  51. * Type description
  52. * """
  53. * type Foo {
  54. * """
  55. * Field description
  56. * """
  57. * bar: String
  58. * }
  59. *
  60. * Becomes:
  61. *
  62. * """Type description""" type Foo{"""Field description""" bar:String}
  63. */
  64. function stripIgnoredCharacters(source) {
  65. var sourceObj = typeof source === 'string' ? new _source.Source(source) : source;
  66. if (!(sourceObj instanceof _source.Source)) {
  67. throw new TypeError("Must provide string or Source. Received: ".concat((0, _inspect.default)(sourceObj)));
  68. }
  69. var body = sourceObj.body;
  70. var lexer = (0, _lexer.createLexer)(sourceObj);
  71. var strippedBody = '';
  72. var wasLastAddedTokenNonPunctuator = false;
  73. while (lexer.advance().kind !== _tokenKind.TokenKind.EOF) {
  74. var currentToken = lexer.token;
  75. var tokenKind = currentToken.kind;
  76. /**
  77. * Every two non-punctuator tokens should have space between them.
  78. * Also prevent case of non-punctuator token following by spread resulting
  79. * in invalid token (e.g. `1...` is invalid Float token).
  80. */
  81. var isNonPunctuator = !(0, _lexer.isPunctuatorToken)(currentToken);
  82. if (wasLastAddedTokenNonPunctuator) {
  83. if (isNonPunctuator || currentToken.kind === _tokenKind.TokenKind.SPREAD) {
  84. strippedBody += ' ';
  85. }
  86. }
  87. var tokenBody = body.slice(currentToken.start, currentToken.end);
  88. if (tokenKind === _tokenKind.TokenKind.BLOCK_STRING) {
  89. strippedBody += dedentBlockString(tokenBody);
  90. } else {
  91. strippedBody += tokenBody;
  92. }
  93. wasLastAddedTokenNonPunctuator = isNonPunctuator;
  94. }
  95. return strippedBody;
  96. }
  97. function dedentBlockString(blockStr) {
  98. // skip leading and trailing triple quotations
  99. var rawStr = blockStr.slice(3, -3);
  100. var body = (0, _blockString.dedentBlockStringValue)(rawStr);
  101. var lines = body.split(/\r\n|[\n\r]/g);
  102. if ((0, _blockString.getBlockStringIndentation)(lines) > 0) {
  103. body = '\n' + body;
  104. }
  105. var lastChar = body[body.length - 1];
  106. var hasTrailingQuote = lastChar === '"' && body.slice(-4) !== '\\"""';
  107. if (hasTrailingQuote || lastChar === '\\') {
  108. body += '\n';
  109. }
  110. return '"""' + body + '"""';
  111. }