import { u as toPath } from "../path-BUhlDN52.mjs"; import process from "node:process"; //#region src/presets/env.ts /** Adds a collapsed `Environment` section with runtime and package versions. */ function envPreset(options = {}) { return { plugins: [{ name: "env", transform(report) { if (report.sections.some((section) => section.id === "env")) return; const content = { "runtime": typeof Bun !== "undefined" ? `bun ${Bun.version}` : typeof Deno !== "undefined" ? `deno ${Deno.version.deno}` : `node ${process.versions?.node ?? "unknown"}`, "my-bad": "0.2.11" }; for (const [name, value] of Object.entries(options.versions ?? {})) if (value) content[name] = value; report.sections.push({ id: "env", title: "Environment", content, collapsed: true }); } }] }; } //#endregion //#region src/presets/h3.ts const DEFAULT_REDACT = [ "cookie", "set-cookie", "authorization", "proxy-authorization", "x-api-key" ]; function headerEntries(headers) { if (!headers) return []; if (typeof headers.forEach === "function" && typeof headers.get === "function") { const out = []; headers.forEach((value, key) => out.push([key, value])); return out; } if (Symbol.iterator in new Object(headers)) return [...headers]; return Object.entries(headers).filter((entry) => entry[1] !== void 0).map(([key, value]) => [key, Array.isArray(value) ? value.join(", ") : value]); } /** Extract a request-like object from an h3 v1/v2 event, a Fetch `Request`, or a Node `IncomingMessage`. */ function requestFromContext(context) { const event = context.event; const direct = context.request ?? context.req; if (direct) return direct; if (event?.req && (event.req.headers || event.req.url)) return event.req; if (event?.node?.req) return event.node.req; if (event?.path) return { method: event.method, url: event.path }; } /** Adds `Request` and `Headers` sections from `context.event`, `context.request` or `context.req`. */ function requestPreset(options = {}) { const redact = /* @__PURE__ */ new Set([...DEFAULT_REDACT, ...(options.redact ?? []).map((name) => name.toLowerCase())]); return { plugins: [{ name: "request", transform(report, ctx) { if (report.sections.some((section) => section.id === "request")) return; const request = requestFromContext(ctx.options.context); if (!request) return; const url = request.url ? request.url.startsWith("/") ? request.url : safeUrl(request.url) : void 0; const summary = {}; if (request.method) summary.method = request.method; if (url) summary.url = url; if (report.status) summary.status = report.status; const sections = [{ id: "request", title: "Request", content: summary }]; if (options.headers !== false) { const headers = {}; for (const [key, value] of headerEntries(request.headers)) headers[key.toLowerCase()] = redact.has(key.toLowerCase()) ? "[redacted]" : value; if (Object.keys(headers).length) sections.push({ id: "headers", title: "Headers", content: headers, collapsed: true }); } report.sections.unshift(...sections); } }] }; } function safeUrl(url) { try { const parsed = new URL(url); return `${parsed.pathname}${parsed.search}`; } catch { return url; } } /** Alias of `requestPreset` with Nitro/h3 runtime frames marked internal. */ function nitroPreset(options = {}) { return { ...requestPreset(options), internal: [ /\/node_modules\/(?:nitro|nitropack|h3|nitro-server|@nitro)\//, /^(?:nitro|nitropack|h3|nitro-server|@nitro\/[^/]+)$/, /\/\.output\/server\/(?:chunks\/(?:nitro|_)|index\.mjs)/, /\/\.nitro\// ] }; } //#endregion //#region src/presets/vue.ts const TRACE_LINE_RE = /^\s*at\s+<([^\s>]+)(?:\s[^>]*)?>\s*$/; /** Parse the `trace` string Vue passes to `app.config.warnHandler`. */ function parseVueTrace(trace) { const entries = []; for (const line of trace.split("\n")) { const name = TRACE_LINE_RE.exec(line)?.[1]; if (name) entries.push({ label: `<${name}>` }); } return entries.reverse(); } /** Build a component trace from a Vue component instance (`getCurrentInstance()` or the `instance` argument of `errorHandler`). */ function traceFromInstance(instance) { const entries = []; let current = instance?.$ ?? instance; let guard = 0; while (current && guard++ < 100) { const type = current.type; const file = type?.__file ? toPath(type.__file) : void 0; const name = type?.__name ?? type?.name ?? (file ? file.split(/[\\/]/).pop().replace(/\.\w+$/, "") : "Anonymous"); entries.push({ label: `<${name}>`, ...file && { file } }); current = current.parent; } return entries.reverse(); } /** * Vue support: component traces from `context.instance` or `context.trace`, * Vue runtime frames marked as internal. */ function vuePreset(options = {}) { return { internal: [ /\/node_modules\/(?:@vue|vue)\//, /^(?:vue|@vue\/[^/]+)$/, /\/@vue\/(?:runtime|reactivity|shared|server-renderer|compiler)/, ...options.internal ?? [] ], plugins: [{ name: "vue", transform(report, ctx) { if (report.trace?.length) return; const { instance, trace } = ctx.options.context; const inputTrace = ctx.input?.vueTrace; if (instance) report.trace = traceFromInstance(instance); else if (typeof trace === "string" || typeof inputTrace === "string") report.trace = parseVueTrace(trace ?? inputTrace); if (report.trace && !report.trace.length) delete report.trace; } }] }; } //#endregion //#region src/presets/nuxt.ts const NUXT_CODE_RE = /^(?:NUXT_)?(?[BE]\d{4})$/i; /** * Nuxt support: error codes linked to docs, Nuxt/Nitro/Vue internals collapsed, * request and route sections, and Vue component traces. */ function nuxtPreset(options = {}) { const docsBase = (options.docsBase ?? "https://nuxt.com/docs/errors/").replace(/\/?$/, "/"); const parts = [ vuePreset(), nitroPreset({ redact: options.redact }), envPreset({ versions: options.versions }) ]; return { internal: [ /\/node_modules\/(?:nuxt|@nuxt|nuxt-nightly|@nuxt\/[^/]+|unctx|hookable|ofetch|vue-router)\//, /^(?:nuxt|nuxt-nightly|unctx|hookable|ofetch|vue-router|@nuxt\/[^/]+)$/, /\/\.nuxt\/(?:dev\/|dist\/server\/)/, /#app\//, /^(?:callWithNuxt|applyPlugin|applyPlugins|executeAsync|runWithContext|callAsync|createError|showError)$/, ...parts.flatMap((part) => part.internal ?? []) ], plugins: [...parts.flatMap((part) => part.plugins ?? []), { name: "nuxt", transform(report, ctx) { const visit = (node) => { const code = node.code && !node.docsUrl && !node.diagnostic ? NUXT_CODE_RE.exec(node.code)?.groups?.code : void 0; if (code) node.docsUrl = `${docsBase}${code.toLowerCase()}`; node.causes.forEach(visit); node.errors?.forEach(visit); }; visit(report); const route = ctx.options.context.route; if (route && !report.sections.some((section) => section.id === "route")) { const content = {}; if (route.fullPath ?? route.path) content.path = route.fullPath ?? route.path; if (route.name) content.name = String(route.name); if (route.matched?.length) content.matched = route.matched.map((record) => String(record.name ?? record.path)).join(" › "); const layout = route.meta?.layout; if (layout) content.layout = String(layout); const middleware = route.meta?.middleware; if (Array.isArray(middleware) && middleware.length) content.middleware = middleware.map((item) => typeof item === "string" ? item : item.name ?? "[fn]").join(", "); const index = report.sections.findIndex((section) => section.id === "headers" || section.id === "env"); report.sections.splice(index === -1 ? report.sections.length : index, 0, { id: "route", title: "Route", content }); } } }] }; } const NUXT_LIGHT = [`:root[data-theme='light']`, `:host([data-theme='light'])`]; const inLight = (selector) => NUXT_LIGHT.map((scheme) => `${scheme} ${selector}`).join(","); /** * Nuxt brand for `renderPage` / `renderOverlay`, following https://nuxt.com/design.md: * green accent on neutral surfaces, Outfit headings and Inter body when installed, and * the icon lockup in the header. */ const nuxtTheme = { name: "Nuxt", url: "https://nuxt.com", accent: "#00dc82", vars: { "--mb-bg": "#0a0a0a", "--mb-fg": "#ffffff", "--mb-font-sans": `'Inter', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif`, "--mb-font-display": `'Outfit', var(--mb-font-sans)` }, css: [ `.mb-brand svg{color:var(--mb-accent)}`, `.mb-message{font-weight:500}`, `${NUXT_LIGHT.join(",")}{--mb-fg:#171717;--mb-accent-ink:#007f45;--mb-shadow:0 24px 64px -24px rgb(0 0 0 / 0.2), 0 0 0 1px var(--mb-line)}`, `${inLight(".mb-progress-bar")},${inLight(`.mb-framework[aria-checked='true'] .mb-switch-track`)},${inLight(".mb-live[data-connected]::before")}{background:#00c16a}` ].join("\n"), logo: "" }; //#endregion export { envPreset, requestPreset as h3Preset, requestPreset, nitroPreset, nuxtPreset, nuxtTheme, parseVueTrace, requestFromContext, traceFromInstance, vuePreset };