UNPKG

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