UNPKG

graphql

Version:

A Query Language and Runtime which can target any service.

1 lines 8.29 kB
{"version":3,"file":"blockString.js","sourceRoot":"","sources":["../../src/language/blockString.ts"],"names":[],"mappings":"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","sourcesContent":["import { isWhiteSpace } from './characterClasses.ts';\n\n/**\n * Produces the value of a block string from its parsed raw value, similar to\n * CoffeeScript's block string, Python's docstring trim or Ruby's strip_heredoc.\n *\n * This implements the GraphQL spec's BlockStringValue() static algorithm.\n *\n * @internal\n */\nexport function dedentBlockStringLines(\n lines: ReadonlyArray<string>,\n): Array<string> {\n let commonIndent = Number.MAX_SAFE_INTEGER;\n let firstNonEmptyLine = null;\n let lastNonEmptyLine = -1;\n\n for (let i = 0; i < lines.length; ++i) {\n const line = lines[i];\n const indent = leadingWhitespace(line);\n\n if (indent === line.length) {\n continue; // skip empty lines\n }\n\n firstNonEmptyLine ??= i;\n lastNonEmptyLine = i;\n\n if (i !== 0 && indent < commonIndent) {\n commonIndent = indent;\n }\n }\n\n return (\n lines\n // Remove common indentation from all lines but first.\n .map((line, i) => (i === 0 ? line : line.slice(commonIndent)))\n // Remove leading and trailing blank lines.\n .slice(firstNonEmptyLine ?? 0, lastNonEmptyLine + 1)\n );\n}\n\nfunction leadingWhitespace(str: string): number {\n let i = 0;\n while (i < str.length && isWhiteSpace(str.charCodeAt(i))) {\n ++i;\n }\n return i;\n}\n\n/** @internal */\nexport function isPrintableAsBlockString(value: string): boolean {\n if (value === '') {\n return true; // empty string is printable\n }\n\n let isEmptyLine = true;\n let hasIndent = false;\n let hasCommonIndent = true;\n let seenNonEmptyLine = false;\n\n for (let i = 0; i < value.length; ++i) {\n switch (value.codePointAt(i)) {\n case 0x0000:\n case 0x0001:\n case 0x0002:\n case 0x0003:\n case 0x0004:\n case 0x0005:\n case 0x0006:\n case 0x0007:\n case 0x0008:\n case 0x000b:\n case 0x000c:\n case 0x000e:\n case 0x000f:\n return false; // Has non-printable characters\n\n case 0x000d: // \\r\n return false; // Has \\r or \\r\\n which will be replaced as \\n\n\n case 10: // \\n\n if (isEmptyLine && !seenNonEmptyLine) {\n return false; // Has leading new line\n }\n seenNonEmptyLine = true;\n\n isEmptyLine = true;\n hasIndent = false;\n break;\n case 9: // \\t\n case 32: // <space>\n hasIndent ||= isEmptyLine;\n break;\n default:\n hasCommonIndent &&= hasIndent;\n isEmptyLine = false;\n }\n }\n\n if (isEmptyLine) {\n return false; // Has trailing empty lines\n }\n\n if (hasCommonIndent && seenNonEmptyLine) {\n return false; // Has internal indent\n }\n\n return true;\n}\n\n/**\n * Print a block string in the indented block form by adding a leading and\n * trailing blank line. However, if a block string starts with whitespace and is\n * a single-line, adding a leading blank line would strip that whitespace.\n *\n * @internal\n */\nexport function printBlockString(\n value: string,\n options?: { minimize?: boolean },\n): string {\n const escapedValue = value.replaceAll('\"\"\"', '\\\\\"\"\"');\n\n // Expand a block string's raw value into independent lines.\n const lines = escapedValue.split(/\\r\\n|[\\n\\r]/g);\n const isSingleLine = lines.length === 1;\n\n // If common indentation is found we can fix some of those cases by adding leading new line\n const forceLeadingNewLine =\n lines.length > 1 &&\n lines\n .slice(1)\n .every((line) => line.length === 0 || isWhiteSpace(line.charCodeAt(0)));\n\n // Trailing triple quotes just looks confusing but doesn't force trailing new line\n const hasTrailingTripleQuotes = escapedValue.endsWith('\\\\\"\"\"');\n\n // Trailing quote (single or double) or slash forces trailing new line\n const hasTrailingQuote = value.endsWith('\"') && !hasTrailingTripleQuotes;\n const hasTrailingSlash = value.endsWith('\\\\');\n const forceTrailingNewline = hasTrailingQuote || hasTrailingSlash;\n\n const printAsMultipleLines =\n !options?.minimize &&\n // add leading and trailing new lines only if it improves readability\n (!isSingleLine ||\n value.length > 70 ||\n forceTrailingNewline ||\n forceLeadingNewLine ||\n hasTrailingTripleQuotes);\n\n let result = '';\n\n // Format a multi-line block quote to account for leading space.\n const skipLeadingNewLine = isSingleLine && isWhiteSpace(value.charCodeAt(0));\n if ((printAsMultipleLines && !skipLeadingNewLine) || forceLeadingNewLine) {\n result += '\\n';\n }\n\n result += escapedValue;\n if (printAsMultipleLines || forceTrailingNewline) {\n result += '\\n';\n }\n\n return '\"\"\"' + result + '\"\"\"';\n}\n"]}