UNPKG

@stryke/json

Version:

A package containing JSON parsing/stringify utilities used by Storm Software.

1 lines 6.16 kB
{"version":3,"file":"code-frames.mjs","names":[],"sources":["../../src/utils/code-frames.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n 🗲 Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\ninterface Location {\n column: number;\n line: number;\n}\n\ninterface NodeLocation {\n end?: Location;\n start?: Location;\n}\n\n// Adapted from https://raw.githubusercontent.com/babel/babel/4108524/packages/babel-code-frame/src/index.js\n\n/**\n * RegExp to test for newlines in terminal.\n */\nconst NEWLINE = /\\r\\n|[\\n\\r\\u2028\\u2029]/;\n\n/**\n * Extract what lines should be marked and highlighted.\n */\nfunction getMarkerLines(\n loc: NodeLocation,\n source: string[],\n opts: { linesAbove?: number; linesBelow?: number } = {}\n): {\n start: number;\n end: number;\n markerLines: Record<number, boolean | [number, number]>;\n} {\n const startLoc: Location = {\n column: 0,\n line: -1,\n ...loc.start\n };\n const endLoc: Location = {\n ...startLoc,\n ...loc.end\n };\n const { linesAbove = 2, linesBelow = 3 } = opts || {};\n const startLine = startLoc.line;\n const startColumn = startLoc.column;\n const endLine = endLoc.line;\n const endColumn = endLoc.column;\n\n let start = Math.max(startLine - (linesAbove + 1), 0);\n let end = Math.min(source.length, endLine + linesBelow);\n\n if (startLine === -1) {\n start = 0;\n }\n\n if (endLine === -1) {\n end = source.length;\n }\n\n const lineDiff = endLine - startLine;\n const markerLines = {} as Record<number, boolean | [number, number]>;\n\n if (lineDiff) {\n for (let i = 0; i <= lineDiff; i++) {\n const lineNumber = i + startLine;\n\n if (!startColumn) {\n markerLines[lineNumber] = true;\n } else if (i === 0) {\n const sourceLength = source[lineNumber - 1]?.length ?? 0;\n\n markerLines[lineNumber] = [startColumn, sourceLength - startColumn + 1];\n } else if (i === lineDiff) {\n markerLines[lineNumber] = [0, endColumn];\n } else {\n const sourceLength = source[lineNumber - i]?.length ?? 0;\n\n markerLines[lineNumber] = [0, sourceLength];\n }\n }\n } else if (startColumn === endColumn) {\n markerLines[startLine] = startColumn ? [startColumn, 0] : true;\n } else {\n markerLines[startLine] = [startColumn, endColumn - startColumn];\n }\n\n return {\n start,\n end,\n markerLines\n };\n}\n\nexport function codeFrameColumns(\n rawLines: string,\n loc: NodeLocation,\n opts: {\n linesAbove?: number;\n linesBelow?: number;\n highlight?: (rawLines: string) => string;\n } = {}\n): string {\n const lines = rawLines.split(NEWLINE);\n const { start, end, markerLines } = getMarkerLines(loc, lines, opts);\n\n const numberMaxWidth = String(end).length;\n const highlightedLines = opts.highlight ? opts.highlight(rawLines) : rawLines;\n\n const frame = highlightedLines\n .split(NEWLINE)\n .slice(start, end)\n .map((line, index) => {\n const number = start + 1 + index;\n const paddedNumber = ` ${number}`.slice(-numberMaxWidth);\n const gutter = ` ${paddedNumber} | `;\n const hasMarker = Boolean(markerLines[number] ?? false);\n if (hasMarker) {\n let markerLine = \"\";\n if (Array.isArray(hasMarker)) {\n const markerSpacing = line\n .slice(0, Math.max(hasMarker[0] - 1, 0))\n .replace(/[^\\t]/g, \" \");\n const numberOfMarkers = hasMarker[1] || 1;\n\n markerLine = [\n \"\\n \",\n gutter.replace(/\\d/g, \" \"),\n markerSpacing,\n \"^\".repeat(numberOfMarkers)\n ].join(\"\");\n }\n return [\">\", gutter, line, markerLine].join(\"\");\n }\n return ` ${gutter}${line}`;\n })\n .join(\"\\n\");\n\n return frame;\n}\n"],"mappings":";;;;AAiCA,MAAM,UAAU;;;;AAKhB,SAAS,eACP,KACA,QACA,OAAqD,EAAE,EAKvD;CACA,MAAM,WAAqB;EACzB,QAAQ;EACR,MAAM;EACN,GAAG,IAAI;EACR;CACD,MAAM,SAAmB;EACvB,GAAG;EACH,GAAG,IAAI;EACR;CACD,MAAM,EAAE,aAAa,GAAG,aAAa,MAAM,QAAQ,EAAE;CACrD,MAAM,YAAY,SAAS;CAC3B,MAAM,cAAc,SAAS;CAC7B,MAAM,UAAU,OAAO;CACvB,MAAM,YAAY,OAAO;CAEzB,IAAI,QAAQ,KAAK,IAAI,aAAa,aAAa,IAAI,EAAE;CACrD,IAAI,MAAM,KAAK,IAAI,OAAO,QAAQ,UAAU,WAAW;AAEvD,KAAI,cAAc,GAChB,SAAQ;AAGV,KAAI,YAAY,GACd,OAAM,OAAO;CAGf,MAAM,WAAW,UAAU;CAC3B,MAAM,cAAc,EAAE;AAEtB,KAAI,SACF,MAAK,IAAI,IAAI,GAAG,KAAK,UAAU,KAAK;EAClC,MAAM,aAAa,IAAI;AAEvB,MAAI,CAAC,YACH,aAAY,cAAc;WACjB,MAAM,EAGf,aAAY,cAAc,CAAC,cAFN,OAAO,aAAa,IAAI,UAAU,KAEA,cAAc,EAAE;WAC9D,MAAM,SACf,aAAY,cAAc,CAAC,GAAG,UAAU;MAIxC,aAAY,cAAc,CAAC,GAFN,OAAO,aAAa,IAAI,UAAU,EAEZ;;UAGtC,gBAAgB,UACzB,aAAY,aAAa,cAAc,CAAC,aAAa,EAAE,GAAG;KAE1D,aAAY,aAAa,CAAC,aAAa,YAAY,YAAY;AAGjE,QAAO;EACL;EACA;EACA;EACD;;AAGH,SAAgB,iBACd,UACA,KACA,OAII,EAAE,EACE;CAER,MAAM,EAAE,OAAO,KAAK,gBAAgB,eAAe,KADrC,SAAS,MAAM,QACgC,EAAE,KAAK;CAEpE,MAAM,iBAAiB,OAAO,IAAI,CAAC;AAgCnC,SA/ByB,KAAK,YAAY,KAAK,UAAU,SAAS,GAAG,UAGlE,MAAM,QAAQ,CACd,MAAM,OAAO,IAAI,CACjB,KAAK,MAAM,UAAU;EACpB,MAAM,SAAS,QAAQ,IAAI;EAE3B,MAAM,SAAS,IADM,IAAI,SAAS,MAAM,CAAC,eACV,CAAC;EAChC,MAAM,YAAY,QAAQ,YAAY,WAAW,MAAM;AACvD,MAAI,WAAW;GACb,IAAI,aAAa;AACjB,OAAI,MAAM,QAAQ,UAAU,EAAE;IAC5B,MAAM,gBAAgB,KACnB,MAAM,GAAG,KAAK,IAAI,UAAU,KAAK,GAAG,EAAE,CAAC,CACvC,QAAQ,UAAU,IAAI;IACzB,MAAM,kBAAkB,UAAU,MAAM;AAExC,iBAAa;KACX;KACA,OAAO,QAAQ,OAAO,IAAI;KAC1B;KACA,IAAI,OAAO,gBAAgB;KAC5B,CAAC,KAAK,GAAG;;AAEZ,UAAO;IAAC;IAAK;IAAQ;IAAM;IAAW,CAAC,KAAK,GAAG;;AAEjD,SAAO,IAAI,SAAS;GACpB,CACD,KAAK,KAEI"}