UNPKG

@platformos/pos-cli

Version:

Manage your platformOS application

204 lines (170 loc) 6.9 kB
"use strict"; var _graphql = require("graphql"); var _codemirror = _interopRequireDefault(require("codemirror")); var _getTypeInfo = _interopRequireDefault(require("./utils/getTypeInfo")); var _SchemaReference = require("./utils/SchemaReference"); require("./utils/info-addon"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Copyright (c) 2019 GraphQL Contributors * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ /** * Registers GraphQL "info" tooltips for CodeMirror. * * When hovering over a token, this presents a tooltip explaining it. * * Options: * * - schema: GraphQLSchema provides positionally relevant info. * - hoverTime: The number of ms to wait before showing info. (Default 500) * - renderDescription: Convert a description to some HTML, Useful since * descriptions are often Markdown formatted. * - onClick: A function called when a named thing is clicked. * */ _codemirror.default.registerHelper('info', 'graphql', (token, options) => { if (!options.schema || !token.state) { return; } const state = token.state; const kind = state.kind; const step = state.step; const typeInfo = (0, _getTypeInfo.default)(options.schema, token.state); // Given a Schema and a Token, produce the contents of an info tooltip. // To do this, create a div element that we will render "into" and then pass // it to various rendering functions. if (kind === 'Field' && step === 0 && typeInfo.fieldDef || kind === 'AliasedField' && step === 2 && typeInfo.fieldDef) { const into = document.createElement('div'); renderField(into, typeInfo, options); renderDescription(into, options, typeInfo.fieldDef); return into; } else if (kind === 'Directive' && step === 1 && typeInfo.directiveDef) { const into = document.createElement('div'); renderDirective(into, typeInfo, options); renderDescription(into, options, typeInfo.directiveDef); return into; } else if (kind === 'Argument' && step === 0 && typeInfo.argDef) { const into = document.createElement('div'); renderArg(into, typeInfo, options); renderDescription(into, options, typeInfo.argDef); return into; } else if (kind === 'EnumValue' && typeInfo.enumValue && typeInfo.enumValue.description) { const into = document.createElement('div'); renderEnumValue(into, typeInfo, options); renderDescription(into, options, typeInfo.enumValue); return into; } else if (kind === 'NamedType' && typeInfo.type && typeInfo.type.description) { const into = document.createElement('div'); renderType(into, typeInfo, options, typeInfo.type); renderDescription(into, options, typeInfo.type); return into; } }); function renderField(into, typeInfo, options) { renderQualifiedField(into, typeInfo, options); renderTypeAnnotation(into, typeInfo, options, typeInfo.type); } function renderQualifiedField(into, typeInfo, options) { const fieldName = typeInfo.fieldDef.name; if (fieldName.slice(0, 2) !== '__') { renderType(into, typeInfo, options, typeInfo.parentType); text(into, '.'); } text(into, fieldName, 'field-name', options, (0, _SchemaReference.getFieldReference)(typeInfo)); } function renderDirective(into, typeInfo, options) { const name = '@' + typeInfo.directiveDef.name; text(into, name, 'directive-name', options, (0, _SchemaReference.getDirectiveReference)(typeInfo)); } function renderArg(into, typeInfo, options) { if (typeInfo.directiveDef) { renderDirective(into, typeInfo, options); } else if (typeInfo.fieldDef) { renderQualifiedField(into, typeInfo, options); } const name = typeInfo.argDef.name; text(into, '('); text(into, name, 'arg-name', options, (0, _SchemaReference.getArgumentReference)(typeInfo)); renderTypeAnnotation(into, typeInfo, options, typeInfo.inputType); text(into, ')'); } function renderTypeAnnotation(into, typeInfo, options, t) { text(into, ': '); renderType(into, typeInfo, options, t); } function renderEnumValue(into, typeInfo, options) { const name = typeInfo.enumValue.name; renderType(into, typeInfo, options, typeInfo.inputType); text(into, '.'); text(into, name, 'enum-value', options, (0, _SchemaReference.getEnumValueReference)(typeInfo)); } function renderType(into, typeInfo, options, t) { if (t instanceof _graphql.GraphQLNonNull) { renderType(into, typeInfo, options, t.ofType); text(into, '!'); } else if (t instanceof _graphql.GraphQLList) { text(into, '['); renderType(into, typeInfo, options, t.ofType); text(into, ']'); } else { text(into, t.name, 'type-name', options, (0, _SchemaReference.getTypeReference)(typeInfo, t)); } } function renderDescription(into, options, def) { const description = def.description; if (description) { const descriptionDiv = document.createElement('div'); descriptionDiv.className = 'info-description'; if (options.renderDescription) { descriptionDiv.innerHTML = options.renderDescription(description); } else { descriptionDiv.appendChild(document.createTextNode(description)); } into.appendChild(descriptionDiv); } renderDeprecation(into, options, def); } function renderDeprecation(into, options, def) { const reason = def.deprecationReason; if (reason) { const deprecationDiv = document.createElement('div'); deprecationDiv.className = 'info-deprecation'; if (options.renderDescription) { deprecationDiv.innerHTML = options.renderDescription(reason); } else { deprecationDiv.appendChild(document.createTextNode(reason)); } const label = document.createElement('span'); label.className = 'info-deprecation-label'; label.appendChild(document.createTextNode('Deprecated: ')); deprecationDiv.insertBefore(label, deprecationDiv.firstChild); into.appendChild(deprecationDiv); } } function text(into, content, className, options = { onClick: null }, ref) { if (className) { const onClick = options.onClick; let node; if (onClick) { node = document.createElement('a'); // Providing a href forces proper a tag behavior, though we don't actually // want clicking the node to navigate anywhere. node.href = 'javascript:void 0'; // eslint-disable-line no-script-url node.addEventListener('click', e => { onClick(ref, e); }); } else { node = document.createElement('span'); } node.className = className; node.appendChild(document.createTextNode(content)); into.appendChild(node); } else { into.appendChild(document.createTextNode(content)); } }