UNPKG

2.89 kBJavaScriptView Raw
1import { Kind, parse, Source as GraphQLSource, visit, isTypeSystemDefinitionNode, print, } from 'graphql';
2import { dedentBlockStringValue, getLeadingCommentBlock } from './comments.js';
3export function parseGraphQLSDL(location, rawSDL, options = {}) {
4 let document;
5 try {
6 if (options.commentDescriptions && rawSDL.includes('#')) {
7 document = transformCommentsToDescriptions(rawSDL, options);
8 // If noLocation=true, we need to make sure to print and parse it again, to remove locations,
9 // since `transformCommentsToDescriptions` must have locations set in order to transform the comments
10 // into descriptions.
11 if (options.noLocation) {
12 document = parse(print(document), options);
13 }
14 }
15 else {
16 document = parse(new GraphQLSource(rawSDL, location), options);
17 }
18 }
19 catch (e) {
20 if (e.message.includes('EOF') && rawSDL.replace(/(\#[^*]*)/g, '').trim() === '') {
21 document = {
22 kind: Kind.DOCUMENT,
23 definitions: [],
24 };
25 }
26 else {
27 throw e;
28 }
29 }
30 return {
31 location,
32 document,
33 };
34}
35export function transformCommentsToDescriptions(sourceSdl, options = {}) {
36 const parsedDoc = parse(sourceSdl, {
37 ...options,
38 noLocation: false,
39 });
40 const modifiedDoc = visit(parsedDoc, {
41 leave: (node) => {
42 if (isDescribable(node)) {
43 const rawValue = getLeadingCommentBlock(node);
44 if (rawValue !== undefined) {
45 const commentsBlock = dedentBlockStringValue('\n' + rawValue);
46 const isBlock = commentsBlock.includes('\n');
47 if (!node.description) {
48 return {
49 ...node,
50 description: {
51 kind: Kind.STRING,
52 value: commentsBlock,
53 block: isBlock,
54 },
55 };
56 }
57 else {
58 return {
59 ...node,
60 description: {
61 ...node.description,
62 value: node.description.value + '\n' + commentsBlock,
63 block: true,
64 },
65 };
66 }
67 }
68 }
69 },
70 });
71 return modifiedDoc;
72}
73export function isDescribable(node) {
74 return (isTypeSystemDefinitionNode(node) ||
75 node.kind === Kind.FIELD_DEFINITION ||
76 node.kind === Kind.INPUT_VALUE_DEFINITION ||
77 node.kind === Kind.ENUM_VALUE_DEFINITION);
78}