UNPKG

nuxi

Version:
1,070 lines (1,069 loc) 35.2 kB
import { t as defineCommand } from "./dist-B03QHgrC.mjs"; import { n as colors } from "./consola.DXBYu-KD-qSGefJ79.mjs"; import "./utils-MaFlCoS1.mjs"; import { a as legacyRootDirArgs, i as extendsArgs, n as dotEnvArgs, o as logLevelArgs, t as cwdArgs } from "./_shared-D6pJgr6t.mjs"; import { c as Se, g as ye, n as logger, o as Me, u as ge } from "./logger-CtlB9piy.mjs"; import { t as defu } from "./defu-C23GdbdT.mjs"; import { t as overrideEnv } from "./env-DUdYa0ce.mjs"; import { a as join, c as resolve } from "./pathe.M-eThtNZ-BfnU2wdd.mjs"; import { r as relativeToProcess, t as loadKit } from "./kit-Bx45zdA5.mjs"; import { i as FastURL, n as serve, t as NodeResponse } from "./node-2KsOo3qw.mjs"; import { n as clearDir } from "./fs-qJl3Qqxr.mjs"; import process from "node:process"; import { promises } from "node:fs"; //#region ../../node_modules/.pnpm/rou3@0.8.1/node_modules/rou3/dist/index.mjs const NullProtoObj = /* @__PURE__ */ (() => { const e = function() {}; return e.prototype = Object.create(null), Object.freeze(e.prototype), e; })(); /** * Create a new router context. */ function createRouter() { return { root: { key: "" }, static: new NullProtoObj() }; } function expandGroupDelimiters(path) { let i = 0; let depth = 0; for (; i < path.length; i++) { const c = path.charCodeAt(i); if (c === 92) { i++; continue; } if (c === 40) { depth++; continue; } if (c === 41 && depth > 0) { depth--; continue; } if (c === 123 && depth === 0) break; } if (i >= path.length) return; let j = i + 1; depth = 0; for (; j < path.length; j++) { const c = path.charCodeAt(j); if (c === 92) { j++; continue; } if (c === 40) { depth++; continue; } if (c === 41 && depth > 0) { depth--; continue; } if (c === 125 && depth === 0) break; } if (j >= path.length) return; const mod = path[j + 1]; const hasMod = mod === "?" || mod === "+" || mod === "*"; const pre = path.slice(0, i); const body = path.slice(i + 1, j); const suf = path.slice(j + (hasMod ? 2 : 1)); if (!hasMod) return [pre + body + suf]; if (mod === "?") return [pre + body + suf, pre + suf]; if (body.includes("/")) throw new Error("unsupported group repetition across segments"); return [`${pre}(?:${body})${mod}${suf}`]; } const UNNAMED_GROUP_PREFIX = "__rou3_unnamed_"; const _unnamedGroupPrefixLength = 15; function hasSegmentWildcard(segment) { let depth = 0; for (let i = 0; i < segment.length; i++) { const ch = segment.charCodeAt(i); if (ch === 92) { i++; continue; } if (ch === 40) { depth++; continue; } if (ch === 41 && depth > 0) { depth--; continue; } if (ch === 42 && depth === 0) return true; } return false; } function replaceSegmentWildcards(segment, unnamedStart, toGroupKey = toUnnamedGroupKey) { let depth = 0; let nextIndex = unnamedStart; let replaced = ""; for (let i = 0; i < segment.length; i++) { const ch = segment.charCodeAt(i); if (ch === 92) { replaced += segment[i]; if (i + 1 < segment.length) replaced += segment[++i]; continue; } if (ch === 40) { depth++; replaced += segment[i]; continue; } if (ch === 41 && depth > 0) { depth--; replaced += segment[i]; continue; } if (ch === 42 && depth === 0) { replaced += `(?<${toGroupKey(nextIndex++)}>[^/]*)`; continue; } replaced += segment[i]; } return [replaced, nextIndex]; } function toUnnamedGroupKey(index) { return `${UNNAMED_GROUP_PREFIX}${index}`; } function normalizeUnnamedGroupKey(key) { return key.startsWith("__rou3_unnamed_") ? key.slice(_unnamedGroupPrefixLength) : key; } function encodeEscapes(path) { return path.replace(/\\:/g, "�A").replace(/\\\(/g, "�B").replace(/\\\)/g, "�C").replace(/\\\{/g, "�D").replace(/\\\}/g, "�E"); } function decodeEscaped(segment) { return segment.replace(/\uFFFD([A-E])/g, (_, c) => c === "A" ? ":" : c === "B" ? "(" : c === "C" ? ")" : c === "D" ? "{" : "}"); } function expandModifiers(segments) { for (let i = 0; i < segments.length; i++) { const m = segments[i].match(/^(.*:[\w-]+(?:\([^)]*\))?)([?+*])$/); if (!m) continue; const pre = segments.slice(0, i); const suf = segments.slice(i + 1); if (m[2] === "?") return ["/" + pre.concat(m[1]).concat(suf).join("/"), "/" + pre.concat(suf).join("/")]; const name = m[1].match(/:([\w-]+)/)?.[1] || "_"; const wc = "/" + [ ...pre, `**:${name}`, ...suf ].join("/"); const without = "/" + [...pre, ...suf].join("/"); return m[2] === "+" ? [wc] : [wc, without]; } } function normalizePath(path) { if (!path.includes("/.")) return path; const r = []; for (const s of path.split("/")) if (s === ".") continue; else if (s === ".." && r.length > 1) r.pop(); else r.push(s); return r.join("/") || "/"; } function splitPath(path) { const [_, ...s] = path.split("/"); return s[s.length - 1] === "" ? s.slice(0, -1) : s; } function getMatchParams(segments, paramsMap) { const params = new NullProtoObj(); for (const [index, name] of paramsMap) { const segment = index < 0 ? segments.slice(-(index + 1)).join("/") : segments[index]; if (typeof name === "string") params[name] = segment; else { const match = segment.match(name); if (match) for (const key in match.groups) params[normalizeUnnamedGroupKey(key)] = match.groups[key]; } } return params; } /** * Add a route to the router context. */ function addRoute(ctx, method = "", path, data) { method = method.toUpperCase(); if (path.charCodeAt(0) !== 47) path = `/${path}`; const groupExpanded = expandGroupDelimiters(path); if (groupExpanded) { for (const expandedPath of groupExpanded) addRoute(ctx, method, expandedPath, data); return; } path = encodeEscapes(path); const segments = splitPath(path); const expanded = expandModifiers(segments); if (expanded) { for (const p of expanded) addRoute(ctx, method, p, data); return; } let node = ctx.root; let _unnamedParamIndex = 0; const paramsMap = []; const paramsRegexp = []; for (let i = 0; i < segments.length; i++) { let segment = segments[i]; if (segment.startsWith("**")) { if (!node.wildcard) node.wildcard = { key: "**" }; node = node.wildcard; paramsMap.push([ -(i + 1), segment.split(":")[1] || "_", segment.length === 2 ]); break; } if (segment === "*" || segment.includes(":") || segment.includes("(") || hasSegmentWildcard(segment)) { if (!node.param) node.param = { key: "*" }; node = node.param; if (segment === "*") paramsMap.push([ i, String(_unnamedParamIndex++), true ]); else if (segment.includes(":", 1) || segment.includes("(") || hasSegmentWildcard(segment) || !/^:[\w-]+$/.test(segment)) { const [regexp, nextIndex] = getParamRegexp(segment, _unnamedParamIndex); _unnamedParamIndex = nextIndex; paramsRegexp[i] = regexp; node.hasRegexParam = true; paramsMap.push([ i, regexp, false ]); } else paramsMap.push([ i, segment.slice(1), false ]); continue; } if (segment === "\\*") segment = segments[i] = "*"; else if (segment === "\\*\\*") segment = segments[i] = "**"; segment = segments[i] = decodeEscaped(segment); const child = node.static?.[segment]; if (child) node = child; else { const staticNode = { key: segment }; if (!node.static) node.static = new NullProtoObj(); node.static[segment] = staticNode; node = staticNode; } } const hasParams = paramsMap.length > 0; if (!node.methods) node.methods = new NullProtoObj(); node.methods[method] ??= []; node.methods[method].push({ data: data || null, paramsRegexp, paramsMap: hasParams ? paramsMap : void 0 }); if (!hasParams) ctx.static["/" + segments.join("/")] = node; } function getParamRegexp(segment, unnamedStart = 0) { let _i = unnamedStart; let _s = "", _d = 0; for (let j = 0; j < segment.length; j++) { const c = segment.charCodeAt(j); if (c === 40) _d++; else if (c === 41 && _d > 0) _d--; else if (c === 92 && _d === 0 && j + 1 < segment.length) { const n = segment[j + 1]; if (n !== ":" && n !== "(" && n !== "*" && n !== "\\") { _s += "￾" + n; j++; continue; } } _s += segment[j]; } [_s, _i] = replaceSegmentWildcards(_s, _i); const regex = _s.replace(/:([\w-]+)(?:\(([^)]*)\))?/g, (_, id, p) => `(?<${id}>${p || "[^/]+"})`).replace(/\((?![?<])/g, () => `(?<${toUnnamedGroupKey(_i++)}>`).replace(/\./g, "\\.").replace(/\uFFFE(.)/g, (_, c) => /[.*+?^${}()|[\]\\]/.test(c) ? `\\${c}` : c); return [new RegExp(`^${regex}$`), _i]; } /** * Find a route by path. */ function findRoute(ctx, method = "", path, opts) { if (opts?.normalize) path = normalizePath(path); if (path.charCodeAt(path.length - 1) === 47) path = path.slice(0, -1); const staticNode = ctx.static[path]; if (staticNode && staticNode.methods) { const staticMatch = staticNode.methods[method] || staticNode.methods[""]; if (staticMatch !== void 0) return staticMatch[0]; } const segments = splitPath(path); const match = _lookupTree(ctx.root, method, segments, 0)?.[0]; if (match === void 0) return; if (opts?.params === false) return match; return { data: match.data, params: match.paramsMap ? getMatchParams(segments, match.paramsMap) : void 0 }; } function _lookupTree(node, method, segments, index) { if (index === segments.length) { if (node.methods) { const match = node.methods[method] || node.methods[""]; if (match) return match; } if (node.param && node.param.methods) { const match = node.param.methods[method] || node.param.methods[""]; if (match) { const pMap = match[0].paramsMap; if (pMap?.[pMap?.length - 1]?.[2]) return match; } } if (node.wildcard && node.wildcard.methods) { const match = node.wildcard.methods[method] || node.wildcard.methods[""]; if (match) { const pMap = match[0].paramsMap; if (pMap?.[pMap?.length - 1]?.[2]) return match; } } return; } const segment = segments[index]; if (node.static) { const staticChild = node.static[segment]; if (staticChild) { const match = _lookupTree(staticChild, method, segments, index + 1); if (match) return match; } } if (node.param) { const match = _lookupTree(node.param, method, segments, index + 1); if (match) { if (node.param.hasRegexParam) { const exactMatch = match.find((m) => m.paramsRegexp[index]?.test(segment)) || match.find((m) => !m.paramsRegexp[index]); return exactMatch ? [exactMatch] : void 0; } return match; } } if (node.wildcard && node.wildcard.methods) return node.wildcard.methods[method] || node.wildcard.methods[""]; } const _P = "￾"; function replaceEscapesOutsideGroups(segment) { let r = "", d = 0; for (let i = 0; i < segment.length; i++) { const c = segment.charCodeAt(i); if (c === 40) d++; else if (c === 41 && d > 0) d--; else if (c === 92 && d === 0 && i + 1 < segment.length) { const n = segment[i + 1]; if (n !== ":" && n !== "(" && n !== "*" && n !== "\\") { r += _P + n; i++; continue; } } r += segment[i]; } return r; } function resolveEscapePlaceholders(str) { return str.replace(/\uFFFE(.)/g, (_, c) => /[.*+?^${}()|[\]\\]/.test(c) ? `\\${c}` : c); } function routeToRegExp(route = "/") { const groupExpanded = expandGroupDelimiters(route); if (groupExpanded) { const sources = groupExpanded.map((expandedRoute) => routeToRegExp(expandedRoute).source.slice(1, -1)); return new RegExp(`^(?:${sources.join("|")})$`); } return _routeToRegExp(route); } function _routeToRegExp(route) { const reSegments = []; let idCtr = 0; for (const segment of route.split("/")) { if (!segment) continue; if (segment === "*") reSegments.push(`(?<${toRegExpUnnamedKey(idCtr++)}>[^/]*)`); else if (segment.startsWith("**")) reSegments.push(segment === "**" ? "?(?<_>.*)" : `?(?<${segment.slice(3)}>.+)`); else if (segment.includes(":") || /(^|[^\\])\(/.test(segment) || hasSegmentWildcard(segment)) { const modMatch = segment.match(/^(.*:[\w-]+(?:\([^)]*\))?)([?+*])$/); if (modMatch) { const [, base, mod] = modMatch; const name = base.match(/:([\w-]+)/)?.[1] || `_${idCtr++}`; if (mod === "?") { const inner = base.replace(/:([\w-]+)(?:\(([^)]*)\))?/g, (_, id, pattern) => `(?<${id}>${pattern || "[^/]+"})`).replace(/\./g, "\\."); if (reSegments.length > 0) { const prevQ = reSegments.pop(); reSegments.push(`${prevQ}(?:/${inner})?`); } else reSegments.push(`?${inner}?`); continue; } const pattern = base.match(/:(\w+)(?:\(([^)]*)\))?/)?.[2]; if (reSegments.length > 0) { const prevMod = reSegments.pop(); if (pattern) { const repeated = `${pattern}(?:/${pattern})*`; reSegments.push(mod === "+" ? `${prevMod}/(?<${name}>${repeated})` : `${prevMod}(?:/(?<${name}>${repeated}))?`); } else reSegments.push(mod === "+" ? `${prevMod}/(?<${name}>.+)` : `${prevMod}(?:/(?<${name}>.*))?`); } else if (pattern) { const repeated = `${pattern}(?:/${pattern})*`; reSegments.push(mod === "+" ? `?(?<${name}>${repeated})` : `?(?<${name}>${repeated})?`); } else reSegments.push(mod === "+" ? `?(?<${name}>.+)` : `?(?<${name}>.*)`); continue; } let dynamicSegment = replaceEscapesOutsideGroups(segment); [dynamicSegment, idCtr] = replaceSegmentWildcards(dynamicSegment, idCtr, toRegExpUnnamedKey); reSegments.push(resolveEscapePlaceholders(dynamicSegment.replace(/:([\w-]+)(?:\(([^)]*)\))?/g, (_, id, pattern) => `(?<${id}>${pattern || "[^/]+"})`).replace(/(^|[^\\])\((?![?<])/g, (_, p) => `${p}(?<${toRegExpUnnamedKey(idCtr++)}>`).replace(/\./g, "\\."))); } else reSegments.push(segment.replace(/\\(.)/g, "$1").replace(/[.*+?^${}()|[\]]/g, "\\$&")); } return new RegExp(`^/${reSegments.join("/")}/?$`); } function toRegExpUnnamedKey(index) { return `_${index}`; } //#endregion //#region ../../node_modules/.pnpm/h3@2.0.1-rc.22_crossws@0.4.5_srvx@0.11.15_/node_modules/h3/dist/h3.mjs function decodePathname(pathname) { return decodeURI(pathname.includes("%25") ? pathname.replace(/%25/g, "%2525") : pathname); } const kEventNS = "h3.internal.event."; const kEventRes = /* @__PURE__ */ Symbol.for(`${kEventNS}res`); const kEventResHeaders = /* @__PURE__ */ Symbol.for(`${kEventNS}res.headers`); const kEventResErrHeaders = /* @__PURE__ */ Symbol.for(`${kEventNS}res.err.headers`); var H3Event = class { app; req; url; context; static __is_event__ = true; constructor(req, context, app) { this.context = context || req.context || new NullProtoObj(); this.req = req; this.app = app; const _url = req._url; const url = _url && _url instanceof URL ? _url : new FastURL(req.url); if (url.pathname.includes("%")) url.pathname = decodePathname(url.pathname); this.url = url; } get res() { return this[kEventRes] ||= new H3EventResponse(); } get runtime() { return this.req.runtime; } waitUntil(promise) { this.req.waitUntil?.(promise); } toString() { return `[${this.req.method}] ${this.req.url}`; } toJSON() { return this.toString(); } get node() { return this.req.runtime?.node; } get headers() { return this.req.headers; } get path() { return this.url.pathname + this.url.search; } get method() { return this.req.method; } }; var H3EventResponse = class { status; statusText; get headers() { return this[kEventResHeaders] ||= new Headers(); } get errHeaders() { return this[kEventResErrHeaders] ||= new Headers(); } }; const DISALLOWED_STATUS_CHARS = /[^\u0009\u0020-\u007E]/g; function sanitizeStatusMessage(statusMessage = "") { return statusMessage.replace(DISALLOWED_STATUS_CHARS, ""); } function sanitizeStatusCode(statusCode, defaultStatusCode = 200) { if (!statusCode) return defaultStatusCode; if (typeof statusCode === "string") statusCode = +statusCode; if (statusCode < 100 || statusCode > 599) return defaultStatusCode; return statusCode; } var HTTPError = class HTTPError extends Error { get name() { return "HTTPError"; } status; statusText; headers; cause; data; body; unhandled; static isError(input) { return input instanceof Error && input?.name === "HTTPError"; } static status(status, statusText, details) { return new HTTPError({ ...details, statusText, status }); } constructor(arg1, arg2) { let messageInput; let details; if (typeof arg1 === "string") { messageInput = arg1; details = arg2; } else details = arg1; const status = sanitizeStatusCode(details?.status || details?.statusCode || (details?.cause)?.status || (details?.cause)?.statusCode, 500); const statusText = sanitizeStatusMessage(details?.statusText || details?.statusMessage || (details?.cause)?.statusText || (details?.cause)?.statusMessage); const message = messageInput || details?.message || (details?.cause)?.message || details?.statusText || details?.statusMessage || [ "HTTPError", status, statusText ].filter(Boolean).join(" "); super(message, { cause: details }); this.cause = details; this.status = status; this.statusText = statusText || void 0; const rawHeaders = details?.headers || (details?.cause)?.headers; this.headers = rawHeaders ? new Headers(rawHeaders) : void 0; this.unhandled = details?.unhandled ?? (details?.cause)?.unhandled ?? void 0; this.data = details?.data; this.body = details?.body; } get statusCode() { return this.status; } get statusMessage() { return this.statusText; } toJSON() { const unhandled = this.unhandled; return { status: this.status, statusText: this.statusText, unhandled, message: unhandled ? "HTTPError" : this.message, data: unhandled ? void 0 : this.data, ...unhandled ? void 0 : this.body }; } }; function isJSONSerializable(value, _type) { if (value === null || value === void 0) return true; if (_type !== "object") return _type === "boolean" || _type === "number" || _type === "string"; if (typeof value.toJSON === "function") return true; if (Array.isArray(value)) return true; if (typeof value.pipe === "function" || typeof value.pipeTo === "function") return false; if (value instanceof NullProtoObj) return true; const proto = Object.getPrototypeOf(value); return proto === Object.prototype || proto === null; } const kNotFound = /* @__PURE__ */ Symbol.for("h3.notFound"); const kHandled = /* @__PURE__ */ Symbol.for("h3.handled"); function toResponse(val, event, config = {}) { if (typeof val?.then === "function") return val.then((resolvedVal) => toResponse(resolvedVal, event, config), (r) => toResponse(typeof r === "number" ? new HTTPError({ status: r }) : r, event, config)); const response = prepareResponse(val, event, config); if (typeof response?.then === "function") return toResponse(response, event, config); const { onResponse } = config; return onResponse ? Promise.resolve(onResponse(response, event)).then(() => response) : response; } var HTTPResponse = class { #headers; #init; body; constructor(body, init) { this.body = body; this.#init = init; } get status() { return this.#init?.status || 200; } get statusText() { return this.#init?.statusText || "OK"; } get headers() { return this.#headers ||= new Headers(this.#init?.headers); } }; function prepareResponse(val, event, config, nested) { if (val === kHandled) return new NodeResponse(null); if (val === kNotFound) val = new HTTPError({ status: 404, message: `Cannot find any route matching [${event.req.method}] ${event.url}` }); if (val && val instanceof Error) { const isHTTPError = HTTPError.isError(val); const error = isHTTPError ? val : new HTTPError(val); if (!isHTTPError) { error.unhandled = true; if (val?.stack) error.stack = val.stack; } if (error.unhandled && !config.silent) console.error(error); const { onError } = config; const errHeaders = event[kEventRes]?.[kEventResErrHeaders]; return onError && !nested ? Promise.resolve(onError(error, event)).catch((error) => error).then((newVal) => prepareResponse(newVal ?? val, event, config, true)) : errorResponse(error, config.debug, errHeaders); } const preparedRes = event[kEventRes]; const preparedHeaders = preparedRes?.[kEventResHeaders]; event[kEventRes] = void 0; if (!(val instanceof Response)) { const res = prepareResponseBody(val, event, config); const status = res.status || preparedRes?.status; return new NodeResponse(nullBody(event.req.method, status) ? null : res.body, { status, statusText: res.statusText || preparedRes?.statusText, headers: res.headers && preparedHeaders ? mergeHeaders$1(res.headers, preparedHeaders) : res.headers || preparedHeaders }); } if (!preparedHeaders || nested || !val.ok) return val; try { mergeHeaders$1(val.headers, preparedHeaders, val.headers); return val; } catch { return new NodeResponse(nullBody(event.req.method, val.status) ? null : val.body, { status: val.status, statusText: val.statusText, headers: mergeHeaders$1(val.headers, preparedHeaders) }); } } function mergeHeaders$1(base, overrides, target = new Headers(base)) { for (const [name, value] of overrides) if (name === "set-cookie") target.append(name, value); else target.set(name, value); return target; } const frozen = (name) => (...args) => { throw new Error(`Headers are frozen (${name} ${args.join(", ")})`); }; var FrozenHeaders = class extends Headers { set = frozen("set"); append = frozen("append"); delete = frozen("delete"); }; const emptyHeaders = /* @__PURE__ */ new FrozenHeaders({ "content-length": "0" }); const jsonHeaders = /* @__PURE__ */ new FrozenHeaders({ "content-type": "application/json;charset=UTF-8" }); function prepareResponseBody(val, event, config) { if (val === null || val === void 0) return { body: "", headers: emptyHeaders }; const valType = typeof val; if (valType === "string") return { body: val }; if (val instanceof Uint8Array) { event.res.headers.set("content-length", val.byteLength.toString()); return { body: val }; } if (val instanceof HTTPResponse || val?.constructor?.name === "HTTPResponse") return val; if (isJSONSerializable(val, valType)) return { body: JSON.stringify(val, void 0, config.debug ? 2 : void 0), headers: jsonHeaders }; if (valType === "bigint") return { body: val.toString(), headers: jsonHeaders }; if (val instanceof Blob) { const headers = new Headers({ "content-type": val.type, "content-length": val.size.toString() }); let filename = val.name; if (filename) { filename = encodeURIComponent(filename); headers.set("content-disposition", `filename="${filename}"; filename*=UTF-8''${filename}`); } return { body: val.stream(), headers }; } if (valType === "symbol") return { body: val.toString() }; if (valType === "function") return { body: `${val.name}()` }; return { body: val }; } function nullBody(method, status) { return method === "HEAD" || status === 100 || status === 101 || status === 102 || status === 204 || status === 205 || status === 304; } function errorResponse(error, debug, errHeaders) { let headers = error.headers ? mergeHeaders$1(jsonHeaders, error.headers) : new Headers(jsonHeaders); if (errHeaders) headers = mergeHeaders$1(headers, errHeaders); return new NodeResponse(JSON.stringify({ ...error.toJSON(), stack: debug && error.stack ? error.stack.split("\n").map((l) => l.trim()) : void 0 }, void 0, debug ? 2 : void 0), { status: error.status, statusText: error.statusText, headers }); } function normalizeMiddleware(input, opts = {}) { const matcher = createMatcher(opts); if (!matcher && (input.length > 1 || input.constructor?.name === "AsyncFunction")) return input; return (event, next) => { if (matcher && !matcher(event)) return next(); const res = input(event, next); return res === void 0 || res === kNotFound ? next() : res; }; } function createMatcher(opts) { if (!opts.route && !opts.method && !opts.match) return; const routeMatcher = opts.route ? routeToRegExp(opts.route) : void 0; const method = opts.method?.toUpperCase(); return function _middlewareMatcher(event) { if (method && event.req.method !== method) return false; if (opts.match && !opts.match(event)) return false; if (!routeMatcher) return true; const match = event.url.pathname.match(routeMatcher); if (!match) return false; if (match.groups) event.context.middlewareParams = { ...event.context.middlewareParams, ...match.groups }; return true; }; } function callMiddleware(event, middleware, handler, index = 0) { if (index === middleware.length) return handler(event); const fn = middleware[index]; let nextCalled; let nextResult; const next = () => { if (nextCalled) return nextResult; nextCalled = true; nextResult = callMiddleware(event, middleware, handler, index + 1); return nextResult; }; const ret = fn(event, next); return isUnhandledResponse(ret) ? next() : typeof ret?.then === "function" ? ret.then((resolved) => isUnhandledResponse(resolved) ? next() : resolved) : ret; } function isUnhandledResponse(val) { return val === void 0 || val === kNotFound; } function requestWithURL(req, url) { const cache = { url }; return new Proxy(req, { get(target, prop) { if (prop in cache) return cache[prop]; const value = Reflect.get(target, prop); cache[prop] = typeof value === "function" ? value.bind(target) : value; return cache[prop]; } }); } function requestWithBaseURL(req, base) { const url = new URL(req.url); url.pathname = decodePathname(url.pathname).slice(base.length) || "/"; return requestWithURL(req, url.href); } function toRequest(input, options) { if (typeof input === "string") { let url = input; if (url[0] === "/") { const headers = options?.headers ? new Headers(options.headers) : void 0; const host = headers?.get("host") || "localhost"; url = `${headers?.get("x-forwarded-proto") === "https" ? "https" : "http"}://${host}${url}`; } return new Request(url, options); } else if (options || input instanceof URL) return new Request(input, options); return input; } function defineHandler(input) { if (typeof input === "function") return handlerWithFetch(input); const handler = input.handler || (input.fetch ? function _fetchHandler(event) { return input.fetch(event.req); } : NoHandler); return Object.assign(handlerWithFetch(input.middleware?.length ? function _handlerMiddleware(event) { return callMiddleware(event, input.middleware, handler); } : handler), input); } function handlerWithFetch(handler) { if ("fetch" in handler) return handler; return Object.assign(handler, { fetch: (req) => { if (typeof req === "string") req = new URL(req, "http://_"); if (req instanceof URL) req = new Request(req); const event = new H3Event(req); try { return Promise.resolve(toResponse(handler(event), event)); } catch (error) { return Promise.resolve(toResponse(error, event)); } } }); } function defineLazyEventHandler(loader) { let handler; let promise; return defineHandler(function lazyHandler(event) { return handler ? handler(event) : (promise ??= Promise.resolve(loader()).then(function resolveLazyHandler(r) { handler = toEventHandler(r) || toEventHandler(r.default); if (typeof handler !== "function") throw new TypeError("Invalid lazy handler", { cause: { resolved: r } }); return handler; })).then((r) => r(event)); }); } function toEventHandler(handler) { if (typeof handler === "function") return handler; if (typeof handler?.handler === "function" && handler.constructor?.["~h3"]) return handler.handler; if (typeof handler?.fetch === "function") return function _fetchHandler(event) { return handler.fetch(event.req); }; } const NoHandler = () => kNotFound; var H3Core = class { static "~h3" = true; config; "~middleware"; "~routes" = []; constructor(config = {}) { this["~middleware"] = []; this.config = config; this.fetch = this.fetch.bind(this); this.handler = this.handler.bind(this); } fetch(request) { return this["~request"](request); } handler(event) { const route = this["~findRoute"](event); if (route) { event.context.params = route.params; event.context.matchedRoute = route.data; } const routeHandler = route?.data.handler || NoHandler; const middleware = this["~getMiddleware"](event, route); return middleware.length > 0 ? callMiddleware(event, middleware, routeHandler) : routeHandler(event); } "~request"(request, context) { const event = new H3Event(request, context, this); let handlerRes; try { if (this.config.onRequest) { const hookRes = this.config.onRequest(event); handlerRes = typeof hookRes?.then === "function" ? hookRes.then(() => this.handler(event)) : this.handler(event); } else handlerRes = this.handler(event); } catch (error) { handlerRes = Promise.reject(error); } return toResponse(handlerRes, event, this.config); } "~findRoute"(_event) {} "~addRoute"(_route) { this["~routes"].push(_route); } "~getMiddleware"(_event, route) { const routeMiddleware = route?.data.middleware; const globalMiddleware = this["~middleware"]; return routeMiddleware ? [...globalMiddleware, ...routeMiddleware] : globalMiddleware; } }; const H3 = /* @__PURE__ */ (() => { class H3 extends H3Core { "~rou3"; constructor(config = {}) { super(config); this["~rou3"] = createRouter(); this.request = this.request.bind(this); config.plugins?.forEach((plugin) => plugin(this)); } register(plugin) { plugin(this); return this; } request(_req, _init, context) { return this["~request"](toRequest(_req, _init), context); } mount(base, input) { if ("handler" in input) { if (input["~middleware"].length > 0) this["~middleware"].push((event, next) => { const originalPathname = event.url.pathname; if (!originalPathname.startsWith(base) || originalPathname.length > base.length && originalPathname[base.length] !== "/") return next(); event.url.pathname = event.url.pathname.slice(base.length) || "/"; return callMiddleware(event, input["~middleware"], () => { event.url.pathname = originalPathname; return next(); }); }); for (const r of input["~routes"]) this["~addRoute"]({ ...r, route: base + r.route }); } else { const fetchHandler = "fetch" in input ? input.fetch : input; this.all(`${base}/**`, function _mountedMiddleware(event) { return fetchHandler(requestWithBaseURL(event.req, base)); }); } return this; } on(method, route, handler, opts) { const _method = (method || "").toUpperCase(); route = new URL(route, "http://_").pathname; this["~addRoute"]({ method: _method, route, handler: toEventHandler(handler), middleware: opts?.middleware, meta: { ...handler.meta, ...opts?.meta } }); return this; } all(route, handler, opts) { return this.on("", route, handler, opts); } "~findRoute"(_event) { return findRoute(this["~rou3"], _event.req.method, _event.url.pathname); } "~addRoute"(_route) { addRoute(this["~rou3"], _route.method, _route.route, _route); super["~addRoute"](_route); } use(arg1, arg2, arg3) { let route; let fn; let opts; if (typeof arg1 === "string") { route = arg1; fn = arg2; opts = arg3; } else { fn = arg1; opts = arg2; } if (typeof fn !== "function" && "handler" in fn) return this.mount(route || "", fn); this["~middleware"].push(normalizeMiddleware(fn, { ...opts, route })); return this; } } for (const method of [ "GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "CONNECT", "TRACE" ]) H3Core.prototype[method.toLowerCase()] = function(route, handler, opts) { return this.on(method, route, handler, opts); }; return H3; })(); const lazyEventHandler = defineLazyEventHandler; //#endregion //#region src/commands/analyze.ts const NON_WORD_RE = /[^\w-]/g; const indexHtml = ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Nuxt Bundle Stats (experimental)</title> </head> <h1>Nuxt Bundle Stats (experimental)</h1> <ul> <li> <a href="/nitro">Nitro server bundle stats</a> </li> <li> <a href="/client">Client bundle stats</a> </li> </ul> </html> `.trim(); var analyze_default = defineCommand({ meta: { name: "analyze", description: "Build Nuxt and analyze production bundle (experimental)" }, args: { ...cwdArgs, ...logLevelArgs, ...legacyRootDirArgs, ...dotEnvArgs, ...extendsArgs, name: { type: "string", description: "Name of the analysis", default: "default", valueHint: "name" }, serve: { type: "boolean", description: "Serve the analysis results", negativeDescription: "Skip serving the analysis results", default: true } }, async run(ctx) { overrideEnv("production"); const cwd = resolve(ctx.args.cwd || ctx.args.rootDir); const name = ctx.args.name || "default"; const slug = name.trim().replace(NON_WORD_RE, "_"); ge(colors.cyan("Analyzing bundle size...")); const startTime = Date.now(); const { loadNuxt, buildNuxt } = await loadKit(cwd); const nuxt = await loadNuxt({ cwd, dotenv: { cwd, fileName: ctx.args.dotenv }, overrides: defu(ctx.data?.overrides, { ...ctx.args.extends && { extends: ctx.args.extends }, build: { analyze: { enabled: true } }, vite: { build: { rollupOptions: { output: { chunkFileNames: "_nuxt/[name].js", entryFileNames: "_nuxt/[name].js" } } } }, logLevel: ctx.args.logLevel }) }); const analyzeDir = nuxt.options.analyzeDir; const buildDir = nuxt.options.buildDir; const outDir = nuxt.options.nitro.output?.dir || join(nuxt.options.rootDir, ".output"); nuxt.options.build.analyze = defu(nuxt.options.build.analyze, { filename: join(analyzeDir, "client.html") }); const tasklog = Me({ title: "Building Nuxt with analysis enabled", retainLog: false, limit: 1 }); tasklog.message("Clearing analyze directory..."); await clearDir(analyzeDir); tasklog.message("Building Nuxt..."); await buildNuxt(nuxt); tasklog.success("Build complete"); const meta = { name, slug, startTime, endTime: Date.now(), analyzeDir, buildDir, outDir }; await nuxt.callHook("build:analyze:done", meta); await promises.writeFile(join(analyzeDir, "meta.json"), JSON.stringify(meta, null, 2), "utf-8"); Se(`${relativeToProcess(analyzeDir)}\n\nDo not deploy analyze results! Use ${colors.cyan("nuxt build")} before deploying.`, "Build location"); if (ctx.args.serve !== false && !process.env.CI) { const app = new H3(); const opts = { headers: { "content-type": "text/html" } }; const serveFile = (filePath) => lazyEventHandler(async () => { const contents = await promises.readFile(filePath, "utf-8"); return () => new Response(contents, opts); }); logger.step("Starting stats server..."); app.use("/client", serveFile(join(analyzeDir, "client.html"))); app.use("/nitro", serveFile(join(analyzeDir, "nitro.html"))); app.use(() => new Response(indexHtml, opts)); await serve(app).serve(); } else ye("✨ Analysis build complete!"); } }); //#endregion export { analyze_default as default };