UNPKG

core-types-graphql

Version:
115 lines (114 loc) 3.52 kB
import { ensureArray } from "core-types"; /** * Turns annotations into Markdown comments, which is the standard GraphQL * comment format. */ export function stringifyAnnotations(node, ctx) { const { description, examples, default: _default, comment } = node; const exampleArray = ensureArray(examples); const fullComment = [ description, ...(examples == undefined ? [] : [ formatExamples(exampleArray, ctx) ]), ...(_default === undefined ? [] : [ formatDefault(_default, ctx) ]), ...(ctx.options.includeComment ? [comment] : []), ] .filter(v => v) .join("\n\n") .trim(); return fullComment; } function enquoteCode(code, ctx) { if (code.includes("`")) return code; if (code.includes("\n")) return "```\n" + code + "\n```"; else return "`" + code + "`"; } function formatExamples(examples, ctx) { const lines = examples.map(example => "# example\n" + indent(enquoteCode(example, ctx))) .join("\n") .trim(); return lines; } function formatDefault(_default, ctx) { return `# default\n${indent(enquoteCode(_default, ctx))}`; } function indent(text) { return text .split("\n") .map(line => ` ${line}`) .join("\n"); } export function parseDescription(descriptionText) { descriptionText = (descriptionText && typeof descriptionText === 'object') ? parseString(descriptionText) : descriptionText; if (!descriptionText) return {}; const description = []; const examples = []; const _default = []; let where = 'description'; descriptionText .split("\n") .forEach(line => { if (line.match(/^#+\s*example$/)) { where = 'examples'; examples.push([]); return; } else if (line.match(/^#+\s*default$/)) { where = 'default'; return; } else if (where === 'examples') examples[examples.length - 1].push(line); else if (where === 'default') _default.push(line); else // 'description' description.push(line); }); return { ...(description.length === 0 ? {} : { description: joinUnindentedBlock(description).trim() }), ...(examples.length === 0 ? {} : examples.length === 1 ? { examples: joinUnindentedBlock(examples[0]) } : { examples: examples .map(example => joinUnindentedBlock(example)) }), ...(_default.length === 0 ? {} : { default: joinUnindentedBlock(_default) }), }; } function joinUnindentedBlock(lines) { return unindentEqual(lines).join("\n"); } export function unindentEqual(lines) { if (lines.length === 0 || lines[0].length === 0) return lines; const char = lines[0].charAt(0); if (char !== ' ' && char !== '\t') return lines; const re = new RegExp(`^(${char}+)`); const initial = lines[0].match(re)[1].length; const indent = lines.reduce((prev, cur) => { const m = cur.match(re); if (!m || m[1].length === 0) return 0; return Math.min(prev, m[1].length); }, initial); return lines.map(line => line.slice(indent)); } export function parseString(str) { return str?.value; }