| import { visit } from "./visitor.mjs"; |
| import { printBlockString } from "./blockString.mjs"; |
| /** |
| * Converts an AST into a string, using one set of reasonable |
| * formatting rules. |
| */ |
| |
| export function print(ast) { |
| return visit(ast, { |
| leave: printDocASTReducer |
| }); |
| } // TODO: provide better type coverage in future |
| |
| var printDocASTReducer = { |
| Name: function Name(node) { |
| return node.value; |
| }, |
| Variable: function Variable(node) { |
| return '$' + node.name; |
| }, |
| // Document |
| Document: function Document(node) { |
| return join(node.definitions, '\n\n') + '\n'; |
| }, |
| OperationDefinition: function OperationDefinition(node) { |
| var op = node.operation; |
| var name = node.name; |
| var varDefs = wrap('(', join(node.variableDefinitions, ', '), ')'); |
| var directives = join(node.directives, ' '); |
| var selectionSet = node.selectionSet; // Anonymous queries with no directives or variable definitions can use |
| // the query short form. |
| |
| return !name && !directives && !varDefs && op === 'query' ? selectionSet : join([op, join([name, varDefs]), directives, selectionSet], ' '); |
| }, |
| VariableDefinition: function VariableDefinition(_ref) { |
| var variable = _ref.variable, |
| type = _ref.type, |
| defaultValue = _ref.defaultValue, |
| directives = _ref.directives; |
| return variable + ': ' + type + wrap(' = ', defaultValue) + wrap(' ', join(directives, ' ')); |
| }, |
| SelectionSet: function SelectionSet(_ref2) { |
| var selections = _ref2.selections; |
| return block(selections); |
| }, |
| Field: function Field(_ref3) { |
| var alias = _ref3.alias, |
| name = _ref3.name, |
| args = _ref3.arguments, |
| directives = _ref3.directives, |
| selectionSet = _ref3.selectionSet; |
| return join([wrap('', alias, ': ') + name + wrap('(', join(args, ', '), ')'), join(directives, ' '), selectionSet], ' '); |
| }, |
| Argument: function Argument(_ref4) { |
| var name = _ref4.name, |
| value = _ref4.value; |
| return name + ': ' + value; |
| }, |
| // Fragments |
| FragmentSpread: function FragmentSpread(_ref5) { |
| var name = _ref5.name, |
| directives = _ref5.directives; |
| return '...' + name + wrap(' ', join(directives, ' ')); |
| }, |
| InlineFragment: function InlineFragment(_ref6) { |
| var typeCondition = _ref6.typeCondition, |
| directives = _ref6.directives, |
| selectionSet = _ref6.selectionSet; |
| return join(['...', wrap('on ', typeCondition), join(directives, ' '), selectionSet], ' '); |
| }, |
| FragmentDefinition: function FragmentDefinition(_ref7) { |
| var name = _ref7.name, |
| typeCondition = _ref7.typeCondition, |
| variableDefinitions = _ref7.variableDefinitions, |
| directives = _ref7.directives, |
| selectionSet = _ref7.selectionSet; |
| return (// Note: fragment variable definitions are experimental and may be changed |
| // or removed in the future. |
| "fragment ".concat(name).concat(wrap('(', join(variableDefinitions, ', '), ')'), " ") + "on ".concat(typeCondition, " ").concat(wrap('', join(directives, ' '), ' ')) + selectionSet |
| ); |
| }, |
| // Value |
| IntValue: function IntValue(_ref8) { |
| var value = _ref8.value; |
| return value; |
| }, |
| FloatValue: function FloatValue(_ref9) { |
| var value = _ref9.value; |
| return value; |
| }, |
| StringValue: function StringValue(_ref10, key) { |
| var value = _ref10.value, |
| isBlockString = _ref10.block; |
| return isBlockString ? printBlockString(value, key === 'description' ? '' : ' ') : JSON.stringify(value); |
| }, |
| BooleanValue: function BooleanValue(_ref11) { |
| var value = _ref11.value; |
| return value ? 'true' : 'false'; |
| }, |
| NullValue: function NullValue() { |
| return 'null'; |
| }, |
| EnumValue: function EnumValue(_ref12) { |
| var value = _ref12.value; |
| return value; |
| }, |
| ListValue: function ListValue(_ref13) { |
| var values = _ref13.values; |
| return '[' + join(values, ', ') + ']'; |
| }, |
| ObjectValue: function ObjectValue(_ref14) { |
| var fields = _ref14.fields; |
| return '{' + join(fields, ', ') + '}'; |
| }, |
| ObjectField: function ObjectField(_ref15) { |
| var name = _ref15.name, |
| value = _ref15.value; |
| return name + ': ' + value; |
| }, |
| // Directive |
| Directive: function Directive(_ref16) { |
| var name = _ref16.name, |
| args = _ref16.arguments; |
| return '@' + name + wrap('(', join(args, ', '), ')'); |
| }, |
| // Type |
| NamedType: function NamedType(_ref17) { |
| var name = _ref17.name; |
| return name; |
| }, |
| ListType: function ListType(_ref18) { |
| var type = _ref18.type; |
| return '[' + type + ']'; |
| }, |
| NonNullType: function NonNullType(_ref19) { |
| var type = _ref19.type; |
| return type + '!'; |
| }, |
| // Type System Definitions |
| SchemaDefinition: addDescription(function (_ref20) { |
| var directives = _ref20.directives, |
| operationTypes = _ref20.operationTypes; |
| return join(['schema', join(directives, ' '), block(operationTypes)], ' '); |
| }), |
| OperationTypeDefinition: function OperationTypeDefinition(_ref21) { |
| var operation = _ref21.operation, |
| type = _ref21.type; |
| return operation + ': ' + type; |
| }, |
| ScalarTypeDefinition: addDescription(function (_ref22) { |
| var name = _ref22.name, |
| directives = _ref22.directives; |
| return join(['scalar', name, join(directives, ' ')], ' '); |
| }), |
| ObjectTypeDefinition: addDescription(function (_ref23) { |
| var name = _ref23.name, |
| interfaces = _ref23.interfaces, |
| directives = _ref23.directives, |
| fields = _ref23.fields; |
| return join(['type', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '); |
| }), |
| FieldDefinition: addDescription(function (_ref24) { |
| var name = _ref24.name, |
| args = _ref24.arguments, |
| type = _ref24.type, |
| directives = _ref24.directives; |
| return name + (hasMultilineItems(args) ? wrap('(\n', indent(join(args, '\n')), '\n)') : wrap('(', join(args, ', '), ')')) + ': ' + type + wrap(' ', join(directives, ' ')); |
| }), |
| InputValueDefinition: addDescription(function (_ref25) { |
| var name = _ref25.name, |
| type = _ref25.type, |
| defaultValue = _ref25.defaultValue, |
| directives = _ref25.directives; |
| return join([name + ': ' + type, wrap('= ', defaultValue), join(directives, ' ')], ' '); |
| }), |
| InterfaceTypeDefinition: addDescription(function (_ref26) { |
| var name = _ref26.name, |
| interfaces = _ref26.interfaces, |
| directives = _ref26.directives, |
| fields = _ref26.fields; |
| return join(['interface', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '); |
| }), |
| UnionTypeDefinition: addDescription(function (_ref27) { |
| var name = _ref27.name, |
| directives = _ref27.directives, |
| types = _ref27.types; |
| return join(['union', name, join(directives, ' '), types && types.length !== 0 ? '= ' + join(types, ' | ') : ''], ' '); |
| }), |
| EnumTypeDefinition: addDescription(function (_ref28) { |
| var name = _ref28.name, |
| directives = _ref28.directives, |
| values = _ref28.values; |
| return join(['enum', name, join(directives, ' '), block(values)], ' '); |
| }), |
| EnumValueDefinition: addDescription(function (_ref29) { |
| var name = _ref29.name, |
| directives = _ref29.directives; |
| return join([name, join(directives, ' ')], ' '); |
| }), |
| InputObjectTypeDefinition: addDescription(function (_ref30) { |
| var name = _ref30.name, |
| directives = _ref30.directives, |
| fields = _ref30.fields; |
| return join(['input', name, join(directives, ' '), block(fields)], ' '); |
| }), |
| DirectiveDefinition: addDescription(function (_ref31) { |
| var name = _ref31.name, |
| args = _ref31.arguments, |
| repeatable = _ref31.repeatable, |
| locations = _ref31.locations; |
| return 'directive @' + name + (hasMultilineItems(args) ? wrap('(\n', indent(join(args, '\n')), '\n)') : wrap('(', join(args, ', '), ')')) + (repeatable ? ' repeatable' : '') + ' on ' + join(locations, ' | '); |
| }), |
| SchemaExtension: function SchemaExtension(_ref32) { |
| var directives = _ref32.directives, |
| operationTypes = _ref32.operationTypes; |
| return join(['extend schema', join(directives, ' '), block(operationTypes)], ' '); |
| }, |
| ScalarTypeExtension: function ScalarTypeExtension(_ref33) { |
| var name = _ref33.name, |
| directives = _ref33.directives; |
| return join(['extend scalar', name, join(directives, ' ')], ' '); |
| }, |
| ObjectTypeExtension: function ObjectTypeExtension(_ref34) { |
| var name = _ref34.name, |
| interfaces = _ref34.interfaces, |
| directives = _ref34.directives, |
| fields = _ref34.fields; |
| return join(['extend type', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '); |
| }, |
| InterfaceTypeExtension: function InterfaceTypeExtension(_ref35) { |
| var name = _ref35.name, |
| interfaces = _ref35.interfaces, |
| directives = _ref35.directives, |
| fields = _ref35.fields; |
| return join(['extend interface', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '); |
| }, |
| UnionTypeExtension: function UnionTypeExtension(_ref36) { |
| var name = _ref36.name, |
| directives = _ref36.directives, |
| types = _ref36.types; |
| return join(['extend union', name, join(directives, ' '), types && types.length !== 0 ? '= ' + join(types, ' | ') : ''], ' '); |
| }, |
| EnumTypeExtension: function EnumTypeExtension(_ref37) { |
| var name = _ref37.name, |
| directives = _ref37.directives, |
| values = _ref37.values; |
| return join(['extend enum', name, join(directives, ' '), block(values)], ' '); |
| }, |
| InputObjectTypeExtension: function InputObjectTypeExtension(_ref38) { |
| var name = _ref38.name, |
| directives = _ref38.directives, |
| fields = _ref38.fields; |
| return join(['extend input', name, join(directives, ' '), block(fields)], ' '); |
| } |
| }; |
| |
| function addDescription(cb) { |
| return function (node) { |
| return join([node.description, cb(node)], '\n'); |
| }; |
| } |
| /** |
| * Given maybeArray, print an empty string if it is null or empty, otherwise |
| * print all items together separated by separator if provided |
| */ |
| |
| |
| function join(maybeArray) { |
| var _ref39; |
| |
| var separator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; |
| return (_ref39 = maybeArray === null || maybeArray === void 0 ? void 0 : maybeArray.filter(function (x) { |
| return x; |
| }).join(separator)) !== null && _ref39 !== void 0 ? _ref39 : ''; |
| } |
| /** |
| * Given array, print each item on its own line, wrapped in an |
| * indented "{ }" block. |
| */ |
| |
| |
| function block(array) { |
| return array && array.length !== 0 ? '{\n' + indent(join(array, '\n')) + '\n}' : ''; |
| } |
| /** |
| * If maybeString is not null or empty, then wrap with start and end, otherwise |
| * print an empty string. |
| */ |
| |
| |
| function wrap(start, maybeString) { |
| var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; |
| return maybeString ? start + maybeString + end : ''; |
| } |
| |
| function indent(maybeString) { |
| return maybeString && ' ' + maybeString.replace(/\n/g, '\n '); |
| } |
| |
| function isMultiline(string) { |
| return string.indexOf('\n') !== -1; |
| } |
| |
| function hasMultilineItems(maybeArray) { |
| return maybeArray && maybeArray.some(isMultiline); |
| } |