import { colors, htmlEscape } from "./chunk-4L7RY2JA.js"; import { publicDirURL } from "./chunk-OSUFJZHZ.js"; import { BaseComponent } from "./chunk-4YEN7HVQ.js"; // src/templates/error_stack/main.ts import { dump, themes } from "@poppinss/dumper/html"; import { dump as dumpCli } from "@poppinss/dumper/console"; var CHEVIRON = ` `; var EDITORS = { textmate: "txmt://open?url=file://%f&line=%l", macvim: "mvim://open?url=file://%f&line=%l", emacs: "emacs://open?url=file://%f&line=%l", sublime: "subl://open?url=file://%f&line=%l", phpstorm: "phpstorm://open?file=%f&line=%l", atom: "atom://core/open/file?filename=%f&line=%l", vscode: "vscode://file/%f:%l" }; var ErrorStack = class extends BaseComponent { cssFile = new URL("./error_stack/style.css", publicDirURL); scriptFile = new URL("./error_stack/script.js", publicDirURL); /** * Returns the file's relative name from the CWD */ #getRelativeFileName(filePath) { return filePath.replace(`${process.cwd()}/`, ""); } /** * Returns the index of the frame that should be expanded by * default */ #getFirstExpandedFrameIndex(frames) { let expandAtIndex = frames.findIndex((frame) => frame.type === "app"); if (expandAtIndex === -1) { expandAtIndex = frames.findIndex((frame) => frame.type === "module"); } return expandAtIndex; } /** * Returns the link to open the file within known code * editors */ #getEditorLink(ide, frame) { const editorURL = EDITORS[ide] || ide; if (!editorURL || frame.type === "native") { return { text: this.#getRelativeFileName(frame.fileName) }; } return { href: editorURL.replace("%f", frame.fileName).replace("%l", String(frame.lineNumber)), text: this.#getRelativeFileName(frame.fileName) }; } /** * Returns the HTML fragment for the frame location */ #renderFrameLocation(frame, ide) { const { text, href } = this.#getEditorLink(ide, frame); const fileName = ` ${htmlEscape(text)} `; const functionName = frame.functionName ? `in ${htmlEscape(frame.functionName)} ` : ""; const loc = `at line ${frame.lineNumber}:${frame.columnNumber}`; if (frame.type !== "native" && frame.source) { return ``; } return `
${fileName} ${functionName} ${loc}
`; } /** * Returns HTML fragment for the stack frame */ async #renderStackFrame(frame, index, expandAtIndex, props) { const label = frame.type === "app" ? 'In App' : ""; const expandedClass = expandAtIndex === index ? " expanded" : ""; const toggleButton = frame.type !== "native" && frame.source ? `` : ""; return `
  • ${this.#renderFrameLocation(frame, props.ide)}
    ${label} ${toggleButton}
    ${await props.sourceCodeRenderer(props.error, frame)}
  • `; } /** * Returns the ANSI output to print the stack frame on the * terminal */ async #printStackFrame(frame, index, expandAtIndex, props) { const fileName = this.#getRelativeFileName(frame.fileName); const loc = `${fileName}:${frame.lineNumber}:${frame.columnNumber}`; if (index === expandAtIndex) { const functionName2 = frame.functionName ? `at ${frame.functionName} ` : ""; const codeSnippet = await props.sourceCodeRenderer(props.error, frame); return ` \u2043 ${functionName2}${colors.yellow(`(${loc})`)}${codeSnippet}`; } if (frame.type === "native") { const functionName2 = frame.functionName ? `at ${colors.italic(frame.functionName)} ` : ""; return colors.dim(` \u2043 ${functionName2}(${colors.italic(loc)})`); } const functionName = frame.functionName ? `at ${frame.functionName} ` : ""; return ` \u2043 ${functionName}${colors.yellow(`(${loc})`)}`; } /** * The toHTML method is used to output the HTML for the * web view */ async toHTML(props) { const frames = await Promise.all( props.error.frames.map((frame, index) => { return this.#renderStackFrame( frame, index, this.#getFirstExpandedFrameIndex(props.error.frames), props ); }) ); return `

    Stack Trace

      ${frames.join("\n")}
    ${dump(props.error.raw, { styles: themes.cssVariables, expand: true, cspNonce: props.cspNonce, inspectObjectPrototype: false, inspectStaticMembers: false, inspectArrayPrototype: false })}
    `; } /** * The toANSI method is used to output the text for the console */ async toANSI(props) { const displayRaw = process.env.YOUCH_RAW; if (displayRaw) { const depth = Number.isNaN(Number(displayRaw)) ? 2 : Number(displayRaw); return ` ${colors.red("[RAW]")} ${dumpCli(props.error.raw, { depth, inspectObjectPrototype: false, inspectStaticMembers: false, inspectArrayPrototype: false })}`; } const frames = await Promise.all( props.error.frames.map((frame, index) => { return this.#printStackFrame( frame, index, this.#getFirstExpandedFrameIndex(props.error.frames), props ); }) ); return ` ${frames.join("\n")}`; } }; export { ErrorStack };