@nuxt/cli
Advanced tools
| import "./logger-B4ge7MhP.mjs"; | ||
| import { t as initialize } from "./dev-CGEtJnLN.mjs"; | ||
| import "./kit-CPEUdXTm.mjs"; | ||
| import "./versions-CTlxnxbH.mjs"; | ||
| import "./banner-drlfl0J-.mjs"; | ||
| import "./fs-B_hD5MnA.mjs"; | ||
| import "./nuxt-Bkosdz43.mjs"; | ||
| export { initialize }; |
| import { i as withNodePath, t as loadKit } from "./kit-CPEUdXTm.mjs"; | ||
| import { r as showVersionsFromConfig } from "./banner-drlfl0J-.mjs"; | ||
| import { t as clearBuildDir } from "./fs-B_hD5MnA.mjs"; | ||
| import { a as writeNuxtManifest, i as resolveNuxtManifest, n as loadNuxtManifest } from "./nuxt-Bkosdz43.mjs"; | ||
| import process from "node:process"; | ||
| import { provider } from "std-env"; | ||
| import { pathToFileURL } from "node:url"; | ||
| import defu, { defu as defu$1 } from "defu"; | ||
| import EventEmitter from "node:events"; | ||
| import { existsSync, readdirSync, statSync, watch } from "node:fs"; | ||
| import { mkdir } from "node:fs/promises"; | ||
| import { resolveModulePath } from "exsolve"; | ||
| import { joinURL } from "ufo"; | ||
| import { listen } from "listhen"; | ||
| import { join, resolve } from "pathe"; | ||
| import { debounce } from "perfect-debounce"; | ||
| import { toNodeHandler } from "srvx/node"; | ||
| import { Youch } from "youch"; | ||
| //#region ../../node_modules/.pnpm/h3@1.15.4/node_modules/h3/dist/index.mjs | ||
| function hasProp(obj, prop) { | ||
| try { | ||
| return prop in obj; | ||
| } catch { | ||
| return false; | ||
| } | ||
| } | ||
| var H3Error = class extends Error { | ||
| static __h3_error__ = true; | ||
| statusCode = 500; | ||
| fatal = false; | ||
| unhandled = false; | ||
| statusMessage; | ||
| data; | ||
| cause; | ||
| constructor(message, opts = {}) { | ||
| super(message, opts); | ||
| if (opts.cause && !this.cause) this.cause = opts.cause; | ||
| } | ||
| toJSON() { | ||
| const obj = { | ||
| message: this.message, | ||
| statusCode: sanitizeStatusCode(this.statusCode, 500) | ||
| }; | ||
| if (this.statusMessage) obj.statusMessage = sanitizeStatusMessage(this.statusMessage); | ||
| if (this.data !== void 0) obj.data = this.data; | ||
| return obj; | ||
| } | ||
| }; | ||
| function createError(input) { | ||
| if (typeof input === "string") return new H3Error(input); | ||
| if (isError(input)) return input; | ||
| const err = new H3Error(input.message ?? input.statusMessage ?? "", { cause: input.cause || input }); | ||
| if (hasProp(input, "stack")) try { | ||
| Object.defineProperty(err, "stack", { get() { | ||
| return input.stack; | ||
| } }); | ||
| } catch { | ||
| try { | ||
| err.stack = input.stack; | ||
| } catch {} | ||
| } | ||
| if (input.data) err.data = input.data; | ||
| if (input.statusCode) err.statusCode = sanitizeStatusCode(input.statusCode, err.statusCode); | ||
| else if (input.status) err.statusCode = sanitizeStatusCode(input.status, err.statusCode); | ||
| if (input.statusMessage) err.statusMessage = input.statusMessage; | ||
| else if (input.statusText) err.statusMessage = input.statusText; | ||
| if (err.statusMessage) { | ||
| const originalMessage = err.statusMessage; | ||
| if (sanitizeStatusMessage(err.statusMessage) !== originalMessage) console.warn("[h3] Please prefer using `message` for longer error messages instead of `statusMessage`. In the future, `statusMessage` will be sanitized by default."); | ||
| } | ||
| if (input.fatal !== void 0) err.fatal = input.fatal; | ||
| if (input.unhandled !== void 0) err.unhandled = input.unhandled; | ||
| return err; | ||
| } | ||
| function sendError(event, error, debug) { | ||
| if (event.handled) return; | ||
| const h3Error = isError(error) ? error : createError(error); | ||
| const responseBody = { | ||
| statusCode: h3Error.statusCode, | ||
| statusMessage: h3Error.statusMessage, | ||
| stack: [], | ||
| data: h3Error.data | ||
| }; | ||
| if (debug) responseBody.stack = (h3Error.stack || "").split("\n").map((l) => l.trim()); | ||
| if (event.handled) return; | ||
| setResponseStatus(event, Number.parseInt(h3Error.statusCode), h3Error.statusMessage); | ||
| event.node.res.setHeader("content-type", MIMES.json); | ||
| event.node.res.end(JSON.stringify(responseBody, void 0, 2)); | ||
| } | ||
| function isError(input) { | ||
| return input?.constructor?.__h3_error__ === true; | ||
| } | ||
| const RawBodySymbol = Symbol.for("h3RawBody"); | ||
| const ParsedBodySymbol = Symbol.for("h3ParsedBody"); | ||
| const MIMES = { | ||
| html: "text/html", | ||
| json: "application/json" | ||
| }; | ||
| 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 = Number.parseInt(statusCode, 10); | ||
| if (statusCode < 100 || statusCode > 999) return defaultStatusCode; | ||
| return statusCode; | ||
| } | ||
| function splitCookiesString(cookiesString) { | ||
| if (Array.isArray(cookiesString)) return cookiesString.flatMap((c) => splitCookiesString(c)); | ||
| if (typeof cookiesString !== "string") return []; | ||
| const cookiesStrings = []; | ||
| let pos = 0; | ||
| let start$1; | ||
| let ch; | ||
| let lastComma; | ||
| let nextStart; | ||
| let cookiesSeparatorFound; | ||
| const skipWhitespace = () => { | ||
| while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos))) pos += 1; | ||
| return pos < cookiesString.length; | ||
| }; | ||
| const notSpecialChar = () => { | ||
| ch = cookiesString.charAt(pos); | ||
| return ch !== "=" && ch !== ";" && ch !== ","; | ||
| }; | ||
| while (pos < cookiesString.length) { | ||
| start$1 = pos; | ||
| cookiesSeparatorFound = false; | ||
| while (skipWhitespace()) { | ||
| ch = cookiesString.charAt(pos); | ||
| if (ch === ",") { | ||
| lastComma = pos; | ||
| pos += 1; | ||
| skipWhitespace(); | ||
| nextStart = pos; | ||
| while (pos < cookiesString.length && notSpecialChar()) pos += 1; | ||
| if (pos < cookiesString.length && cookiesString.charAt(pos) === "=") { | ||
| cookiesSeparatorFound = true; | ||
| pos = nextStart; | ||
| cookiesStrings.push(cookiesString.slice(start$1, lastComma)); | ||
| start$1 = pos; | ||
| } else pos = lastComma + 1; | ||
| } else pos += 1; | ||
| } | ||
| if (!cookiesSeparatorFound || pos >= cookiesString.length) cookiesStrings.push(cookiesString.slice(start$1)); | ||
| } | ||
| return cookiesStrings; | ||
| } | ||
| function setResponseStatus(event, code, text) { | ||
| if (code) event.node.res.statusCode = sanitizeStatusCode(code, event.node.res.statusCode); | ||
| if (text) event.node.res.statusMessage = sanitizeStatusMessage(text); | ||
| } | ||
| function sendStream(event, stream) { | ||
| if (!stream || typeof stream !== "object") throw new Error("[h3] Invalid stream provided."); | ||
| event.node.res._data = stream; | ||
| if (!event.node.res.socket) { | ||
| event._handled = true; | ||
| return Promise.resolve(); | ||
| } | ||
| if (hasProp(stream, "pipeTo") && typeof stream.pipeTo === "function") return stream.pipeTo(new WritableStream({ write(chunk) { | ||
| event.node.res.write(chunk); | ||
| } })).then(() => { | ||
| event.node.res.end(); | ||
| }); | ||
| if (hasProp(stream, "pipe") && typeof stream.pipe === "function") return new Promise((resolve$1, reject) => { | ||
| stream.pipe(event.node.res); | ||
| if (stream.on) { | ||
| stream.on("end", () => { | ||
| event.node.res.end(); | ||
| resolve$1(); | ||
| }); | ||
| stream.on("error", (error) => { | ||
| reject(error); | ||
| }); | ||
| } | ||
| event.node.res.on("close", () => { | ||
| if (stream.abort) stream.abort(); | ||
| }); | ||
| }); | ||
| throw new Error("[h3] Invalid or incompatible stream provided."); | ||
| } | ||
| function sendWebResponse(event, response) { | ||
| for (const [key, value] of response.headers) if (key === "set-cookie") event.node.res.appendHeader(key, splitCookiesString(value)); | ||
| else event.node.res.setHeader(key, value); | ||
| if (response.status) event.node.res.statusCode = sanitizeStatusCode(response.status, event.node.res.statusCode); | ||
| if (response.statusText) event.node.res.statusMessage = sanitizeStatusMessage(response.statusText); | ||
| if (response.redirected) event.node.res.setHeader("location", response.url); | ||
| if (!response.body) { | ||
| event.node.res.end(); | ||
| return; | ||
| } | ||
| return sendStream(event, response.body); | ||
| } | ||
| var H3Event = class { | ||
| "__is_event__" = true; | ||
| node; | ||
| web; | ||
| context = {}; | ||
| _method; | ||
| _path; | ||
| _headers; | ||
| _requestBody; | ||
| _handled = false; | ||
| _onBeforeResponseCalled; | ||
| _onAfterResponseCalled; | ||
| constructor(req, res) { | ||
| this.node = { | ||
| req, | ||
| res | ||
| }; | ||
| } | ||
| get method() { | ||
| if (!this._method) this._method = (this.node.req.method || "GET").toUpperCase(); | ||
| return this._method; | ||
| } | ||
| get path() { | ||
| return this._path || this.node.req.url || "/"; | ||
| } | ||
| get headers() { | ||
| if (!this._headers) this._headers = _normalizeNodeHeaders(this.node.req.headers); | ||
| return this._headers; | ||
| } | ||
| get handled() { | ||
| return this._handled || this.node.res.writableEnded || this.node.res.headersSent; | ||
| } | ||
| respondWith(response) { | ||
| return Promise.resolve(response).then((_response) => sendWebResponse(this, _response)); | ||
| } | ||
| toString() { | ||
| return `[${this.method}] ${this.path}`; | ||
| } | ||
| toJSON() { | ||
| return this.toString(); | ||
| } | ||
| /** @deprecated Please use `event.node.req` instead. */ | ||
| get req() { | ||
| return this.node.req; | ||
| } | ||
| /** @deprecated Please use `event.node.res` instead. */ | ||
| get res() { | ||
| return this.node.res; | ||
| } | ||
| }; | ||
| function createEvent(req, res) { | ||
| return new H3Event(req, res); | ||
| } | ||
| function _normalizeNodeHeaders(nodeHeaders) { | ||
| const headers = new Headers(); | ||
| for (const [name, value] of Object.entries(nodeHeaders)) if (Array.isArray(value)) for (const item of value) headers.append(name, item); | ||
| else if (value) headers.set(name, value); | ||
| return headers; | ||
| } | ||
| const H3Headers = globalThis.Headers; | ||
| const H3Response = globalThis.Response; | ||
| function toNodeListener(app) { | ||
| const toNodeHandle = async function(req, res) { | ||
| const event = createEvent(req, res); | ||
| try { | ||
| await app.handler(event); | ||
| } catch (_error) { | ||
| const error = createError(_error); | ||
| if (!isError(_error)) error.unhandled = true; | ||
| setResponseStatus(event, error.statusCode, error.statusMessage); | ||
| if (app.options.onError) await app.options.onError(error, event); | ||
| if (event.handled) return; | ||
| if (error.unhandled || error.fatal) console.error("[h3]", error.fatal ? "[fatal]" : "[unhandled]", error); | ||
| if (app.options.onBeforeResponse && !event._onBeforeResponseCalled) await app.options.onBeforeResponse(event, { body: error }); | ||
| await sendError(event, error, !!app.options.debug); | ||
| if (app.options.onAfterResponse && !event._onAfterResponseCalled) await app.options.onAfterResponse(event, { body: error }); | ||
| } | ||
| }; | ||
| return toNodeHandle; | ||
| } | ||
| //#endregion | ||
| //#region ../nuxi/src/dev/error.ts | ||
| async function renderError(req, res, error) { | ||
| if (res.headersSent) { | ||
| if (!res.writableEnded) res.end(); | ||
| return; | ||
| } | ||
| const youch = new Youch(); | ||
| res.statusCode = 500; | ||
| res.setHeader("Content-Type", "text/html"); | ||
| res.setHeader("Cache-Control", "no-store"); | ||
| res.setHeader("Refresh", "3"); | ||
| const html = await youch.toHTML(error, { request: { | ||
| url: req.url, | ||
| method: req.method, | ||
| headers: req.headers | ||
| } }); | ||
| res.end(html); | ||
| } | ||
| //#endregion | ||
| //#region ../nuxi/src/dev/utils.ts | ||
| const RESTART_RE = /^(?:nuxt\.config\.[a-z0-9]+|\.nuxtignore|\.nuxtrc|\.config\/nuxt(?:\.config)?\.[a-z0-9]+)$/; | ||
| var FileChangeTracker = class { | ||
| mtimes = /* @__PURE__ */ new Map(); | ||
| shouldEmitChange(filePath) { | ||
| const resolved = resolve(filePath); | ||
| try { | ||
| const currentMtime = statSync(resolved).mtimeMs; | ||
| const lastMtime = this.mtimes.get(resolved); | ||
| this.mtimes.set(resolved, currentMtime); | ||
| return lastMtime === void 0 || currentMtime !== lastMtime; | ||
| } catch { | ||
| this.mtimes.delete(resolved); | ||
| return true; | ||
| } | ||
| } | ||
| prime(filePath, recursive = false) { | ||
| const resolved = resolve(filePath); | ||
| const stat = statSync(resolved); | ||
| this.mtimes.set(resolved, stat.mtimeMs); | ||
| if (stat.isDirectory()) { | ||
| const entries = readdirSync(resolved); | ||
| for (const entry of entries) { | ||
| const fullPath = resolve(resolved, entry); | ||
| try { | ||
| const stats = statSync(fullPath); | ||
| this.mtimes.set(fullPath, stats.mtimeMs); | ||
| if (recursive && stats.isDirectory()) this.prime(fullPath, recursive); | ||
| } catch {} | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| var NuxtDevServer = class extends EventEmitter { | ||
| #handler; | ||
| #distWatcher; | ||
| #configWatcher; | ||
| #currentNuxt; | ||
| #loadingMessage; | ||
| #loadingError; | ||
| #fileChangeTracker = new FileChangeTracker(); | ||
| #cwd; | ||
| #websocketConnections = /* @__PURE__ */ new Set(); | ||
| loadDebounced; | ||
| handler; | ||
| listener; | ||
| constructor(options) { | ||
| super(); | ||
| this.options = options; | ||
| this.loadDebounced = debounce(this.load); | ||
| let _initResolve; | ||
| const _initPromise = new Promise((resolve$1) => { | ||
| _initResolve = resolve$1; | ||
| }); | ||
| this.once("ready", () => { | ||
| _initResolve(); | ||
| }); | ||
| this.#cwd = options.cwd; | ||
| this.handler = async (req, res) => { | ||
| if (this.#loadingError) { | ||
| renderError(req, res, this.#loadingError); | ||
| return; | ||
| } | ||
| await _initPromise; | ||
| if (this.#handler) this.#handler(req, res); | ||
| else this.#renderLoadingScreen(req, res); | ||
| }; | ||
| } | ||
| async #renderLoadingScreen(req, res) { | ||
| if (res.headersSent) { | ||
| if (!res.writableEnded) res.end(); | ||
| return; | ||
| } | ||
| res.statusCode = 503; | ||
| res.setHeader("Content-Type", "text/html"); | ||
| const loadingTemplate = this.options.loadingTemplate || this.#currentNuxt?.options.devServer.loadingTemplate || await resolveLoadingTemplate(this.#cwd); | ||
| res.end(loadingTemplate({ loading: this.#loadingMessage || "Loading..." })); | ||
| } | ||
| async init() { | ||
| this.#loadingMessage = `Starting Nuxt...`; | ||
| this.#handler = void 0; | ||
| this.emit("loading", this.#loadingMessage); | ||
| await this.#loadNuxtInstance(); | ||
| if (this.options.showBanner) showVersionsFromConfig(this.options.cwd, this.#currentNuxt.options); | ||
| await this.#createListener(); | ||
| await this.#initializeNuxt(false); | ||
| this.#watchConfig(); | ||
| } | ||
| closeWatchers() { | ||
| this.#distWatcher?.close(); | ||
| this.#configWatcher?.(); | ||
| } | ||
| async load(reload, reason) { | ||
| try { | ||
| this.closeWatchers(); | ||
| await this.#load(reload, reason); | ||
| this.#loadingError = void 0; | ||
| } catch (error) { | ||
| console.error(`Cannot ${reload ? "restart" : "start"} nuxt: `, error); | ||
| this.#handler = void 0; | ||
| this.#loadingError = error; | ||
| this.#loadingMessage = "Error while loading Nuxt. Please check console and fix errors."; | ||
| this.emit("loading:error", error); | ||
| } | ||
| this.#watchConfig(); | ||
| } | ||
| async #loadNuxtInstance(urls) { | ||
| const kit = await loadKit(this.options.cwd); | ||
| const loadOptions = { | ||
| cwd: this.options.cwd, | ||
| dev: true, | ||
| ready: false, | ||
| envName: this.options.envName, | ||
| dotenv: { | ||
| cwd: this.options.cwd, | ||
| fileName: this.options.dotenv.fileName | ||
| }, | ||
| overrides: { | ||
| logLevel: this.options.logLevel, | ||
| ...this.options.overrides, | ||
| vite: { | ||
| clearScreen: this.options.clear, | ||
| ...this.options.overrides.vite | ||
| } | ||
| } | ||
| }; | ||
| if (urls) { | ||
| const overrides = this.options.listenOverrides || {}; | ||
| const hostname = overrides.hostname; | ||
| const https = overrides.https; | ||
| loadOptions.defaults = resolveDevServerDefaults({ | ||
| hostname, | ||
| https | ||
| }, urls); | ||
| } | ||
| this.#currentNuxt = await kit.loadNuxt(loadOptions); | ||
| } | ||
| async #createListener() { | ||
| if (!this.#currentNuxt) throw new Error("Nuxt must be loaded before creating listener"); | ||
| const listenOptions = this.#resolveListenOptions(); | ||
| this.listener = await listen(this.handler, listenOptions); | ||
| if (listenOptions.public) { | ||
| this.#currentNuxt.options.devServer.cors = { origin: "*" }; | ||
| if (this.#currentNuxt.options.vite?.server) this.#currentNuxt.options.vite.server.allowedHosts = true; | ||
| return; | ||
| } | ||
| const urls = await this.listener.getURLs().then((r) => r.map((r$1) => r$1.url)); | ||
| if (urls && urls.length > 0) this.#currentNuxt.options.vite = defu(this.#currentNuxt.options.vite, { server: { allowedHosts: urls.map((u) => new URL(u).hostname) } }); | ||
| } | ||
| #resolveListenOptions() { | ||
| if (!this.#currentNuxt) throw new Error("Nuxt must be loaded before resolving listen options"); | ||
| const nuxtConfig = this.#currentNuxt.options; | ||
| const overrides = this.options.listenOverrides || {}; | ||
| const port = overrides.port ?? nuxtConfig.devServer?.port; | ||
| const hostname = overrides.hostname ?? nuxtConfig.devServer?.host; | ||
| const isPublic = provider === "codesandbox" || (overrides.public ?? (isPublicHostname(hostname) ? true : void 0)); | ||
| const httpsFromConfig = typeof nuxtConfig.devServer?.https !== "boolean" && nuxtConfig.devServer?.https ? nuxtConfig.devServer.https : {}; | ||
| overrides._https ??= !!nuxtConfig.devServer?.https; | ||
| const httpsOptions = overrides.https && defu(typeof overrides.https === "object" ? overrides.https : {}, httpsFromConfig); | ||
| const baseURL = nuxtConfig.app?.baseURL?.startsWith?.("./") ? nuxtConfig.app.baseURL.slice(1) : nuxtConfig.app?.baseURL; | ||
| return { | ||
| ...overrides, | ||
| port, | ||
| hostname, | ||
| public: isPublic, | ||
| https: httpsOptions || void 0, | ||
| baseURL | ||
| }; | ||
| } | ||
| async #initializeNuxt(reload) { | ||
| if (!this.#currentNuxt) throw new Error("Nuxt must be loaded before configuration"); | ||
| if (!process.env.NUXI_DISABLE_VITE_HMR) this.#currentNuxt.hooks.hook("vite:extend", ({ config }) => { | ||
| if (config.server) config.server.hmr = { | ||
| protocol: void 0, | ||
| ...config.server.hmr, | ||
| port: void 0, | ||
| host: void 0, | ||
| server: this.listener.server | ||
| }; | ||
| }); | ||
| this.#currentNuxt.hooks.hookOnce("close", () => { | ||
| this.#closeWebSocketConnections(); | ||
| this.listener.server.removeAllListeners("upgrade"); | ||
| }); | ||
| if (!reload) { | ||
| const previousManifest = await loadNuxtManifest(this.#currentNuxt.options.buildDir); | ||
| const newManifest = resolveNuxtManifest(this.#currentNuxt); | ||
| const promise = writeNuxtManifest(this.#currentNuxt, newManifest); | ||
| this.#currentNuxt.hooks.hookOnce("ready", async () => { | ||
| await promise; | ||
| }); | ||
| if (previousManifest && newManifest && previousManifest._hash !== newManifest._hash) await clearBuildDir(this.#currentNuxt.options.buildDir); | ||
| } | ||
| await this.#currentNuxt.ready(); | ||
| const unsub = this.#currentNuxt.hooks.hook("restart", async (options) => { | ||
| unsub(); | ||
| if (options?.hard) { | ||
| this.emit("restart"); | ||
| return; | ||
| } | ||
| await this.load(true); | ||
| }); | ||
| if (this.#currentNuxt.server && "upgrade" in this.#currentNuxt.server) this.listener.server.on("upgrade", (req, socket, head) => { | ||
| const nuxt = this.#currentNuxt; | ||
| if (!nuxt || !nuxt.server) return; | ||
| const viteHmrPath = joinURL(nuxt.options.app.baseURL.startsWith("./") ? nuxt.options.app.baseURL.slice(1) : nuxt.options.app.baseURL, nuxt.options.app.buildAssetsDir); | ||
| if (req.url?.startsWith(viteHmrPath)) return; | ||
| nuxt.server.upgrade(req, socket, head); | ||
| this.#websocketConnections.add(socket); | ||
| socket.on("close", () => { | ||
| this.#websocketConnections.delete(socket); | ||
| }); | ||
| }); | ||
| await this.#currentNuxt.hooks.callHook("listen", this.listener.server, this.listener); | ||
| const addr = this.listener.address; | ||
| this.#currentNuxt.options.devServer.host = addr.address; | ||
| this.#currentNuxt.options.devServer.port = addr.port; | ||
| this.#currentNuxt.options.devServer.url = getAddressURL(addr, !!this.listener.https); | ||
| this.#currentNuxt.options.devServer.https = this.listener.https; | ||
| if (this.listener.https && !process.env.NODE_TLS_REJECT_UNAUTHORIZED) console.warn("You might need `NODE_TLS_REJECT_UNAUTHORIZED=0` environment variable to make https work."); | ||
| const kit = await loadKit(this.options.cwd); | ||
| const typesPromise = existsSync(join(this.#currentNuxt.options.buildDir, "tsconfig.json")) ? kit.writeTypes(this.#currentNuxt).catch(console.error) : await kit.writeTypes(this.#currentNuxt).catch(console.error); | ||
| await Promise.all([typesPromise, kit.buildNuxt(this.#currentNuxt)]); | ||
| if (!this.#currentNuxt.server) throw new Error("Nitro server has not been initialized."); | ||
| const distDir = join(this.#currentNuxt.options.buildDir, "dist"); | ||
| await mkdir(distDir, { recursive: true }); | ||
| this.#fileChangeTracker.prime(distDir); | ||
| this.#distWatcher = watch(distDir); | ||
| this.#distWatcher.on("change", (_event, file) => { | ||
| if (!this.#fileChangeTracker.shouldEmitChange(resolve(distDir, file || ""))) return; | ||
| this.loadDebounced(true, ".nuxt/dist directory has been removed"); | ||
| }); | ||
| if ("fetch" in this.#currentNuxt.server) this.#handler = toNodeHandler(this.#currentNuxt.server.fetch); | ||
| else this.#handler = toNodeListener(this.#currentNuxt.server.app); | ||
| const proto = this.listener.https ? "https" : "http"; | ||
| this.emit("ready", `${proto}://127.0.0.1:${addr.port}`); | ||
| } | ||
| async close() { | ||
| if (this.#currentNuxt) await this.#currentNuxt.close(); | ||
| } | ||
| #closeWebSocketConnections() { | ||
| for (const socket of this.#websocketConnections) socket.destroy(); | ||
| this.#websocketConnections.clear(); | ||
| } | ||
| async #load(reload, reason) { | ||
| const action = reload ? "Restarting" : "Starting"; | ||
| this.#loadingMessage = `${reason ? `${reason}. ` : ""}${action} Nuxt...`; | ||
| this.#handler = void 0; | ||
| this.emit("loading", this.#loadingMessage); | ||
| if (reload) console.info(this.#loadingMessage); | ||
| await this.close(); | ||
| const urls = await this.listener.getURLs().then((r) => r.map((r$1) => r$1.url)); | ||
| await this.#loadNuxtInstance(urls); | ||
| await this.#initializeNuxt(!!reload); | ||
| } | ||
| #watchConfig() { | ||
| this.#configWatcher = createConfigWatcher(this.#cwd, this.options.dotenv.fileName, () => this.emit("restart"), (file) => this.loadDebounced(true, `${file} updated`)); | ||
| } | ||
| }; | ||
| function getAddressURL(addr, https) { | ||
| const proto = https ? "https" : "http"; | ||
| let host = addr.address.includes(":") ? `[${addr.address}]` : addr.address; | ||
| if (host === "[::]") host = "localhost"; | ||
| const port = addr.port || 3e3; | ||
| return `${proto}://${host}:${port}/`; | ||
| } | ||
| function resolveDevServerDefaults(listenOptions, urls = []) { | ||
| const defaultConfig = {}; | ||
| if (urls && urls.length > 0) defaultConfig.vite = { server: { allowedHosts: urls.map((u) => new URL(u).hostname) } }; | ||
| if (listenOptions.hostname) { | ||
| defaultConfig.devServer = { cors: { origin: [`${listenOptions.https ? "https" : "http"}://${listenOptions.hostname}`, ...urls] } }; | ||
| defaultConfig.vite = defu(defaultConfig.vite, { server: { allowedHosts: [listenOptions.hostname] } }); | ||
| } | ||
| return defaultConfig; | ||
| } | ||
| function createConfigWatcher(cwd, dotenvFileName = ".env", onRestart, onReload) { | ||
| const fileWatcher = new FileChangeTracker(); | ||
| fileWatcher.prime(cwd); | ||
| const configWatcher = watch(cwd); | ||
| let configDirWatcher = existsSync(join(cwd, ".config")) ? createConfigDirWatcher(cwd, onReload) : void 0; | ||
| const dotenvFileNames = new Set(Array.isArray(dotenvFileName) ? dotenvFileName : [dotenvFileName]); | ||
| configWatcher.on("change", (_event, file) => { | ||
| if (!fileWatcher.shouldEmitChange(resolve(cwd, file))) return; | ||
| if (dotenvFileNames.has(file)) onRestart(); | ||
| if (RESTART_RE.test(file)) onReload(file); | ||
| if (file === ".config") configDirWatcher ||= createConfigDirWatcher(cwd, onReload); | ||
| }); | ||
| return () => { | ||
| configWatcher.close(); | ||
| configDirWatcher?.(); | ||
| }; | ||
| } | ||
| function createConfigDirWatcher(cwd, onReload) { | ||
| const configDir = join(cwd, ".config"); | ||
| const fileWatcher = new FileChangeTracker(); | ||
| fileWatcher.prime(configDir); | ||
| const configDirWatcher = watch(configDir); | ||
| configDirWatcher.on("change", (_event, file) => { | ||
| if (!fileWatcher.shouldEmitChange(resolve(configDir, file))) return; | ||
| if (RESTART_RE.test(file)) onReload(file); | ||
| }); | ||
| return () => configDirWatcher.close(); | ||
| } | ||
| async function resolveLoadingTemplate(cwd) { | ||
| return (await import(pathToFileURL(resolveModulePath("@nuxt/ui-templates", { from: withNodePath(resolveModulePath("nuxt", { | ||
| from: withNodePath(cwd), | ||
| try: true | ||
| }) || cwd) })).href)).loading || ((params) => `<h2>${params.loading}</h2>`); | ||
| } | ||
| function isPublicHostname(hostname) { | ||
| return !!hostname && ![ | ||
| "localhost", | ||
| "127.0.0.1", | ||
| "::1" | ||
| ].includes(hostname); | ||
| } | ||
| //#endregion | ||
| //#region ../nuxi/src/dev/index.ts | ||
| const start = Date.now(); | ||
| process.env.NODE_ENV = "development"; | ||
| var IPC = class { | ||
| enabled = !!process.send && !process.title?.includes("vitest") && process.env.__NUXT__FORK; | ||
| constructor() { | ||
| if (this.enabled) process.once("unhandledRejection", (reason) => { | ||
| this.send({ | ||
| type: "nuxt:internal:dev:rejection", | ||
| message: reason instanceof Error ? reason.toString() : "Unhandled Rejection" | ||
| }); | ||
| process.exit(); | ||
| }); | ||
| process.on("message", (message) => { | ||
| if (message.type === "nuxt:internal:dev:context") initialize(message.context, { listenOverrides: message.listenOverrides }); | ||
| }); | ||
| this.send({ type: "nuxt:internal:dev:fork-ready" }); | ||
| } | ||
| send(message) { | ||
| if (this.enabled) process.send?.(message); | ||
| } | ||
| }; | ||
| const ipc = new IPC(); | ||
| async function initialize(devContext, ctx = {}) { | ||
| const devServer = new NuxtDevServer({ | ||
| cwd: devContext.cwd, | ||
| overrides: defu(ctx.data?.overrides, { extends: devContext.args.extends }), | ||
| logLevel: devContext.args.logLevel, | ||
| clear: devContext.args.clear, | ||
| dotenv: { | ||
| cwd: devContext.cwd, | ||
| fileName: devContext.args.dotenv | ||
| }, | ||
| envName: devContext.args.envName, | ||
| showBanner: ctx.showBanner !== false && !ipc.enabled, | ||
| listenOverrides: ctx.listenOverrides | ||
| }); | ||
| let address; | ||
| if (ipc.enabled) { | ||
| devServer.on("loading:error", (_error) => { | ||
| ipc.send({ | ||
| type: "nuxt:internal:dev:loading:error", | ||
| error: { | ||
| message: _error.message, | ||
| stack: _error.stack, | ||
| name: _error.name, | ||
| code: "code" in _error ? _error.code : void 0 | ||
| } | ||
| }); | ||
| }); | ||
| devServer.on("loading", (message) => { | ||
| ipc.send({ | ||
| type: "nuxt:internal:dev:loading", | ||
| message | ||
| }); | ||
| }); | ||
| devServer.on("restart", () => { | ||
| ipc.send({ type: "nuxt:internal:dev:restart" }); | ||
| }); | ||
| devServer.on("ready", (payload) => { | ||
| ipc.send({ | ||
| type: "nuxt:internal:dev:ready", | ||
| address: payload | ||
| }); | ||
| }); | ||
| } else devServer.on("ready", (payload) => { | ||
| address = payload; | ||
| }); | ||
| await devServer.init(); | ||
| if (process.env.DEBUG) console.debug(`Dev server (internal) initialized in ${Date.now() - start}ms`); | ||
| return { | ||
| listener: devServer.listener, | ||
| close: async () => { | ||
| devServer.closeWatchers(); | ||
| await Promise.all([devServer.listener.close(), devServer.close()]); | ||
| }, | ||
| onReady: (callback) => { | ||
| if (address) callback(address); | ||
| else devServer.once("ready", (payload) => callback(payload)); | ||
| }, | ||
| onRestart: (callback) => { | ||
| let restarted = false; | ||
| function restart() { | ||
| if (!restarted) { | ||
| restarted = true; | ||
| callback(devServer); | ||
| } | ||
| } | ||
| devServer.once("restart", restart); | ||
| process.once("uncaughtException", restart); | ||
| process.once("unhandledRejection", restart); | ||
| } | ||
| }; | ||
| } | ||
| //#endregion | ||
| export { initialize as t }; |
| import { a as legacyRootDirArgs, n as dotEnvArgs, o as logLevelArgs, r as envNameArgs, t as cwdArgs } from "./_shared-BCYCnX0T.mjs"; | ||
| import process from "node:process"; | ||
| import { defineCommand } from "citty"; | ||
| import { isTest } from "std-env"; | ||
| import { resolve } from "pathe"; | ||
| //#region ../nuxi/src/commands/dev-child.ts | ||
| var dev_child_default = defineCommand({ | ||
| meta: { | ||
| name: "_dev", | ||
| description: "Run Nuxt development server (internal command to start child process)" | ||
| }, | ||
| args: { | ||
| ...cwdArgs, | ||
| ...logLevelArgs, | ||
| ...envNameArgs, | ||
| ...dotEnvArgs, | ||
| ...legacyRootDirArgs, | ||
| clear: { | ||
| type: "boolean", | ||
| description: "Clear console on restart", | ||
| negativeDescription: "Disable clear console on restart" | ||
| } | ||
| }, | ||
| async run(ctx) { | ||
| if (!process.send && !isTest) console.warn("`nuxi _dev` is an internal command and should not be used directly. Please use `nuxi dev` instead."); | ||
| const cwd = resolve(ctx.args.cwd || ctx.args.rootDir); | ||
| const { initialize } = await import("./dev-BZKkizyv.mjs"); | ||
| await initialize({ | ||
| cwd, | ||
| args: ctx.args | ||
| }, ctx); | ||
| } | ||
| }); | ||
| //#endregion | ||
| export { dev_child_default as default }; |
| import { a as legacyRootDirArgs, i as extendsArgs, n as dotEnvArgs, o as logLevelArgs, r as envNameArgs, t as cwdArgs } from "./_shared-BCYCnX0T.mjs"; | ||
| import { n as logger, t as debug } from "./logger-B4ge7MhP.mjs"; | ||
| import { t as initialize } from "./dev-CGEtJnLN.mjs"; | ||
| import "./kit-CPEUdXTm.mjs"; | ||
| import "./versions-CTlxnxbH.mjs"; | ||
| import "./banner-drlfl0J-.mjs"; | ||
| import "./fs-B_hD5MnA.mjs"; | ||
| import "./nuxt-Bkosdz43.mjs"; | ||
| import { t as overrideEnv } from "./env-kdrdHqLf.mjs"; | ||
| import process from "node:process"; | ||
| import { defineCommand } from "citty"; | ||
| import { isBun, isDeno, isTest } from "std-env"; | ||
| import { colors } from "consola/utils"; | ||
| import { resolve } from "pathe"; | ||
| import { satisfies } from "semver"; | ||
| import { getArgs, parseArgs } from "listhen/cli"; | ||
| import { fork } from "node:child_process"; | ||
| //#region ../nuxi/src/dev/pool.ts | ||
| var ForkPool = class { | ||
| pool = []; | ||
| poolSize; | ||
| rawArgs; | ||
| listenOverrides; | ||
| warming = false; | ||
| constructor(options) { | ||
| this.rawArgs = options.rawArgs; | ||
| this.poolSize = options.poolSize ?? 2; | ||
| this.listenOverrides = options.listenOverrides; | ||
| for (const signal of [ | ||
| "exit", | ||
| "SIGTERM", | ||
| "SIGINT", | ||
| "SIGQUIT" | ||
| ]) process.once(signal, () => { | ||
| this.killAll(signal === "exit" ? 0 : signal); | ||
| }); | ||
| } | ||
| startWarming() { | ||
| if (this.warming) return; | ||
| this.warming = true; | ||
| for (let i = 0; i < this.poolSize; i++) this.warmFork(); | ||
| } | ||
| async getFork(context, onMessage) { | ||
| const readyFork = this.pool.find((f) => f.state === "ready"); | ||
| if (readyFork) { | ||
| readyFork.state = "active"; | ||
| if (onMessage) this.attachMessageHandler(readyFork.process, onMessage); | ||
| await this.sendContext(readyFork.process, context); | ||
| if (this.warming) this.warmFork(); | ||
| return () => this.killFork(readyFork); | ||
| } | ||
| const warmingFork = this.pool.find((f) => f.state === "warming"); | ||
| if (warmingFork) { | ||
| await warmingFork.ready; | ||
| warmingFork.state = "active"; | ||
| if (onMessage) this.attachMessageHandler(warmingFork.process, onMessage); | ||
| await this.sendContext(warmingFork.process, context); | ||
| if (this.warming) this.warmFork(); | ||
| return () => this.killFork(warmingFork); | ||
| } | ||
| debug("No pre-warmed forks available, starting cold fork"); | ||
| const coldFork = this.createFork(); | ||
| await coldFork.ready; | ||
| coldFork.state = "active"; | ||
| if (onMessage) this.attachMessageHandler(coldFork.process, onMessage); | ||
| await this.sendContext(coldFork.process, context); | ||
| return () => this.killFork(coldFork); | ||
| } | ||
| attachMessageHandler(childProc, onMessage) { | ||
| childProc.on("message", (message) => { | ||
| if (message.type !== "nuxt:internal:dev:fork-ready") onMessage(message); | ||
| }); | ||
| } | ||
| warmFork() { | ||
| const fork$1 = this.createFork(); | ||
| fork$1.ready.then(() => { | ||
| if (fork$1.state === "warming") fork$1.state = "ready"; | ||
| }).catch(() => { | ||
| this.removeFork(fork$1); | ||
| }); | ||
| this.pool.push(fork$1); | ||
| } | ||
| createFork() { | ||
| const childProc = fork(globalThis.__nuxt_cli__.devEntry, this.rawArgs, { | ||
| execArgv: ["--enable-source-maps", process.argv.find((a) => a.includes("--inspect"))].filter(Boolean), | ||
| env: { | ||
| ...process.env, | ||
| __NUXT__FORK: "true" | ||
| } | ||
| }); | ||
| let readyResolve; | ||
| let readyReject; | ||
| const pooledFork = { | ||
| process: childProc, | ||
| ready: new Promise((resolve$1, reject) => { | ||
| readyResolve = resolve$1; | ||
| readyReject = reject; | ||
| }), | ||
| state: "warming" | ||
| }; | ||
| childProc.on("message", (message) => { | ||
| if (message.type === "nuxt:internal:dev:fork-ready") readyResolve(); | ||
| }); | ||
| childProc.on("error", (err) => { | ||
| readyReject(err); | ||
| this.removeFork(pooledFork); | ||
| }); | ||
| childProc.on("close", (errorCode) => { | ||
| if (pooledFork.state === "active" && errorCode) process.exit(errorCode); | ||
| this.removeFork(pooledFork); | ||
| }); | ||
| return pooledFork; | ||
| } | ||
| async sendContext(childProc, context) { | ||
| childProc.send({ | ||
| type: "nuxt:internal:dev:context", | ||
| listenOverrides: this.listenOverrides, | ||
| context | ||
| }); | ||
| } | ||
| killFork(fork$1, signal = "SIGTERM") { | ||
| fork$1.state = "dead"; | ||
| if (fork$1.process) fork$1.process.kill(signal === 0 && isDeno ? "SIGTERM" : signal); | ||
| this.removeFork(fork$1); | ||
| } | ||
| removeFork(fork$1) { | ||
| const index = this.pool.indexOf(fork$1); | ||
| if (index > -1) this.pool.splice(index, 1); | ||
| } | ||
| killAll(signal) { | ||
| for (const fork$1 of this.pool) this.killFork(fork$1, signal); | ||
| } | ||
| getStats() { | ||
| return { | ||
| total: this.pool.length, | ||
| warming: this.pool.filter((f) => f.state === "warming").length, | ||
| ready: this.pool.filter((f) => f.state === "ready").length, | ||
| active: this.pool.filter((f) => f.state === "active").length | ||
| }; | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region ../nuxi/src/commands/dev.ts | ||
| const startTime = Date.now(); | ||
| const forkSupported = !isTest && (!isBun || isBunForkSupported()); | ||
| const listhenArgs = getArgs(); | ||
| const command = defineCommand({ | ||
| meta: { | ||
| name: "dev", | ||
| description: "Run Nuxt development server" | ||
| }, | ||
| args: { | ||
| ...cwdArgs, | ||
| ...logLevelArgs, | ||
| ...dotEnvArgs, | ||
| ...legacyRootDirArgs, | ||
| ...envNameArgs, | ||
| ...extendsArgs, | ||
| clear: { | ||
| type: "boolean", | ||
| description: "Clear console on restart", | ||
| default: false | ||
| }, | ||
| fork: { | ||
| type: "boolean", | ||
| description: forkSupported ? "Disable forked mode" : "Enable forked mode", | ||
| negativeDescription: "Disable forked mode", | ||
| default: forkSupported, | ||
| alias: ["f"] | ||
| }, | ||
| ...listhenArgs, | ||
| port: { | ||
| ...listhenArgs.port, | ||
| description: "Port to listen on (default: `NUXT_PORT || NITRO_PORT || PORT || nuxtOptions.devServer.port`)", | ||
| alias: ["p"] | ||
| }, | ||
| open: { | ||
| ...listhenArgs.open, | ||
| alias: ["o"], | ||
| default: false | ||
| }, | ||
| host: { | ||
| ...listhenArgs.host, | ||
| alias: ["h"], | ||
| description: "Host to listen on (default: `NUXT_HOST || NITRO_HOST || HOST || nuxtOptions.devServer?.host`)" | ||
| }, | ||
| clipboard: { | ||
| ...listhenArgs.clipboard, | ||
| default: false | ||
| }, | ||
| sslCert: { | ||
| type: "string", | ||
| description: "(DEPRECATED) Use `--https.cert` instead." | ||
| }, | ||
| sslKey: { | ||
| type: "string", | ||
| description: "(DEPRECATED) Use `--https.key` instead." | ||
| } | ||
| }, | ||
| async run(ctx) { | ||
| overrideEnv("development"); | ||
| const cwd = resolve(ctx.args.cwd || ctx.args.rootDir); | ||
| const listenOverrides = resolveListenOverrides(ctx.args); | ||
| const { listener, close, onRestart, onReady } = await initialize({ | ||
| cwd, | ||
| args: ctx.args | ||
| }, { | ||
| data: ctx.data, | ||
| listenOverrides, | ||
| showBanner: true | ||
| }); | ||
| if (!ctx.args.fork) return { | ||
| listener, | ||
| close | ||
| }; | ||
| const pool = new ForkPool({ | ||
| rawArgs: ctx.rawArgs, | ||
| poolSize: 2, | ||
| listenOverrides | ||
| }); | ||
| onReady((_address) => { | ||
| pool.startWarming(); | ||
| if (startTime) debug(`Dev server ready for connections in ${Date.now() - startTime}ms`); | ||
| }); | ||
| let cleanupCurrentFork; | ||
| async function restartWithFork() { | ||
| const context = { | ||
| cwd, | ||
| args: ctx.args | ||
| }; | ||
| cleanupCurrentFork?.(); | ||
| cleanupCurrentFork = await pool.getFork(context, (message) => { | ||
| if (message.type === "nuxt:internal:dev:ready") { | ||
| if (startTime) debug(`Dev server ready for connections in ${Date.now() - startTime}ms`); | ||
| } else if (message.type === "nuxt:internal:dev:restart") restartWithFork(); | ||
| else if (message.type === "nuxt:internal:dev:rejection") { | ||
| logger.info(`Restarting Nuxt due to error: ${colors.cyan(message.message)}`); | ||
| restartWithFork(); | ||
| } | ||
| }); | ||
| } | ||
| onRestart(async () => { | ||
| await close(); | ||
| await restartWithFork(); | ||
| }); | ||
| return { async close() { | ||
| cleanupCurrentFork?.(); | ||
| await Promise.all([listener.close(), close()]); | ||
| } }; | ||
| } | ||
| }); | ||
| var dev_default = command; | ||
| function resolveListenOverrides(args) { | ||
| if (process.env._PORT) return { | ||
| port: process.env._PORT || 0, | ||
| hostname: "127.0.0.1", | ||
| showURL: false | ||
| }; | ||
| const options = parseArgs({ | ||
| ...args, | ||
| "host": args.host || process.env.NUXT_HOST || process.env.NITRO_HOST || process.env.HOST, | ||
| "port": args.port || process.env.NUXT_PORT || process.env.NITRO_PORT || process.env.PORT, | ||
| "https": args.https !== false, | ||
| "https.cert": args["https.cert"] || args.sslCert || process.env.NUXT_SSL_CERT || process.env.NITRO_SSL_CERT, | ||
| "https.key": args["https.key"] || args.sslKey || process.env.NUXT_SSL_KEY || process.env.NITRO_SSL_KEY | ||
| }); | ||
| return { | ||
| ...options, | ||
| _https: args.https, | ||
| get https() { | ||
| return this._https ? options.https : false; | ||
| } | ||
| }; | ||
| } | ||
| function isBunForkSupported() { | ||
| const bunVersion = globalThis.Bun.version; | ||
| return satisfies(bunVersion, ">=1.2"); | ||
| } | ||
| //#endregion | ||
| export { dev_default as default }; |
| import { a as legacyRootDirArgs, t as cwdArgs } from "./_shared-BCYCnX0T.mjs"; | ||
| import { n as logger } from "./logger-B4ge7MhP.mjs"; | ||
| import { n as tryResolveNuxt } from "./kit-CPEUdXTm.mjs"; | ||
| import "./versions-CTlxnxbH.mjs"; | ||
| import { t as getBuilder } from "./banner-drlfl0J-.mjs"; | ||
| import { t as formatInfoBox } from "./formatting-PESozNtr.mjs"; | ||
| import { t as getPackageManagerVersion } from "./packageManagers-BX7-V04a.mjs"; | ||
| import process from "node:process"; | ||
| import { defineCommand } from "citty"; | ||
| import { isBun, isDeno, isMinimal } from "std-env"; | ||
| import { colors } from "consola/utils"; | ||
| import { box } from "@clack/prompts"; | ||
| import { resolve } from "pathe"; | ||
| import { readPackageJSON } from "pkg-types"; | ||
| import os from "node:os"; | ||
| import { copy } from "copy-paste"; | ||
| import { detectPackageManager } from "nypm"; | ||
| //#region ../nuxi/package.json | ||
| var version = "3.31.1"; | ||
| //#endregion | ||
| //#region ../nuxi/src/commands/info.ts | ||
| var info_default = defineCommand({ | ||
| meta: { | ||
| name: "info", | ||
| description: "Get information about Nuxt project" | ||
| }, | ||
| args: { | ||
| ...cwdArgs, | ||
| ...legacyRootDirArgs | ||
| }, | ||
| async run(ctx) { | ||
| const cwd = resolve(ctx.args.cwd || ctx.args.rootDir); | ||
| const nuxtConfig = await getNuxtConfig(cwd); | ||
| const { dependencies = {}, devDependencies = {} } = await readPackageJSON(cwd).catch(() => ({})); | ||
| const nuxtPath = tryResolveNuxt(cwd); | ||
| async function getDepVersion(name) { | ||
| for (const url of [cwd, nuxtPath]) { | ||
| if (!url) continue; | ||
| const pkg = await readPackageJSON(name, { url }).catch(() => null); | ||
| if (pkg) return pkg.version; | ||
| } | ||
| return dependencies[name] || devDependencies[name]; | ||
| } | ||
| async function listModules(arr = []) { | ||
| const info = []; | ||
| for (let m of arr) { | ||
| if (Array.isArray(m)) m = m[0]; | ||
| const name = normalizeConfigModule(m, cwd); | ||
| if (name) { | ||
| const v = await getDepVersion(name.split("/").splice(0, 2).join("/")); | ||
| info.push(`\`${v ? `${name}@${v}` : name}\``); | ||
| } | ||
| } | ||
| return info.join(", "); | ||
| } | ||
| const nuxtVersion = await getDepVersion("nuxt") || await getDepVersion("nuxt-nightly") || await getDepVersion("nuxt-edge") || await getDepVersion("nuxt3") || "-"; | ||
| const isLegacy = nuxtVersion.startsWith("2"); | ||
| const builder = !isLegacy ? nuxtConfig.builder || "vite" : nuxtConfig.bridge?.vite ? "vite" : nuxtConfig.buildModules?.includes("nuxt-vite") ? "vite" : "webpack"; | ||
| let packageManager = (await detectPackageManager(cwd))?.name; | ||
| if (packageManager) packageManager += `@${getPackageManagerVersion(packageManager)}`; | ||
| const osType = os.type(); | ||
| const builderInfo = typeof builder === "string" ? getBuilder(cwd, builder) : { | ||
| name: "custom", | ||
| version: "0.0.0" | ||
| }; | ||
| const infoObj = { | ||
| "Operating system": osType === "Darwin" ? `macOS ${os.release()}` : osType === "Windows_NT" ? `Windows ${os.release()}` : `${osType} ${os.release()}`, | ||
| "CPU": `${os.cpus()[0]?.model || "unknown"} (${os.cpus().length} cores)`, | ||
| ...isBun ? { "Bun version": Bun?.version } : isDeno ? { "Deno version": Deno?.version.deno } : { "Node.js version": process.version }, | ||
| "nuxt/cli version": version, | ||
| "Package manager": packageManager ?? "unknown", | ||
| "Nuxt version": nuxtVersion, | ||
| "Nitro version": await getDepVersion("nitropack") || await getDepVersion("nitro"), | ||
| "Builder": builderInfo.name === "custom" ? "custom" : `${builderInfo.name.toLowerCase()}@${builderInfo.version}`, | ||
| "Config": Object.keys(nuxtConfig).map((key) => `\`${key}\``).sort().join(", "), | ||
| "Modules": await listModules(nuxtConfig.modules), | ||
| ...isLegacy ? { "Build modules": await listModules(nuxtConfig.buildModules || []) } : {} | ||
| }; | ||
| logger.info(`Nuxt root directory: ${colors.cyan(nuxtConfig.rootDir || cwd)}\n`); | ||
| const boxStr = formatInfoBox(infoObj); | ||
| let firstColumnLength = 0; | ||
| let secondColumnLength = 0; | ||
| const entries = Object.entries(infoObj).map(([label, val]) => { | ||
| if (label.length > firstColumnLength) firstColumnLength = label.length + 4; | ||
| if ((val || "").length > secondColumnLength) secondColumnLength = (val || "").length + 2; | ||
| return [label, val || "-"]; | ||
| }); | ||
| let copyStr = `| ${" ".repeat(firstColumnLength)} | ${" ".repeat(secondColumnLength)} |\n| ${"-".repeat(firstColumnLength)} | ${"-".repeat(secondColumnLength)} |\n`; | ||
| for (const [label, value] of entries) if (!isMinimal) copyStr += `| ${`**${label}**`.padEnd(firstColumnLength)} | ${(value.includes("`") ? value : `\`${value}\``).padEnd(secondColumnLength)} |\n`; | ||
| const copied = !isMinimal && await new Promise((resolve$1) => copy(copyStr, (err) => resolve$1(!err))); | ||
| box(`\n${boxStr}`, ` Nuxt project info ${copied ? colors.gray("(copied to clipboard) ") : ""}`, { | ||
| contentAlign: "left", | ||
| titleAlign: "left", | ||
| width: "auto", | ||
| titlePadding: 2, | ||
| contentPadding: 2, | ||
| rounded: true | ||
| }); | ||
| const isNuxt3 = !isLegacy; | ||
| const isBridge = !isNuxt3 && infoObj["Build modules"]?.includes("bridge"); | ||
| const repo = isBridge ? "nuxt/bridge" : "nuxt/nuxt"; | ||
| const docsURL = isNuxt3 || isBridge ? "https://nuxt.com" : "https://v2.nuxt.com"; | ||
| logger.info(`👉 Read documentation: ${colors.cyan(docsURL)}`); | ||
| if (isNuxt3 || isBridge) { | ||
| logger.info(`👉 Report an issue: ${colors.cyan(`https://github.com/${repo}/issues/new?template=bug-report.yml`)}`, { spacing: 0 }); | ||
| logger.info(`👉 Suggest an improvement: ${colors.cyan(`https://github.com/${repo}/discussions/new`)}`, { spacing: 0 }); | ||
| } | ||
| } | ||
| }); | ||
| function normalizeConfigModule(module, rootDir) { | ||
| if (!module) return null; | ||
| if (typeof module === "string") return module.split(rootDir).pop().split("node_modules").pop().replace(/^\//, ""); | ||
| if (typeof module === "function") return `${module.name}()`; | ||
| if (Array.isArray(module)) return normalizeConfigModule(module[0], rootDir); | ||
| return null; | ||
| } | ||
| async function getNuxtConfig(rootDir) { | ||
| try { | ||
| const { createJiti } = await import("jiti"); | ||
| const jiti = createJiti(rootDir, { | ||
| interopDefault: true, | ||
| alias: { | ||
| "~": rootDir, | ||
| "@": rootDir | ||
| } | ||
| }); | ||
| globalThis.defineNuxtConfig = (c) => c; | ||
| const result = await jiti.import("./nuxt.config", { default: true }); | ||
| delete globalThis.defineNuxtConfig; | ||
| return result; | ||
| } catch { | ||
| return {}; | ||
| } | ||
| } | ||
| //#endregion | ||
| export { info_default as default }; |
| import "../logger-B4ge7MhP.mjs"; | ||
| import { t as initialize } from "../dev-BPdQ9vYt.mjs"; | ||
| import { t as initialize } from "../dev-CGEtJnLN.mjs"; | ||
| import "../kit-CPEUdXTm.mjs"; | ||
@@ -4,0 +4,0 @@ import "../versions-CTlxnxbH.mjs"; |
+4
-4
@@ -20,7 +20,7 @@ import { t as cwdArgs } from "./_shared-BCYCnX0T.mjs"; | ||
| cleanup: () => import("./cleanup-CD3OpT9X.mjs").then(_rDefault), | ||
| _dev: () => import("./dev-child-C02p1dAk.mjs").then(_rDefault), | ||
| dev: () => import("./dev-BjCHVbda.mjs").then(_rDefault), | ||
| _dev: () => import("./dev-child-D94d7-bL.mjs").then(_rDefault), | ||
| dev: () => import("./dev-XjVsLkhN.mjs").then(_rDefault), | ||
| devtools: () => import("./devtools-BTYlIJMv.mjs").then(_rDefault), | ||
| generate: () => import("./generate-DSEHRPYE.mjs").then(_rDefault), | ||
| info: () => import("./info-mG9k_IvM.mjs").then(_rDefault), | ||
| info: () => import("./info-B3KI8KR7.mjs").then(_rDefault), | ||
| init: () => import("./init-CUkHvr29.mjs").then(_rDefault), | ||
@@ -70,3 +70,3 @@ module: () => import("./module-dUoKC1O2.mjs").then(_rDefault), | ||
| var name = "@nuxt/cli"; | ||
| var version = "3.31.0"; | ||
| var version = "3.31.1"; | ||
| var description = "Nuxt CLI"; | ||
@@ -73,0 +73,0 @@ |
+1
-1
| { | ||
| "name": "@nuxt/cli", | ||
| "type": "module", | ||
| "version": "3.31.0", | ||
| "version": "3.31.1", | ||
| "description": "Nuxt CLI", | ||
@@ -6,0 +6,0 @@ "license": "MIT", |
| import { a as legacyRootDirArgs, i as extendsArgs, n as dotEnvArgs, o as logLevelArgs, r as envNameArgs, t as cwdArgs } from "./_shared-BCYCnX0T.mjs"; | ||
| import { n as logger, t as debug } from "./logger-B4ge7MhP.mjs"; | ||
| import { t as initialize } from "./dev-BPdQ9vYt.mjs"; | ||
| import "./kit-CPEUdXTm.mjs"; | ||
| import "./versions-CTlxnxbH.mjs"; | ||
| import "./banner-drlfl0J-.mjs"; | ||
| import "./fs-B_hD5MnA.mjs"; | ||
| import "./nuxt-Bkosdz43.mjs"; | ||
| import { t as overrideEnv } from "./env-kdrdHqLf.mjs"; | ||
| import process from "node:process"; | ||
| import { defineCommand } from "citty"; | ||
| import { isBun, isDeno, isTest } from "std-env"; | ||
| import { colors } from "consola/utils"; | ||
| import { resolve } from "pathe"; | ||
| import { satisfies } from "semver"; | ||
| import { getArgs, parseArgs } from "listhen/cli"; | ||
| import { fork } from "node:child_process"; | ||
| //#region ../nuxi/src/dev/pool.ts | ||
| var ForkPool = class { | ||
| pool = []; | ||
| poolSize; | ||
| rawArgs; | ||
| listenOverrides; | ||
| warming = false; | ||
| constructor(options) { | ||
| this.rawArgs = options.rawArgs; | ||
| this.poolSize = options.poolSize ?? 2; | ||
| this.listenOverrides = options.listenOverrides; | ||
| for (const signal of [ | ||
| "exit", | ||
| "SIGTERM", | ||
| "SIGINT", | ||
| "SIGQUIT" | ||
| ]) process.once(signal, () => { | ||
| this.killAll(signal === "exit" ? 0 : signal); | ||
| }); | ||
| } | ||
| startWarming() { | ||
| if (this.warming) return; | ||
| this.warming = true; | ||
| for (let i = 0; i < this.poolSize; i++) this.warmFork(); | ||
| } | ||
| async getFork(context, onMessage) { | ||
| const readyFork = this.pool.find((f) => f.state === "ready"); | ||
| if (readyFork) { | ||
| readyFork.state = "active"; | ||
| if (onMessage) this.attachMessageHandler(readyFork.process, onMessage); | ||
| await this.sendContext(readyFork.process, context); | ||
| if (this.warming) this.warmFork(); | ||
| return () => this.killFork(readyFork); | ||
| } | ||
| const warmingFork = this.pool.find((f) => f.state === "warming"); | ||
| if (warmingFork) { | ||
| await warmingFork.ready; | ||
| warmingFork.state = "active"; | ||
| if (onMessage) this.attachMessageHandler(warmingFork.process, onMessage); | ||
| await this.sendContext(warmingFork.process, context); | ||
| if (this.warming) this.warmFork(); | ||
| return () => this.killFork(warmingFork); | ||
| } | ||
| debug("No pre-warmed forks available, starting cold fork"); | ||
| const coldFork = this.createFork(); | ||
| await coldFork.ready; | ||
| coldFork.state = "active"; | ||
| if (onMessage) this.attachMessageHandler(coldFork.process, onMessage); | ||
| await this.sendContext(coldFork.process, context); | ||
| return () => this.killFork(coldFork); | ||
| } | ||
| attachMessageHandler(childProc, onMessage) { | ||
| childProc.on("message", (message) => { | ||
| if (message.type !== "nuxt:internal:dev:fork-ready") onMessage(message); | ||
| }); | ||
| } | ||
| warmFork() { | ||
| const fork$1 = this.createFork(); | ||
| fork$1.ready.then(() => { | ||
| if (fork$1.state === "warming") fork$1.state = "ready"; | ||
| }).catch(() => { | ||
| this.removeFork(fork$1); | ||
| }); | ||
| this.pool.push(fork$1); | ||
| } | ||
| createFork() { | ||
| const childProc = fork(globalThis.__nuxt_cli__.devEntry, this.rawArgs, { | ||
| execArgv: ["--enable-source-maps", process.argv.find((a) => a.includes("--inspect"))].filter(Boolean), | ||
| env: { | ||
| ...process.env, | ||
| __NUXT__FORK: "true" | ||
| } | ||
| }); | ||
| let readyResolve; | ||
| let readyReject; | ||
| const pooledFork = { | ||
| process: childProc, | ||
| ready: new Promise((resolve$1, reject) => { | ||
| readyResolve = resolve$1; | ||
| readyReject = reject; | ||
| }), | ||
| state: "warming" | ||
| }; | ||
| childProc.on("message", (message) => { | ||
| if (message.type === "nuxt:internal:dev:fork-ready") readyResolve(); | ||
| }); | ||
| childProc.on("error", (err) => { | ||
| readyReject(err); | ||
| this.removeFork(pooledFork); | ||
| }); | ||
| childProc.on("close", (errorCode) => { | ||
| if (pooledFork.state === "active" && errorCode) process.exit(errorCode); | ||
| this.removeFork(pooledFork); | ||
| }); | ||
| return pooledFork; | ||
| } | ||
| async sendContext(childProc, context) { | ||
| childProc.send({ | ||
| type: "nuxt:internal:dev:context", | ||
| listenOverrides: this.listenOverrides, | ||
| context | ||
| }); | ||
| } | ||
| killFork(fork$1, signal = "SIGTERM") { | ||
| fork$1.state = "dead"; | ||
| if (fork$1.process) fork$1.process.kill(signal === 0 && isDeno ? "SIGTERM" : signal); | ||
| this.removeFork(fork$1); | ||
| } | ||
| removeFork(fork$1) { | ||
| const index = this.pool.indexOf(fork$1); | ||
| if (index > -1) this.pool.splice(index, 1); | ||
| } | ||
| killAll(signal) { | ||
| for (const fork$1 of this.pool) this.killFork(fork$1, signal); | ||
| } | ||
| getStats() { | ||
| return { | ||
| total: this.pool.length, | ||
| warming: this.pool.filter((f) => f.state === "warming").length, | ||
| ready: this.pool.filter((f) => f.state === "ready").length, | ||
| active: this.pool.filter((f) => f.state === "active").length | ||
| }; | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region ../nuxi/src/commands/dev.ts | ||
| const startTime = Date.now(); | ||
| const forkSupported = !isTest && (!isBun || isBunForkSupported()); | ||
| const listhenArgs = getArgs(); | ||
| const command = defineCommand({ | ||
| meta: { | ||
| name: "dev", | ||
| description: "Run Nuxt development server" | ||
| }, | ||
| args: { | ||
| ...cwdArgs, | ||
| ...logLevelArgs, | ||
| ...dotEnvArgs, | ||
| ...legacyRootDirArgs, | ||
| ...envNameArgs, | ||
| ...extendsArgs, | ||
| clear: { | ||
| type: "boolean", | ||
| description: "Clear console on restart", | ||
| default: false | ||
| }, | ||
| fork: { | ||
| type: "boolean", | ||
| description: forkSupported ? "Disable forked mode" : "Enable forked mode", | ||
| negativeDescription: "Disable forked mode", | ||
| default: forkSupported, | ||
| alias: ["f"] | ||
| }, | ||
| ...listhenArgs, | ||
| port: { | ||
| ...listhenArgs.port, | ||
| description: "Port to listen on (default: `NUXT_PORT || NITRO_PORT || PORT || nuxtOptions.devServer.port`)", | ||
| alias: ["p"] | ||
| }, | ||
| open: { | ||
| ...listhenArgs.open, | ||
| alias: ["o"], | ||
| default: false | ||
| }, | ||
| host: { | ||
| ...listhenArgs.host, | ||
| alias: ["h"], | ||
| description: "Host to listen on (default: `NUXT_HOST || NITRO_HOST || HOST || nuxtOptions.devServer?.host`)" | ||
| }, | ||
| clipboard: { | ||
| ...listhenArgs.clipboard, | ||
| default: false | ||
| }, | ||
| sslCert: { | ||
| type: "string", | ||
| description: "(DEPRECATED) Use `--https.cert` instead." | ||
| }, | ||
| sslKey: { | ||
| type: "string", | ||
| description: "(DEPRECATED) Use `--https.key` instead." | ||
| } | ||
| }, | ||
| async run(ctx) { | ||
| overrideEnv("development"); | ||
| const cwd = resolve(ctx.args.cwd || ctx.args.rootDir); | ||
| const listenOverrides = resolveListenOverrides(ctx.args); | ||
| const { listener, close, onRestart, onReady } = await initialize({ | ||
| cwd, | ||
| args: ctx.args | ||
| }, { | ||
| data: ctx.data, | ||
| listenOverrides, | ||
| showBanner: true | ||
| }); | ||
| if (!ctx.args.fork) return { | ||
| listener, | ||
| close | ||
| }; | ||
| const pool = new ForkPool({ | ||
| rawArgs: ctx.rawArgs, | ||
| poolSize: 2, | ||
| listenOverrides | ||
| }); | ||
| onReady((_address) => { | ||
| pool.startWarming(); | ||
| if (startTime) debug(`Dev server ready for connections in ${Date.now() - startTime}ms`); | ||
| }); | ||
| let cleanupCurrentFork; | ||
| async function restartWithFork() { | ||
| const context = { | ||
| cwd, | ||
| args: ctx.args | ||
| }; | ||
| cleanupCurrentFork?.(); | ||
| cleanupCurrentFork = await pool.getFork(context, (message) => { | ||
| if (message.type === "nuxt:internal:dev:ready") { | ||
| if (startTime) debug(`Dev server ready for connections in ${Date.now() - startTime}ms`); | ||
| } else if (message.type === "nuxt:internal:dev:restart") restartWithFork(); | ||
| else if (message.type === "nuxt:internal:dev:rejection") { | ||
| logger.info(`Restarting Nuxt due to error: ${colors.cyan(message.message)}`); | ||
| restartWithFork(); | ||
| } | ||
| }); | ||
| } | ||
| onRestart(async () => { | ||
| await close(); | ||
| await restartWithFork(); | ||
| }); | ||
| return { async close() { | ||
| cleanupCurrentFork?.(); | ||
| await Promise.all([listener.close(), close()]); | ||
| } }; | ||
| } | ||
| }); | ||
| var dev_default = command; | ||
| function resolveListenOverrides(args) { | ||
| if (process.env._PORT) return { | ||
| port: process.env._PORT || 0, | ||
| hostname: "127.0.0.1", | ||
| showURL: false | ||
| }; | ||
| const options = parseArgs({ | ||
| ...args, | ||
| "host": args.host || process.env.NUXT_HOST || process.env.NITRO_HOST || process.env.HOST, | ||
| "port": args.port || process.env.NUXT_PORT || process.env.NITRO_PORT || process.env.PORT, | ||
| "https": args.https !== false, | ||
| "https.cert": args["https.cert"] || args.sslCert || process.env.NUXT_SSL_CERT || process.env.NITRO_SSL_CERT, | ||
| "https.key": args["https.key"] || args.sslKey || process.env.NUXT_SSL_KEY || process.env.NITRO_SSL_KEY | ||
| }); | ||
| return { | ||
| ...options, | ||
| _https: args.https, | ||
| get https() { | ||
| return this._https ? options.https : false; | ||
| } | ||
| }; | ||
| } | ||
| function isBunForkSupported() { | ||
| const bunVersion = globalThis.Bun.version; | ||
| return satisfies(bunVersion, ">=1.2"); | ||
| } | ||
| //#endregion | ||
| export { dev_default as default }; |
| import { i as withNodePath, t as loadKit } from "./kit-CPEUdXTm.mjs"; | ||
| import { r as showVersionsFromConfig } from "./banner-drlfl0J-.mjs"; | ||
| import { t as clearBuildDir } from "./fs-B_hD5MnA.mjs"; | ||
| import { a as writeNuxtManifest, i as resolveNuxtManifest, n as loadNuxtManifest } from "./nuxt-Bkosdz43.mjs"; | ||
| import process from "node:process"; | ||
| import { provider } from "std-env"; | ||
| import { pathToFileURL } from "node:url"; | ||
| import defu, { defu as defu$1 } from "defu"; | ||
| import EventEmitter from "node:events"; | ||
| import { existsSync, readdirSync, statSync, watch } from "node:fs"; | ||
| import { mkdir } from "node:fs/promises"; | ||
| import { resolveModulePath } from "exsolve"; | ||
| import { joinURL } from "ufo"; | ||
| import { listen } from "listhen"; | ||
| import { resolve } from "pathe"; | ||
| import { debounce } from "perfect-debounce"; | ||
| import { toNodeHandler } from "srvx/node"; | ||
| import { Youch } from "youch"; | ||
| //#region ../../node_modules/.pnpm/h3@1.15.4/node_modules/h3/dist/index.mjs | ||
| function hasProp(obj, prop) { | ||
| try { | ||
| return prop in obj; | ||
| } catch { | ||
| return false; | ||
| } | ||
| } | ||
| var H3Error = class extends Error { | ||
| static __h3_error__ = true; | ||
| statusCode = 500; | ||
| fatal = false; | ||
| unhandled = false; | ||
| statusMessage; | ||
| data; | ||
| cause; | ||
| constructor(message, opts = {}) { | ||
| super(message, opts); | ||
| if (opts.cause && !this.cause) this.cause = opts.cause; | ||
| } | ||
| toJSON() { | ||
| const obj = { | ||
| message: this.message, | ||
| statusCode: sanitizeStatusCode(this.statusCode, 500) | ||
| }; | ||
| if (this.statusMessage) obj.statusMessage = sanitizeStatusMessage(this.statusMessage); | ||
| if (this.data !== void 0) obj.data = this.data; | ||
| return obj; | ||
| } | ||
| }; | ||
| function createError(input) { | ||
| if (typeof input === "string") return new H3Error(input); | ||
| if (isError(input)) return input; | ||
| const err = new H3Error(input.message ?? input.statusMessage ?? "", { cause: input.cause || input }); | ||
| if (hasProp(input, "stack")) try { | ||
| Object.defineProperty(err, "stack", { get() { | ||
| return input.stack; | ||
| } }); | ||
| } catch { | ||
| try { | ||
| err.stack = input.stack; | ||
| } catch {} | ||
| } | ||
| if (input.data) err.data = input.data; | ||
| if (input.statusCode) err.statusCode = sanitizeStatusCode(input.statusCode, err.statusCode); | ||
| else if (input.status) err.statusCode = sanitizeStatusCode(input.status, err.statusCode); | ||
| if (input.statusMessage) err.statusMessage = input.statusMessage; | ||
| else if (input.statusText) err.statusMessage = input.statusText; | ||
| if (err.statusMessage) { | ||
| const originalMessage = err.statusMessage; | ||
| if (sanitizeStatusMessage(err.statusMessage) !== originalMessage) console.warn("[h3] Please prefer using `message` for longer error messages instead of `statusMessage`. In the future, `statusMessage` will be sanitized by default."); | ||
| } | ||
| if (input.fatal !== void 0) err.fatal = input.fatal; | ||
| if (input.unhandled !== void 0) err.unhandled = input.unhandled; | ||
| return err; | ||
| } | ||
| function sendError(event, error, debug) { | ||
| if (event.handled) return; | ||
| const h3Error = isError(error) ? error : createError(error); | ||
| const responseBody = { | ||
| statusCode: h3Error.statusCode, | ||
| statusMessage: h3Error.statusMessage, | ||
| stack: [], | ||
| data: h3Error.data | ||
| }; | ||
| if (debug) responseBody.stack = (h3Error.stack || "").split("\n").map((l) => l.trim()); | ||
| if (event.handled) return; | ||
| setResponseStatus(event, Number.parseInt(h3Error.statusCode), h3Error.statusMessage); | ||
| event.node.res.setHeader("content-type", MIMES.json); | ||
| event.node.res.end(JSON.stringify(responseBody, void 0, 2)); | ||
| } | ||
| function isError(input) { | ||
| return input?.constructor?.__h3_error__ === true; | ||
| } | ||
| const RawBodySymbol = Symbol.for("h3RawBody"); | ||
| const ParsedBodySymbol = Symbol.for("h3ParsedBody"); | ||
| const MIMES = { | ||
| html: "text/html", | ||
| json: "application/json" | ||
| }; | ||
| 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 = Number.parseInt(statusCode, 10); | ||
| if (statusCode < 100 || statusCode > 999) return defaultStatusCode; | ||
| return statusCode; | ||
| } | ||
| function splitCookiesString(cookiesString) { | ||
| if (Array.isArray(cookiesString)) return cookiesString.flatMap((c) => splitCookiesString(c)); | ||
| if (typeof cookiesString !== "string") return []; | ||
| const cookiesStrings = []; | ||
| let pos = 0; | ||
| let start$1; | ||
| let ch; | ||
| let lastComma; | ||
| let nextStart; | ||
| let cookiesSeparatorFound; | ||
| const skipWhitespace = () => { | ||
| while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos))) pos += 1; | ||
| return pos < cookiesString.length; | ||
| }; | ||
| const notSpecialChar = () => { | ||
| ch = cookiesString.charAt(pos); | ||
| return ch !== "=" && ch !== ";" && ch !== ","; | ||
| }; | ||
| while (pos < cookiesString.length) { | ||
| start$1 = pos; | ||
| cookiesSeparatorFound = false; | ||
| while (skipWhitespace()) { | ||
| ch = cookiesString.charAt(pos); | ||
| if (ch === ",") { | ||
| lastComma = pos; | ||
| pos += 1; | ||
| skipWhitespace(); | ||
| nextStart = pos; | ||
| while (pos < cookiesString.length && notSpecialChar()) pos += 1; | ||
| if (pos < cookiesString.length && cookiesString.charAt(pos) === "=") { | ||
| cookiesSeparatorFound = true; | ||
| pos = nextStart; | ||
| cookiesStrings.push(cookiesString.slice(start$1, lastComma)); | ||
| start$1 = pos; | ||
| } else pos = lastComma + 1; | ||
| } else pos += 1; | ||
| } | ||
| if (!cookiesSeparatorFound || pos >= cookiesString.length) cookiesStrings.push(cookiesString.slice(start$1)); | ||
| } | ||
| return cookiesStrings; | ||
| } | ||
| function setResponseStatus(event, code, text) { | ||
| if (code) event.node.res.statusCode = sanitizeStatusCode(code, event.node.res.statusCode); | ||
| if (text) event.node.res.statusMessage = sanitizeStatusMessage(text); | ||
| } | ||
| function sendStream(event, stream) { | ||
| if (!stream || typeof stream !== "object") throw new Error("[h3] Invalid stream provided."); | ||
| event.node.res._data = stream; | ||
| if (!event.node.res.socket) { | ||
| event._handled = true; | ||
| return Promise.resolve(); | ||
| } | ||
| if (hasProp(stream, "pipeTo") && typeof stream.pipeTo === "function") return stream.pipeTo(new WritableStream({ write(chunk) { | ||
| event.node.res.write(chunk); | ||
| } })).then(() => { | ||
| event.node.res.end(); | ||
| }); | ||
| if (hasProp(stream, "pipe") && typeof stream.pipe === "function") return new Promise((resolve$1, reject) => { | ||
| stream.pipe(event.node.res); | ||
| if (stream.on) { | ||
| stream.on("end", () => { | ||
| event.node.res.end(); | ||
| resolve$1(); | ||
| }); | ||
| stream.on("error", (error) => { | ||
| reject(error); | ||
| }); | ||
| } | ||
| event.node.res.on("close", () => { | ||
| if (stream.abort) stream.abort(); | ||
| }); | ||
| }); | ||
| throw new Error("[h3] Invalid or incompatible stream provided."); | ||
| } | ||
| function sendWebResponse(event, response) { | ||
| for (const [key, value] of response.headers) if (key === "set-cookie") event.node.res.appendHeader(key, splitCookiesString(value)); | ||
| else event.node.res.setHeader(key, value); | ||
| if (response.status) event.node.res.statusCode = sanitizeStatusCode(response.status, event.node.res.statusCode); | ||
| if (response.statusText) event.node.res.statusMessage = sanitizeStatusMessage(response.statusText); | ||
| if (response.redirected) event.node.res.setHeader("location", response.url); | ||
| if (!response.body) { | ||
| event.node.res.end(); | ||
| return; | ||
| } | ||
| return sendStream(event, response.body); | ||
| } | ||
| var H3Event = class { | ||
| "__is_event__" = true; | ||
| node; | ||
| web; | ||
| context = {}; | ||
| _method; | ||
| _path; | ||
| _headers; | ||
| _requestBody; | ||
| _handled = false; | ||
| _onBeforeResponseCalled; | ||
| _onAfterResponseCalled; | ||
| constructor(req, res) { | ||
| this.node = { | ||
| req, | ||
| res | ||
| }; | ||
| } | ||
| get method() { | ||
| if (!this._method) this._method = (this.node.req.method || "GET").toUpperCase(); | ||
| return this._method; | ||
| } | ||
| get path() { | ||
| return this._path || this.node.req.url || "/"; | ||
| } | ||
| get headers() { | ||
| if (!this._headers) this._headers = _normalizeNodeHeaders(this.node.req.headers); | ||
| return this._headers; | ||
| } | ||
| get handled() { | ||
| return this._handled || this.node.res.writableEnded || this.node.res.headersSent; | ||
| } | ||
| respondWith(response) { | ||
| return Promise.resolve(response).then((_response) => sendWebResponse(this, _response)); | ||
| } | ||
| toString() { | ||
| return `[${this.method}] ${this.path}`; | ||
| } | ||
| toJSON() { | ||
| return this.toString(); | ||
| } | ||
| /** @deprecated Please use `event.node.req` instead. */ | ||
| get req() { | ||
| return this.node.req; | ||
| } | ||
| /** @deprecated Please use `event.node.res` instead. */ | ||
| get res() { | ||
| return this.node.res; | ||
| } | ||
| }; | ||
| function createEvent(req, res) { | ||
| return new H3Event(req, res); | ||
| } | ||
| function _normalizeNodeHeaders(nodeHeaders) { | ||
| const headers = new Headers(); | ||
| for (const [name, value] of Object.entries(nodeHeaders)) if (Array.isArray(value)) for (const item of value) headers.append(name, item); | ||
| else if (value) headers.set(name, value); | ||
| return headers; | ||
| } | ||
| const H3Headers = globalThis.Headers; | ||
| const H3Response = globalThis.Response; | ||
| function toNodeListener(app) { | ||
| const toNodeHandle = async function(req, res) { | ||
| const event = createEvent(req, res); | ||
| try { | ||
| await app.handler(event); | ||
| } catch (_error) { | ||
| const error = createError(_error); | ||
| if (!isError(_error)) error.unhandled = true; | ||
| setResponseStatus(event, error.statusCode, error.statusMessage); | ||
| if (app.options.onError) await app.options.onError(error, event); | ||
| if (event.handled) return; | ||
| if (error.unhandled || error.fatal) console.error("[h3]", error.fatal ? "[fatal]" : "[unhandled]", error); | ||
| if (app.options.onBeforeResponse && !event._onBeforeResponseCalled) await app.options.onBeforeResponse(event, { body: error }); | ||
| await sendError(event, error, !!app.options.debug); | ||
| if (app.options.onAfterResponse && !event._onAfterResponseCalled) await app.options.onAfterResponse(event, { body: error }); | ||
| } | ||
| }; | ||
| return toNodeHandle; | ||
| } | ||
| //#endregion | ||
| //#region ../nuxi/src/dev/error.ts | ||
| async function renderError(req, res, error) { | ||
| if (res.headersSent) { | ||
| if (!res.writableEnded) res.end(); | ||
| return; | ||
| } | ||
| const youch = new Youch(); | ||
| res.statusCode = 500; | ||
| res.setHeader("Content-Type", "text/html"); | ||
| res.setHeader("Cache-Control", "no-store"); | ||
| res.setHeader("Refresh", "3"); | ||
| const html = await youch.toHTML(error, { request: { | ||
| url: req.url, | ||
| method: req.method, | ||
| headers: req.headers | ||
| } }); | ||
| res.end(html); | ||
| } | ||
| //#endregion | ||
| //#region ../nuxi/src/dev/utils.ts | ||
| const RESTART_RE = /^(?:nuxt\.config\.[a-z0-9]+|\.nuxtignore|\.nuxtrc|\.config\/nuxt(?:\.config)?\.[a-z0-9]+)$/; | ||
| var FileChangeTracker = class { | ||
| mtimes = /* @__PURE__ */ new Map(); | ||
| shouldEmitChange(filePath) { | ||
| const resolved = resolve(filePath); | ||
| try { | ||
| const currentMtime = statSync(resolved).mtimeMs; | ||
| const lastMtime = this.mtimes.get(resolved); | ||
| this.mtimes.set(resolved, currentMtime); | ||
| return lastMtime === void 0 || currentMtime !== lastMtime; | ||
| } catch { | ||
| this.mtimes.delete(resolved); | ||
| return true; | ||
| } | ||
| } | ||
| prime(filePath, recursive = false) { | ||
| const resolved = resolve(filePath); | ||
| const stat = statSync(resolved); | ||
| this.mtimes.set(resolved, stat.mtimeMs); | ||
| if (stat.isDirectory()) { | ||
| const entries = readdirSync(resolved); | ||
| for (const entry of entries) { | ||
| const fullPath = resolve(resolved, entry); | ||
| try { | ||
| const stats = statSync(fullPath); | ||
| this.mtimes.set(fullPath, stats.mtimeMs); | ||
| if (recursive && stats.isDirectory()) this.prime(fullPath, recursive); | ||
| } catch {} | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| var NuxtDevServer = class extends EventEmitter { | ||
| #handler; | ||
| #distWatcher; | ||
| #configWatcher; | ||
| #currentNuxt; | ||
| #loadingMessage; | ||
| #loadingError; | ||
| #fileChangeTracker = new FileChangeTracker(); | ||
| #cwd; | ||
| #websocketConnections = /* @__PURE__ */ new Set(); | ||
| loadDebounced; | ||
| handler; | ||
| listener; | ||
| constructor(options) { | ||
| super(); | ||
| this.options = options; | ||
| this.loadDebounced = debounce(this.load); | ||
| let _initResolve; | ||
| const _initPromise = new Promise((resolve$1) => { | ||
| _initResolve = resolve$1; | ||
| }); | ||
| this.once("ready", () => { | ||
| _initResolve(); | ||
| }); | ||
| this.#cwd = options.cwd; | ||
| this.handler = async (req, res) => { | ||
| if (this.#loadingError) { | ||
| renderError(req, res, this.#loadingError); | ||
| return; | ||
| } | ||
| await _initPromise; | ||
| if (this.#handler) this.#handler(req, res); | ||
| else this.#renderLoadingScreen(req, res); | ||
| }; | ||
| } | ||
| async #renderLoadingScreen(req, res) { | ||
| if (res.headersSent) { | ||
| if (!res.writableEnded) res.end(); | ||
| return; | ||
| } | ||
| res.statusCode = 503; | ||
| res.setHeader("Content-Type", "text/html"); | ||
| const loadingTemplate = this.options.loadingTemplate || this.#currentNuxt?.options.devServer.loadingTemplate || await resolveLoadingTemplate(this.#cwd); | ||
| res.end(loadingTemplate({ loading: this.#loadingMessage || "Loading..." })); | ||
| } | ||
| async init() { | ||
| this.#loadingMessage = `Starting Nuxt...`; | ||
| this.#handler = void 0; | ||
| this.emit("loading", this.#loadingMessage); | ||
| await this.#loadNuxtInstance(); | ||
| if (this.options.showBanner) showVersionsFromConfig(this.options.cwd, this.#currentNuxt.options); | ||
| await this.#createListener(); | ||
| await this.#initializeNuxt(false); | ||
| this.#watchConfig(); | ||
| } | ||
| closeWatchers() { | ||
| this.#distWatcher?.close(); | ||
| this.#configWatcher?.(); | ||
| } | ||
| async load(reload, reason) { | ||
| try { | ||
| this.closeWatchers(); | ||
| await this.#load(reload, reason); | ||
| this.#loadingError = void 0; | ||
| } catch (error) { | ||
| console.error(`Cannot ${reload ? "restart" : "start"} nuxt: `, error); | ||
| this.#handler = void 0; | ||
| this.#loadingError = error; | ||
| this.#loadingMessage = "Error while loading Nuxt. Please check console and fix errors."; | ||
| this.emit("loading:error", error); | ||
| } | ||
| this.#watchConfig(); | ||
| } | ||
| async #loadNuxtInstance(urls) { | ||
| const kit = await loadKit(this.options.cwd); | ||
| const loadOptions = { | ||
| cwd: this.options.cwd, | ||
| dev: true, | ||
| ready: false, | ||
| envName: this.options.envName, | ||
| dotenv: { | ||
| cwd: this.options.cwd, | ||
| fileName: this.options.dotenv.fileName | ||
| }, | ||
| overrides: { | ||
| logLevel: this.options.logLevel, | ||
| ...this.options.overrides, | ||
| vite: { | ||
| clearScreen: this.options.clear, | ||
| ...this.options.overrides.vite | ||
| } | ||
| } | ||
| }; | ||
| if (urls) { | ||
| const overrides = this.options.listenOverrides || {}; | ||
| const hostname = overrides.hostname; | ||
| const https = overrides.https; | ||
| loadOptions.defaults = resolveDevServerDefaults({ | ||
| hostname, | ||
| https | ||
| }, urls); | ||
| } | ||
| this.#currentNuxt = await kit.loadNuxt(loadOptions); | ||
| } | ||
| async #createListener() { | ||
| if (!this.#currentNuxt) throw new Error("Nuxt must be loaded before creating listener"); | ||
| const listenOptions = this.#resolveListenOptions(); | ||
| this.listener = await listen(this.handler, listenOptions); | ||
| if (listenOptions.public) { | ||
| this.#currentNuxt.options.devServer.cors = { origin: "*" }; | ||
| if (this.#currentNuxt.options.vite?.server) this.#currentNuxt.options.vite.server.allowedHosts = true; | ||
| return; | ||
| } | ||
| const urls = await this.listener.getURLs().then((r) => r.map((r$1) => r$1.url)); | ||
| if (urls && urls.length > 0) this.#currentNuxt.options.vite = defu(this.#currentNuxt.options.vite, { server: { allowedHosts: urls.map((u) => new URL(u).hostname) } }); | ||
| } | ||
| #resolveListenOptions() { | ||
| if (!this.#currentNuxt) throw new Error("Nuxt must be loaded before resolving listen options"); | ||
| const nuxtConfig = this.#currentNuxt.options; | ||
| const overrides = this.options.listenOverrides || {}; | ||
| const port = overrides.port ?? nuxtConfig.devServer?.port; | ||
| const hostname = overrides.hostname ?? nuxtConfig.devServer?.host; | ||
| const isPublic = provider === "codesandbox" || (overrides.public ?? (isPublicHostname(hostname) ? true : void 0)); | ||
| const httpsFromConfig = typeof nuxtConfig.devServer?.https !== "boolean" && nuxtConfig.devServer?.https ? nuxtConfig.devServer.https : {}; | ||
| overrides._https ??= !!nuxtConfig.devServer?.https; | ||
| const httpsOptions = overrides.https && defu(typeof overrides.https === "object" ? overrides.https : {}, httpsFromConfig); | ||
| const baseURL = nuxtConfig.app?.baseURL?.startsWith?.("./") ? nuxtConfig.app.baseURL.slice(1) : nuxtConfig.app?.baseURL; | ||
| return { | ||
| ...overrides, | ||
| port, | ||
| hostname, | ||
| public: isPublic, | ||
| https: httpsOptions || void 0, | ||
| baseURL | ||
| }; | ||
| } | ||
| async #initializeNuxt(reload) { | ||
| if (!this.#currentNuxt) throw new Error("Nuxt must be loaded before configuration"); | ||
| if (!process.env.NUXI_DISABLE_VITE_HMR) this.#currentNuxt.hooks.hook("vite:extend", ({ config }) => { | ||
| if (config.server) config.server.hmr = { | ||
| protocol: void 0, | ||
| ...config.server.hmr, | ||
| port: void 0, | ||
| host: void 0, | ||
| server: this.listener.server | ||
| }; | ||
| }); | ||
| this.#currentNuxt.hooks.hookOnce("close", () => { | ||
| this.#closeWebSocketConnections(); | ||
| this.listener.server.removeAllListeners("upgrade"); | ||
| }); | ||
| if (!reload) { | ||
| const previousManifest = await loadNuxtManifest(this.#currentNuxt.options.buildDir); | ||
| const newManifest = resolveNuxtManifest(this.#currentNuxt); | ||
| const promise = writeNuxtManifest(this.#currentNuxt, newManifest); | ||
| this.#currentNuxt.hooks.hookOnce("ready", async () => { | ||
| await promise; | ||
| }); | ||
| if (previousManifest && newManifest && previousManifest._hash !== newManifest._hash) await clearBuildDir(this.#currentNuxt.options.buildDir); | ||
| } | ||
| await this.#currentNuxt.ready(); | ||
| const unsub = this.#currentNuxt.hooks.hook("restart", async (options) => { | ||
| unsub(); | ||
| if (options?.hard) { | ||
| this.emit("restart"); | ||
| return; | ||
| } | ||
| await this.load(true); | ||
| }); | ||
| if (this.#currentNuxt.server && "upgrade" in this.#currentNuxt.server) this.listener.server.on("upgrade", (req, socket, head) => { | ||
| const nuxt = this.#currentNuxt; | ||
| if (!nuxt || !nuxt.server) return; | ||
| const viteHmrPath = joinURL(nuxt.options.app.baseURL.startsWith("./") ? nuxt.options.app.baseURL.slice(1) : nuxt.options.app.baseURL, nuxt.options.app.buildAssetsDir); | ||
| if (req.url?.startsWith(viteHmrPath)) return; | ||
| nuxt.server.upgrade(req, socket, head); | ||
| this.#websocketConnections.add(socket); | ||
| socket.on("close", () => { | ||
| this.#websocketConnections.delete(socket); | ||
| }); | ||
| }); | ||
| await this.#currentNuxt.hooks.callHook("listen", this.listener.server, this.listener); | ||
| const addr = this.listener.address; | ||
| this.#currentNuxt.options.devServer.host = addr.address; | ||
| this.#currentNuxt.options.devServer.port = addr.port; | ||
| this.#currentNuxt.options.devServer.url = getAddressURL(addr, !!this.listener.https); | ||
| this.#currentNuxt.options.devServer.https = this.listener.https; | ||
| if (this.listener.https && !process.env.NODE_TLS_REJECT_UNAUTHORIZED) console.warn("You might need `NODE_TLS_REJECT_UNAUTHORIZED=0` environment variable to make https work."); | ||
| const kit = await loadKit(this.options.cwd); | ||
| await Promise.all([kit.writeTypes(this.#currentNuxt).catch(console.error), kit.buildNuxt(this.#currentNuxt)]); | ||
| if (!this.#currentNuxt.server) throw new Error("Nitro server has not been initialized."); | ||
| const distDir = resolve(this.#currentNuxt.options.buildDir, "dist"); | ||
| await mkdir(distDir, { recursive: true }); | ||
| this.#fileChangeTracker.prime(distDir); | ||
| this.#distWatcher = watch(distDir); | ||
| this.#distWatcher.on("change", (_event, file) => { | ||
| if (!this.#fileChangeTracker.shouldEmitChange(resolve(distDir, file || ""))) return; | ||
| this.loadDebounced(true, ".nuxt/dist directory has been removed"); | ||
| }); | ||
| if ("fetch" in this.#currentNuxt.server) this.#handler = toNodeHandler(this.#currentNuxt.server.fetch); | ||
| else this.#handler = toNodeListener(this.#currentNuxt.server.app); | ||
| const proto = this.listener.https ? "https" : "http"; | ||
| this.emit("ready", `${proto}://127.0.0.1:${addr.port}`); | ||
| } | ||
| async close() { | ||
| if (this.#currentNuxt) await this.#currentNuxt.close(); | ||
| } | ||
| #closeWebSocketConnections() { | ||
| for (const socket of this.#websocketConnections) socket.destroy(); | ||
| this.#websocketConnections.clear(); | ||
| } | ||
| async #load(reload, reason) { | ||
| const action = reload ? "Restarting" : "Starting"; | ||
| this.#loadingMessage = `${reason ? `${reason}. ` : ""}${action} Nuxt...`; | ||
| this.#handler = void 0; | ||
| this.emit("loading", this.#loadingMessage); | ||
| if (reload) console.info(this.#loadingMessage); | ||
| await this.close(); | ||
| const urls = await this.listener.getURLs().then((r) => r.map((r$1) => r$1.url)); | ||
| await this.#loadNuxtInstance(urls); | ||
| await this.#initializeNuxt(!!reload); | ||
| } | ||
| #watchConfig() { | ||
| this.#configWatcher = createConfigWatcher(this.#cwd, this.options.dotenv.fileName, () => this.emit("restart"), (file) => this.loadDebounced(true, `${file} updated`)); | ||
| } | ||
| }; | ||
| function getAddressURL(addr, https) { | ||
| const proto = https ? "https" : "http"; | ||
| let host = addr.address.includes(":") ? `[${addr.address}]` : addr.address; | ||
| if (host === "[::]") host = "localhost"; | ||
| const port = addr.port || 3e3; | ||
| return `${proto}://${host}:${port}/`; | ||
| } | ||
| function resolveDevServerDefaults(listenOptions, urls = []) { | ||
| const defaultConfig = {}; | ||
| if (urls && urls.length > 0) defaultConfig.vite = { server: { allowedHosts: urls.map((u) => new URL(u).hostname) } }; | ||
| if (listenOptions.hostname) { | ||
| defaultConfig.devServer = { cors: { origin: [`${listenOptions.https ? "https" : "http"}://${listenOptions.hostname}`, ...urls] } }; | ||
| defaultConfig.vite = defu(defaultConfig.vite, { server: { allowedHosts: [listenOptions.hostname] } }); | ||
| } | ||
| return defaultConfig; | ||
| } | ||
| function createConfigWatcher(cwd, dotenvFileName = ".env", onRestart, onReload) { | ||
| const fileWatcher = new FileChangeTracker(); | ||
| fileWatcher.prime(cwd); | ||
| const configWatcher = watch(cwd); | ||
| let configDirWatcher = existsSync(resolve(cwd, ".config")) ? createConfigDirWatcher(cwd, onReload) : void 0; | ||
| const dotenvFileNames = new Set(Array.isArray(dotenvFileName) ? dotenvFileName : [dotenvFileName]); | ||
| configWatcher.on("change", (_event, file) => { | ||
| if (!fileWatcher.shouldEmitChange(resolve(cwd, file))) return; | ||
| if (dotenvFileNames.has(file)) onRestart(); | ||
| if (RESTART_RE.test(file)) onReload(file); | ||
| if (file === ".config") configDirWatcher ||= createConfigDirWatcher(cwd, onReload); | ||
| }); | ||
| return () => { | ||
| configWatcher.close(); | ||
| configDirWatcher?.(); | ||
| }; | ||
| } | ||
| function createConfigDirWatcher(cwd, onReload) { | ||
| const configDir = resolve(cwd, ".config"); | ||
| const fileWatcher = new FileChangeTracker(); | ||
| fileWatcher.prime(configDir); | ||
| const configDirWatcher = watch(configDir); | ||
| configDirWatcher.on("change", (_event, file) => { | ||
| if (!fileWatcher.shouldEmitChange(resolve(configDir, file))) return; | ||
| if (RESTART_RE.test(file)) onReload(file); | ||
| }); | ||
| return () => configDirWatcher.close(); | ||
| } | ||
| async function resolveLoadingTemplate(cwd) { | ||
| return (await import(pathToFileURL(resolveModulePath("@nuxt/ui-templates", { from: withNodePath(resolveModulePath("nuxt", { | ||
| from: withNodePath(cwd), | ||
| try: true | ||
| }) || cwd) })).href)).loading || ((params) => `<h2>${params.loading}</h2>`); | ||
| } | ||
| function isPublicHostname(hostname) { | ||
| return !!hostname && ![ | ||
| "localhost", | ||
| "127.0.0.1", | ||
| "::1" | ||
| ].includes(hostname); | ||
| } | ||
| //#endregion | ||
| //#region ../nuxi/src/dev/index.ts | ||
| const start = Date.now(); | ||
| process.env.NODE_ENV = "development"; | ||
| var IPC = class { | ||
| enabled = !!process.send && !process.title?.includes("vitest") && process.env.__NUXT__FORK; | ||
| constructor() { | ||
| if (this.enabled) process.once("unhandledRejection", (reason) => { | ||
| this.send({ | ||
| type: "nuxt:internal:dev:rejection", | ||
| message: reason instanceof Error ? reason.toString() : "Unhandled Rejection" | ||
| }); | ||
| process.exit(); | ||
| }); | ||
| process.on("message", (message) => { | ||
| if (message.type === "nuxt:internal:dev:context") initialize(message.context, { listenOverrides: message.listenOverrides }); | ||
| }); | ||
| this.send({ type: "nuxt:internal:dev:fork-ready" }); | ||
| } | ||
| send(message) { | ||
| if (this.enabled) process.send?.(message); | ||
| } | ||
| }; | ||
| const ipc = new IPC(); | ||
| async function initialize(devContext, ctx = {}) { | ||
| const devServer = new NuxtDevServer({ | ||
| cwd: devContext.cwd, | ||
| overrides: defu(ctx.data?.overrides, { extends: devContext.args.extends }), | ||
| logLevel: devContext.args.logLevel, | ||
| clear: devContext.args.clear, | ||
| dotenv: { | ||
| cwd: devContext.cwd, | ||
| fileName: devContext.args.dotenv | ||
| }, | ||
| envName: devContext.args.envName, | ||
| showBanner: ctx.showBanner !== false && !ipc.enabled, | ||
| listenOverrides: ctx.listenOverrides | ||
| }); | ||
| let address; | ||
| if (ipc.enabled) { | ||
| devServer.on("loading:error", (_error) => { | ||
| ipc.send({ | ||
| type: "nuxt:internal:dev:loading:error", | ||
| error: { | ||
| message: _error.message, | ||
| stack: _error.stack, | ||
| name: _error.name, | ||
| code: "code" in _error ? _error.code : void 0 | ||
| } | ||
| }); | ||
| }); | ||
| devServer.on("loading", (message) => { | ||
| ipc.send({ | ||
| type: "nuxt:internal:dev:loading", | ||
| message | ||
| }); | ||
| }); | ||
| devServer.on("restart", () => { | ||
| ipc.send({ type: "nuxt:internal:dev:restart" }); | ||
| }); | ||
| devServer.on("ready", (payload) => { | ||
| ipc.send({ | ||
| type: "nuxt:internal:dev:ready", | ||
| address: payload | ||
| }); | ||
| }); | ||
| } else devServer.on("ready", (payload) => { | ||
| address = payload; | ||
| }); | ||
| await devServer.init(); | ||
| if (process.env.DEBUG) console.debug(`Dev server (internal) initialized in ${Date.now() - start}ms`); | ||
| return { | ||
| listener: devServer.listener, | ||
| close: async () => { | ||
| devServer.closeWatchers(); | ||
| await Promise.all([devServer.listener.close(), devServer.close()]); | ||
| }, | ||
| onReady: (callback) => { | ||
| if (address) callback(address); | ||
| else devServer.once("ready", (payload) => callback(payload)); | ||
| }, | ||
| onRestart: (callback) => { | ||
| let restarted = false; | ||
| function restart() { | ||
| if (!restarted) { | ||
| restarted = true; | ||
| callback(devServer); | ||
| } | ||
| } | ||
| devServer.once("restart", restart); | ||
| process.once("uncaughtException", restart); | ||
| process.once("unhandledRejection", restart); | ||
| } | ||
| }; | ||
| } | ||
| //#endregion | ||
| export { initialize as t }; |
| import "./logger-B4ge7MhP.mjs"; | ||
| import { t as initialize } from "./dev-BPdQ9vYt.mjs"; | ||
| import "./kit-CPEUdXTm.mjs"; | ||
| import "./versions-CTlxnxbH.mjs"; | ||
| import "./banner-drlfl0J-.mjs"; | ||
| import "./fs-B_hD5MnA.mjs"; | ||
| import "./nuxt-Bkosdz43.mjs"; | ||
| export { initialize }; |
| import { a as legacyRootDirArgs, n as dotEnvArgs, o as logLevelArgs, r as envNameArgs, t as cwdArgs } from "./_shared-BCYCnX0T.mjs"; | ||
| import process from "node:process"; | ||
| import { defineCommand } from "citty"; | ||
| import { isTest } from "std-env"; | ||
| import { resolve } from "pathe"; | ||
| //#region ../nuxi/src/commands/dev-child.ts | ||
| var dev_child_default = defineCommand({ | ||
| meta: { | ||
| name: "_dev", | ||
| description: "Run Nuxt development server (internal command to start child process)" | ||
| }, | ||
| args: { | ||
| ...cwdArgs, | ||
| ...logLevelArgs, | ||
| ...envNameArgs, | ||
| ...dotEnvArgs, | ||
| ...legacyRootDirArgs, | ||
| clear: { | ||
| type: "boolean", | ||
| description: "Clear console on restart", | ||
| negativeDescription: "Disable clear console on restart" | ||
| } | ||
| }, | ||
| async run(ctx) { | ||
| if (!process.send && !isTest) console.warn("`nuxi _dev` is an internal command and should not be used directly. Please use `nuxi dev` instead."); | ||
| const cwd = resolve(ctx.args.cwd || ctx.args.rootDir); | ||
| const { initialize } = await import("./dev-BTtyQYdl.mjs"); | ||
| await initialize({ | ||
| cwd, | ||
| args: ctx.args | ||
| }, ctx); | ||
| } | ||
| }); | ||
| //#endregion | ||
| export { dev_child_default as default }; |
| import { a as legacyRootDirArgs, t as cwdArgs } from "./_shared-BCYCnX0T.mjs"; | ||
| import { n as logger } from "./logger-B4ge7MhP.mjs"; | ||
| import { n as tryResolveNuxt } from "./kit-CPEUdXTm.mjs"; | ||
| import "./versions-CTlxnxbH.mjs"; | ||
| import { t as getBuilder } from "./banner-drlfl0J-.mjs"; | ||
| import { t as formatInfoBox } from "./formatting-PESozNtr.mjs"; | ||
| import { t as getPackageManagerVersion } from "./packageManagers-BX7-V04a.mjs"; | ||
| import process from "node:process"; | ||
| import { defineCommand } from "citty"; | ||
| import { isBun, isDeno, isMinimal } from "std-env"; | ||
| import { colors } from "consola/utils"; | ||
| import { box } from "@clack/prompts"; | ||
| import { resolve } from "pathe"; | ||
| import { readPackageJSON } from "pkg-types"; | ||
| import os from "node:os"; | ||
| import { copy } from "copy-paste"; | ||
| import { detectPackageManager } from "nypm"; | ||
| //#region ../nuxi/package.json | ||
| var version = "3.31.0"; | ||
| //#endregion | ||
| //#region ../nuxi/src/commands/info.ts | ||
| var info_default = defineCommand({ | ||
| meta: { | ||
| name: "info", | ||
| description: "Get information about Nuxt project" | ||
| }, | ||
| args: { | ||
| ...cwdArgs, | ||
| ...legacyRootDirArgs | ||
| }, | ||
| async run(ctx) { | ||
| const cwd = resolve(ctx.args.cwd || ctx.args.rootDir); | ||
| const nuxtConfig = await getNuxtConfig(cwd); | ||
| const { dependencies = {}, devDependencies = {} } = await readPackageJSON(cwd).catch(() => ({})); | ||
| const nuxtPath = tryResolveNuxt(cwd); | ||
| async function getDepVersion(name) { | ||
| for (const url of [cwd, nuxtPath]) { | ||
| if (!url) continue; | ||
| const pkg = await readPackageJSON(name, { url }).catch(() => null); | ||
| if (pkg) return pkg.version; | ||
| } | ||
| return dependencies[name] || devDependencies[name]; | ||
| } | ||
| async function listModules(arr = []) { | ||
| const info = []; | ||
| for (let m of arr) { | ||
| if (Array.isArray(m)) m = m[0]; | ||
| const name = normalizeConfigModule(m, cwd); | ||
| if (name) { | ||
| const v = await getDepVersion(name.split("/").splice(0, 2).join("/")); | ||
| info.push(`\`${v ? `${name}@${v}` : name}\``); | ||
| } | ||
| } | ||
| return info.join(", "); | ||
| } | ||
| const nuxtVersion = await getDepVersion("nuxt") || await getDepVersion("nuxt-nightly") || await getDepVersion("nuxt-edge") || await getDepVersion("nuxt3") || "-"; | ||
| const isLegacy = nuxtVersion.startsWith("2"); | ||
| const builder = !isLegacy ? nuxtConfig.builder || "vite" : nuxtConfig.bridge?.vite ? "vite" : nuxtConfig.buildModules?.includes("nuxt-vite") ? "vite" : "webpack"; | ||
| let packageManager = (await detectPackageManager(cwd))?.name; | ||
| if (packageManager) packageManager += `@${getPackageManagerVersion(packageManager)}`; | ||
| const osType = os.type(); | ||
| const builderInfo = typeof builder === "string" ? getBuilder(cwd, builder) : { | ||
| name: "custom", | ||
| version: "0.0.0" | ||
| }; | ||
| const infoObj = { | ||
| "Operating system": osType === "Darwin" ? `macOS ${os.release()}` : osType === "Windows_NT" ? `Windows ${os.release()}` : `${osType} ${os.release()}`, | ||
| "CPU": `${os.cpus()[0]?.model || "unknown"} (${os.cpus().length} cores)`, | ||
| ...isBun ? { "Bun version": Bun?.version } : isDeno ? { "Deno version": Deno?.version.deno } : { "Node.js version": process.version }, | ||
| "nuxt/cli version": version, | ||
| "Package manager": packageManager ?? "unknown", | ||
| "Nuxt version": nuxtVersion, | ||
| "Nitro version": await getDepVersion("nitropack") || await getDepVersion("nitro"), | ||
| "Builder": builderInfo.name === "custom" ? "custom" : `${builderInfo.name.toLowerCase()}@${builderInfo.version}`, | ||
| "Config": Object.keys(nuxtConfig).map((key) => `\`${key}\``).sort().join(", "), | ||
| "Modules": await listModules(nuxtConfig.modules), | ||
| ...isLegacy ? { "Build modules": await listModules(nuxtConfig.buildModules || []) } : {} | ||
| }; | ||
| logger.info(`Nuxt root directory: ${colors.cyan(nuxtConfig.rootDir || cwd)}\n`); | ||
| const boxStr = formatInfoBox(infoObj); | ||
| let firstColumnLength = 0; | ||
| let secondColumnLength = 0; | ||
| const entries = Object.entries(infoObj).map(([label, val]) => { | ||
| if (label.length > firstColumnLength) firstColumnLength = label.length + 4; | ||
| if ((val || "").length > secondColumnLength) secondColumnLength = (val || "").length + 2; | ||
| return [label, val || "-"]; | ||
| }); | ||
| let copyStr = `| ${" ".repeat(firstColumnLength)} | ${" ".repeat(secondColumnLength)} |\n| ${"-".repeat(firstColumnLength)} | ${"-".repeat(secondColumnLength)} |\n`; | ||
| for (const [label, value] of entries) if (!isMinimal) copyStr += `| ${`**${label}**`.padEnd(firstColumnLength)} | ${(value.includes("`") ? value : `\`${value}\``).padEnd(secondColumnLength)} |\n`; | ||
| const copied = !isMinimal && await new Promise((resolve$1) => copy(copyStr, (err) => resolve$1(!err))); | ||
| box(`\n${boxStr}`, ` Nuxt project info ${copied ? colors.gray("(copied to clipboard) ") : ""}`, { | ||
| contentAlign: "left", | ||
| titleAlign: "left", | ||
| width: "auto", | ||
| titlePadding: 2, | ||
| contentPadding: 2, | ||
| rounded: true | ||
| }); | ||
| const isNuxt3 = !isLegacy; | ||
| const isBridge = !isNuxt3 && infoObj["Build modules"]?.includes("bridge"); | ||
| const repo = isBridge ? "nuxt/bridge" : "nuxt/nuxt"; | ||
| const docsURL = isNuxt3 || isBridge ? "https://nuxt.com" : "https://v2.nuxt.com"; | ||
| logger.info(`👉 Read documentation: ${colors.cyan(docsURL)}`); | ||
| if (isNuxt3 || isBridge) { | ||
| logger.info(`👉 Report an issue: ${colors.cyan(`https://github.com/${repo}/issues/new?template=bug-report.yml`)}`, { spacing: 0 }); | ||
| logger.info(`👉 Suggest an improvement: ${colors.cyan(`https://github.com/${repo}/discussions/new`)}`, { spacing: 0 }); | ||
| } | ||
| } | ||
| }); | ||
| function normalizeConfigModule(module, rootDir) { | ||
| if (!module) return null; | ||
| if (typeof module === "string") return module.split(rootDir).pop().split("node_modules").pop().replace(/^\//, ""); | ||
| if (typeof module === "function") return `${module.name}()`; | ||
| if (Array.isArray(module)) return normalizeConfigModule(module[0], rootDir); | ||
| return null; | ||
| } | ||
| async function getNuxtConfig(rootDir) { | ||
| try { | ||
| const { createJiti } = await import("jiti"); | ||
| const jiti = createJiti(rootDir, { | ||
| interopDefault: true, | ||
| alias: { | ||
| "~": rootDir, | ||
| "@": rootDir | ||
| } | ||
| }); | ||
| globalThis.defineNuxtConfig = (c) => c; | ||
| const result = await jiti.import("./nuxt.config", { default: true }); | ||
| delete globalThis.defineNuxtConfig; | ||
| return result; | ||
| } catch { | ||
| return {}; | ||
| } | ||
| } | ||
| //#endregion | ||
| export { info_default as default }; |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 27 instances in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 27 instances in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
159157
0.11%4586
0.02%22
-4.35%